Inicio>Relacionado con la programación>Otro código fuente

Randomkit es un marco Swift que hace que la generación de datos aleatorias sea simple y fácil.

Estado de construcción

Rama Estado
master

Instalación

Compatibilidad

Randomkit posiblemente también sea compatible con FreeBSD, Android y Windows (en Cygwin), pero no se ha probado para esas plataformas.

Instalar usando Swift Package Manager

El Swift Package Manager es un administrador de dependencia descentralizado para Swift.

  1. Agregue el proyecto a su Package.swift .

    import PackageDescription
    
    let package = Package (
        name : " MyAwesomeProject " ,
        dependencies : [
            . Package ( url : " https://github.com/nvzqz/RandomKit.git " ,
                     majorVersion : 5 )
        ]
    )
  2. Importar el módulo RandomKit.

    import RandomKit

Instalar con cocoapods

Cocoapods es un gerente de dependencia centralizado para Objective-C y Swift. Vaya aquí para obtener más información.

  1. Agregue el proyecto a su Podfile.

     use_frameworks!
    
    pod 'RandomKit' , '~> 5.2.3'

    Si desea estar en el borde de sangrado, reemplace la última línea con:

     pod 'RandomKit' , :git => 'https://github.com/nvzqz/RandomKit.git'
  2. Ejecute pod install y abra el archivo .xcworkspace para iniciar Xcode.

  3. Importar el marco Randomkit.

    import RandomKit

Instalar con Cartago

Carthage es un administrador de dependencia descentralizado para Objective-C y Swift.

  1. Agregue el proyecto a su Cartfile.

     github "nvzqz/RandomKit"
    
  2. Ejecute carthage update y siga los pasos adicionales para agregar RandomKit a su proyecto.

  3. Importar el marco Randomkit.

    import RandomKit

Punto de referencia

Varios componentes de RandomKit se pueden comparar fácilmente ejecutando benchmark.sh .

./benchmark.sh [FLAGS] [PROTOCOLS]

Use el indicador --help para obtener información sobre cómo usarlo.

Nota: El recuento predeterminado es 10000000, que es mucho si se usa el indicador --array . Esto se puede cambiar pasando un argumento a --count o -c .

Uso

¡Pruébalo por ti mismo! Descargue el repositorio y abra 'randomkit.playground'.

Generador aleatorio

El protocolo RandomGenerator define métodos básicos para generar valores primitivos y aleatorizar un tampón.

Todos los tipos proporcionados que se ajustan al RandomGenerator tienen un valor default estático que puede aprobarse como un argumento inout a las funciones de generación.

 let value = Int . random ( using : & Xoroshiro . default ) 

Generadores disponibles

SeedablerandomGenerator

SeedableRandomGenerator es para tipos que se pueden sembrar con algún tipo Seed asociada.

RandomByTesGenerator

El protocolo RandomBytesGenerator es para tipos que se especializan en generar un tipo específico que llena varios bytes. Por ejemplo, MersenneTwister se especializa en generar UInt64 mientras que Xorshift genera valores UInt32 .

Seguridad

Para programas de un solo subproceso, es seguro utilizar una instancia de generador global como Xoroshiro.default como fuente de aleatoriedad.

Para los programas de múltiples subprocesos, se deben utilizar las instancias locales de hilo. Esto permite que diferentes hilos usen sus propios generadores aleatorios separados sin un estado mutable compartido.

En el siguiente ejemplo, randomGenerator es exclusivo de cada hilo.

 let randomBytes = Xoroshiro . withThreadLocal { randomGenerator in
    return [ UInt8 ] ( randomCount : 1000 , using : & randomGenerator )
}

Los generadores locales de subprocesos se clasifican en la salida de subprocesos, por lo que no hay necesidad de preocuparse por la limpieza.

Se recomienda no llamar withThreadLocal(_:) o obtener el puntero threadLocal cada hora individual que se necesita. La recuperación de la instancia local de hilo incurre en la sobrecarga evitable.

// Bad
let value = Int . random ( using : & Xoroshiro . threadLocal . pointee )
array . shuffle ( using : & Xoroshiro . threadLocal . pointee )

// Good
let threadLocal = Xoroshiro . threadLocal
let value = Int . random ( using : & threadLocal . pointee )
array . shuffle ( using : & threadLocal . pointee )

// Better
Xoroshiro . withThreadLocal { randomGenerator in
    let value = Int . random ( using : & randomGenerator )
    array . shuffle ( using : & randomGenerator )
}

Como atajo, incluso puede aplicar una función directamente como un parámetro.

 let value = Xoroshiro . withThreadLocal ( Int . random )

Antes de V4.4.0, se podría lograr la seguridad de los hilos instanciando una nueva instancia sembrada de un tipo de RandomGenerator dado. El problema con esto es que la siembra innecesaria ocurre cada vez. Con esto, el generador se sembra una vez y luego se puede reutilizar en puntos posteriores.

También están disponibles accesos directos a la versión de reedición de un generador:

 Xoroshiro . withThreadLocalReseeding {
    ...
}

Que es mucho mejor que escribir:

 ReseedingRandomGenerator . withThreadLocal ( createdWith : { Xoroshiro . reseeding } ) {
    ...
}

Protocolos

Randomkit está muy orientado al protocolo, lo que le da la capacidad de ser muy flexible y modular.

Aleatorio

Un protocolo para los tipos que pueden generar valores aleatorios utilizando un RandomGenerator .

Randar rango

Un protocolo para los tipos que pueden generar valores aleatorios opcionales dentro de un rango utilizando un RandomGenerator .

 Int . random ( in : 0 ..< 0 , using : & randomGenerator ) // nil

Randilizado de rango

Un protocolo para los tipos que pueden generar valores aleatorios dentro de un rango cerrado utilizando un RandomGenerator .

 Int . random ( in : - 100 ... 100 , using : & randomGenerator ) // -79

RandomTovalue

Un protocolo para tipos que pueden generar valores aleatorios de un valor base a otro valor, no inclusivo.

El valor base para enteros es 0. Esto significa que llamar random(to:using:) en un valor negativo generará un valor negativo aleatorio o cero, mientras que un valor positivo generará un valor positivo o cero aleatorio.

Si value == randomBase , value se devolverá para random(to:using:) .

 Int . random ( to :  2 , using : & randomGenerator )  // Either 0 or 1
Int . random ( to :  0 , using : & randomGenerator )  // Always 0
Int . random ( to : 32 , using : & randomGenerator )  // 15
Int . random ( to : - 5 , using : & randomGenerator )  // -3

Valor aleatorio

Un protocolo para tipos que pueden generar valores aleatorios a partir de un valor base a través de otro valor, inclusive.

Las mismas reglas con respecto al valor base de RandomToValue se aplican a RandomThroughValue .

Reafirmable

Un protocolo para tipos cuyas instancias pueden tener elementos aleatorios recuperados.

 [ " Bob " , " Cindy " , " May " , " Charles " , " Javier " ] . random ( using : & randomGenerator )  // "Charles"

" Hello " . characters . random ( using : & randomGenerator )  // "e"

Algunos tipos de base como NSArray se ajustan a este protocolo.

RandomTrievableInrange

Un protocolo para tipos cuyas instancias pueden tener elementos aleatorios recuperados de un Range<Index> .

 [ 20 , 37 , 42 ] . random ( in : 1 ..< 3 , using : & randomGenerator )  // Either 37 or 42

Fusible

Un protocolo para tipos cuyos elementos se pueden barajar.

// Array
[ 1 , 2 , 3 , 4 , 5 ] . shuffled ( using : & randomGenerator )  // [3, 4, 1, 5, 2]

// Dictionary
[ " a " : 1 , " b " : 2 , " c " : 3 ] . shuffled ( using : & randomGenerator )  // ["a": 3, "b": 1, "c": 2]

La contraparte mutable de shuffled(using:) es shuffle(using:) .

Para un mejor rendimiento de Array , considere barajar en el lugar con shuffle(using:) .

Unicuado

Similar a Shuffleable , excepto que ningún elemento está en su posición inicial.

Tipos rápidos

Enteros

Todos los tipos enteros nativos de Swift se ajustan a los protocolos Random- .

La función random(using:) crea un entero de cualquier valor. Como resultado, los valores negativos pueden resultar para enteros firmados.

 Int . random ( using : & randomGenerator )               // An Int within Int.min and Int.max
Int . random ( in : 10 ... 20 , using : & randomGenerator )  // An Int within 10 and 20

Para crear un entero firmado positivo, use random(to:using:) o random(through:using:) .

 Int . random ( to : 1000 , using : & randomGenerator )     // 731
Int . random ( through : 10 , using : & randomGenerator )  // 4

Se pueden crear enteros firmados a partir de cualquier rango, sin peligro de desbordamiento.

 Int . random ( in : ( . min + 1000 ) ... ( . max - 200 ) , using : & randomGenerator )  // 5698527899712144154

Números de puntos flotantes

Genere un valor de punto flotante aleatorio desde un rango o 0.0...1.0 por defecto.

 Double . random ( using : & randomGenerator )                 //  0.9813615573117475
Double . random ( in :  - 10 ... 10 , using : & randomGenerator )  // -4.03042337718197
Float . random ( in :   - 10 ... 10 , using : & randomGenerator )  //  5.167088
Float80 . random ( in : - 10 ... 10 , using : & randomGenerator )  // -3.63204542399198874

Todos los tipos FloatingPoint también pueden ajustarse a RandomInClosedRange con mando

Bool

Bool.random(using:) tiene una posibilidad de 50/50 de ser true .

Si necesita una probabilidad diferente, también hay random(withWeight:using:) , que tiene 1 en weight de la posibilidad de ser true .

Cuerda, carácter y unicodescalar

String , Character y UnicodeScalar generan valores dentro de " "..."~" de forma predeterminada.

 String . random ( ofLength : 10 , using : & randomGenerator )                 // "}+[=Ng>$w1"
String . random ( ofLength : 10 , in : " A " ... " z " , using : & randomGenerator )  // "poUtXJIbv["

Character . random ( using : & randomGenerator )                 // "#"
Character . random ( in : " A " ... " z " , using : & randomGenerator )  // "s"

Matrices

Se puede generar una matriz de valores aleatorios para tipos que se ajustan al Random con init(randomCount:using:) .

Existen inicializadores similares para todos los demás protocolos Random- .

 let randoms = Array < Int > ( randomCount : 100 , using : & randomGenerator )  // [8845477344689834233, -957454203475087100, ...]

Para los tipos que se ajustan a UnsafeRandom , una alternativa más rápida es init(unsafeRandomCount:using:) . Este inicializador llena el búfer directamente en lugar de usar random(using:) .

 let unsafeRandoms = Array < Int > ( unsafeRandomCount : 100 , using : & randomGenerator )  // [759709806207883991, 4618491969012429761, ...]
Punto de referencia de matrices

Un punto de referencia para generar 1000 matrices Int aleatorias de 10000 recuento:

Generador Tiempo (en segundos)
Xoroshiro 0.0271
Xorshift 0.0568
XorshiftStar 0.0319
ChaCha 0.2027
MersenneTwister 0.0432
ARC4Random 0.2416
DeviceRandom 5.3348

Nota: Los resultados pueden variar debido a varios factores.

Este mismo punto de referencia se puede ejecutar con:

./benchmark.sh --all-generators --array 10000 --count 1000

Tipos de cimientos

Fecha

Se puede generar una Date aleatoria entre dos o valores de intervalo Date TimeInterval .

La función random(using:) devuelve una Date dentro de Date.distantPast y Date.distantFuture .

 Date . random ( using : & randomGenerator )  // "Aug 28, 2006, 3:38 AM"
Date . random ( in : Date . distantPast ... Date ( ) , using : & randomGenerator )  // "Feb 7, 472, 5:40 AM"

Decimal

El tipo Decimal se ajusta a varios protocolos Random- .

La función random(using:) devuelve un Decimal entre 0 y 1 por defecto.

 Decimal . random ( using : & randomGenerator )                  // 0.87490000409886706715888973957833129437
Decimal . random ( in : 0.0 ... 10.0 , using : & randomGenerator )  // 6.5464639772070720738747790627821299859

Number

Se puede generar un número aleatorio desde un número entero o de doble rango, o 0...100 por defecto.

 NSNumber . random ( using : & randomGenerator )                 // 79
NSNumber . random ( in : - 50 ... 100 , using : & randomGenerator )  // -27
NSNumber . random ( in : 100 ... 200 , using : & randomGenerator )  // 149.6156950363926

Tipos de cacao y uikit

Nscolor y uicolor

Se puede generar un color aleatorio, con o sin alfa aleatorio.

 NSColor . random ( using : & randomGenerator )              // r 0.694 g 0.506 b 0.309 a 1.0
NSColor . random ( alpha : true , using : & randomGenerator ) // r 0.859 g 0.57  b 0.409 a 0.047

UIColor . random ( using : & randomGenerator )              // r 0.488 g 0.805 b 0.679 a 1.0
UIColor . random ( alpha : true , using : & randomGenerator ) // r 0.444 g 0.121 b 0.602 a 0.085

Tipos de coregráfico

Cgfloat

Debido a que CGFloat se ajusta a FloatingPoint , se ajusta a RandomInClosedRange al igual que Double y Float .

 CGFloat . random ( using : & randomGenerator )               // 0.699803650379181
CGFloat . random ( in : 0 ... 100 , using : & randomGenerator )  // 43.27969591675319

Punto cg

Se puede generar un punto aleatorio a partir de rangos dentro de x e y.

 CGPoint . random ( using : & randomGenerator ) // {x 70.093 y 95.721}
CGPoint . random ( xRange : 0 ... 200 , yRange : 0 ... 10 , using : & randomGenerator ) // {x 73.795 y 0.991}

Cgsize

Se puede generar un tamaño aleatorio a partir de rangos dentro de ancho y altura.

 CGSize . random ( using : & randomGenerator ) // {w 3.744  h 35.932}
CGSize . random ( widthRange : 0 ... 50 , heightRange : 0 ... 400 , using : & randomGenerator ) // {w 38.271 h 239.636}

Cgrecto

Se puede generar un rectángulo aleatorio a partir de rangos para rangos para x, y, ancho y altura.

 CGRect . random ( using : & randomGenerator )  // {x 3.872  y 46.15  w 8.852  h 20.201}
CGRect . random ( xRange : 0 ... 50 ,
              yRange : 0 ... 100 ,
              widthRange : 0 ... 25 ,
              heightRange : 0 ... 10 ,
              using : & randomGenerator )  // {x 13.212 y 79.147 w 20.656 h 5.663}

Cgvector

Se puede generar un vector aleatorio a partir de rangos dentro de DX y DY.

 CGVector . random ( using : & randomGenerator ) // {dx 13.992 dy 89.376}
CGVector . random ( dxRange : 0 ... 50 , dyRange : 0 ... 10 , using : & randomGenerator ) // {dx 35.224 dy 13.463}

Extra

Bigint

Las extensiones aleatorias para la biblioteca Bigint de Károly están disponibles en Randomkitbigint.

Licencia

Randomkit y sus activos se lanzan bajo la licencia MIT. Los activos se pueden encontrar en la rama assets .

Las partes de este proyecto utilizan el código escrito por Matt Gallagher y, junto con la licencia MIT, tienen licencia con el que se encuentra aquí.

Expandir
Información adicional