Swiftで乱数を生成する


92

乱数を生成する必要があります。

表示されませんarc4random機能は、もはやだけでなく、存在するarc4random_uniform機能。

私が持っているオプションがありarc4random_stir()arc4random_buf(UnsafeMutablePointer<Void>, Int)arc4random_addrandom(UnsafeMutablePointer<UInt8>, Int32)

関数に関するドキュメントが見つからず、ヘッダーファイルのコメントからヒントが得られません。


3
Xcodeのオートコンプリートが壊れたように見えます。私はオートコンプリートなしでそれを入力したと誓ったかもしれませんが、コンパイルされませんでした。今働いています。@arsenによる素晴らしい参照
Big_Mac

1
arc4random_uniformが利用可能です。これは言語のネイティブ部分ではなくFoundation APIの一部であるため、ファイルを使用できるようにするには、ファイルの先頭に「インポートFoundation」(または「インポートUIKit」)が必要です。
Vince O'Sullivan、2015年

確率= Int(arc4random_uniform(UInt32(total)))–タイプアヘッドが壊れているため、タイピングの不満は特定ではありませんでした。これは、2つの異なるエラーからの私のキャスティングの不満
でした

回答:


227

===== Swift 4.2 / Xcode 10 =====

let randomIntFrom0To10 = Int.random(in: 1..<10)
let randomFloat = Float.random(in: 0..<1)

// if you want to get a random element in an array
let greetings = ["hey", "hi", "hello", "hola"]
greetings.randomElement()

Swiftはarc4random_buf仕事をこなすために内部的に使用しています。

===== Swift 4.1 / Xcode 9 =====

arc4random()0から4の範囲の乱数を返します294 967 295

drand48()0.0から1.0の範囲の乱数を返します

arc4random_uniform(N)0からN-1の範囲の乱数を返します

例:

arc4random() // => UInt32 = 2739058784
arc4random() // => UInt32 = 2672503239
arc4random() // => UInt32 = 3990537167
arc4random() // => UInt32 = 2516511476
arc4random() // => UInt32 = 3959558840

drand48() // => Double = 0.88642843322303122
drand48() // => Double = 0.015582849408328769
drand48() // => Double = 0.58409022031727176
drand48() // => Double = 0.15936862653180484
drand48() // => Double = 0.38371587480719427

arc4random_uniform(3) // => UInt32 = 0
arc4random_uniform(3) // => UInt32 = 1
arc4random_uniform(3) // => UInt32 = 0
arc4random_uniform(3) // => UInt32 = 1
arc4random_uniform(3) // => UInt32 = 2

arc4random() % upper_bound上限が2の累乗ではない場合に「モジュロバイアス」を回避するような構造では、arc4random_uniform()をお勧めします。


Float.random()は現在ベータ版としてマークされているため、次のように表示されます'Float' has no member 'random'
Dale

22

あなたも試すことができます:

let diceRoll = Int(arc4random_uniform(UInt32(6)))

「UInt32」を追加して機能させる必要がありました。


1
この関数を見るとわかりpublic func arc4random_uniform(_: UInt32) -> UInt32ます。だから私はなぜパラメータに変換するのか疑問に思っていますUInt32か?ここで他に何か起こっていますか?
Mark Moeykens、2016年

8

この関数を呼び出して、数値の最小範囲と最大範囲を指定するだけで、乱数が得られます。

例えば、randomNumber(MIN:0、MAX:10)のようにして、0から9までの数値を取得します。

func randomNumber(MIN: Int, MAX: Int)-> Int{
    return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN));
}

注:-出力は常に整数値になります。


1
私は必要があると思います: func randomNumber(MIN: Int, MAX: Int)-> Int{ return Int(arc4random_uniform(UInt32(MAX-MIN)) + UInt32(MIN)); }
Adahus '30

5

いくつかの調査の後、私はこれを書きました:

import Foundation

struct Math {
   private static var seeded = false

   static func randomFractional() -> CGFloat {

      if !Math.seeded {
         let time = Int(NSDate().timeIntervalSinceReferenceDate)
         srand48(time)
         Math.seeded = true
      }

      return CGFloat(drand48())
   }
}

これで、Math.randomFraction()最初にシードを覚えておかなくても、乱数[0..1 []を取得できます。これが誰かを助けることを願っています:o)


4

Swift 4.2で更新:

let randomInt = Int.random(in: 1..<5)
let randomFloat = Float.random(in: 1..<10)
let randomDouble = Double.random(in: 1...100)
let randomCGFloat = CGFloat.random(in: 1...1000)

3

別のオプションは、xorshift128plusアルゴリズムを使用することです。

func xorshift128plus(seed0 : UInt64, _ seed1 : UInt64) -> () -> UInt64 {
    var state0 : UInt64 = seed0
    var state1 : UInt64 = seed1
    if state0 == 0 && state1 == 0 {
        state0 = 1 // both state variables cannot be 0
    }

    func rand() -> UInt64 {
        var s1 : UInt64 = state0
        let s0 : UInt64 = state1
        state0 = s0
        s1 ^= s1 << 23
        s1 ^= s1 >> 17
        s1 ^= s0
        s1 ^= s0 >> 26
        state1 = s1
        return UInt64.addWithOverflow(state0, state1).0
    }

    return rand
}

このアルゴリズムの周期は2 ^ 128-1で、BigCrushテストスイートのすべてのテストに合格します。これは長い周期を持つ高品質の疑似乱数ジェネレータですが、暗号的に安全な乱数ジェネレータではありません

現在の時刻またはその他のランダムなエントロピーソースからシードすることができます。たとえばurand64()UInt64から読み取る関数が呼び出された場合/dev/urandom、次のように使用できます。

let rand = xorshift128plus(urand64(), urand64())
for _ in 1...10 {
    print(rand())
}

1
let MAX : UInt32 = 9
let MIN : UInt32 = 1 
func randomNumber()
{
   var random_number = Int(arc4random_uniform(MAX) + MIN)
   print ("random = ", random_number);    
}

このコードの説明を提供しないのはなぜですか?
改訂

1

Swift 3では:

制限するために0の間の乱数を生成します

let limit : UInt32 = 6
print("Random Number : \(arc4random_uniform(limit))")

そして、0からnの数ではなく、5から10の乱数を生成したい場合
Rishi

1
@Rishi 5から10までarc4random_uniform(6) + 5
Matt Le Fleur

1

Int拡張としての私の実装。範囲内の乱数を生成しますfrom..<to

public extension Int {
    static func random(from: Int, to: Int) -> Int {
        guard to > from else {
            assertionFailure("Can not generate negative random numbers")
            return 0
        }
        return Int(arc4random_uniform(UInt32(to - from)) + UInt32(from))
    }
}

1

これは、私が2 intの間の乱数を取得する方法です!

func randomNumber(MIN: Int, MAX: Int)-> Int{
    var list : [Int] = []
    for i in MIN...MAX {
        list.append(i)
    }
    return list[Int(arc4random_uniform(UInt32(list.count)))]
}

使用法:

print("My Random Number is: \(randomNumber(MIN:-10,MAX:10))")

1

別のオプションは、GameKitのGKMersenneTwisterRandomSourceを使用することです。ドキュメントは言う:

メルセンヌツイスターアルゴリズムに基づいて乱数を生成する確定的な疑似乱数ソース。これは、信頼性の高いゲームプレイメカニズムの作成に適した確定的なランダムソースです。シーケンスを繰り返すまでの期間が長いという点で、Arc4ソースより少し遅いですが、ランダムです。これは確定的ですが、暗号化されたランダムソースではありません。ただし、ゲームプレイデータの難読化には適しています。

import GameKit

let minValue = 0
let maxValue = 100

var randomDistribution: GKRandomDistribution?
let randomSource = GKMersenneTwisterRandomSource()
randomDistribution = GKRandomDistribution(randomSource: randomSource, lowestValue: minValue, highestValue: maxValue)
let number = randomDistribution?.nextInt() ?? 0
print(number)

Appleのサンプルコードからの例:https : //github.com/carekit-apple/CareKit/blob/master/CareKitPrototypingTool/OCKPrototyper/CareKitPatient/RandomNumberGeneratorHelper.swift


1

パーティーに遅れました🤩🎉

配列のサイズとその場での範囲選択を変更できる関数を使用することは、最も用途の広い方法です。マップを使用して、非常に簡潔にすることもできます。私はすべてのパフォーマンステスト/ベンチマーキングで使用しています。

elements
からの数のみを含む配列内の項目の数です0...max

func randArr(_ elements: Int, _ max: Int) -> [Int] {
        return (0..<elements).map{ _ in Int.random(in: 0...max) }
    }

コードセンス/プレースホルダーは次のようになります。 randArr(elements: Int, max: Int)

配列の0から1000までの10要素。

randArr(10, 1000) // [554, 8, 54, 87, 10, 33, 349, 888, 2, 77]

0

これを特定のレートで使用できます。

let die = [1, 2, 3, 4, 5, 6]
 let firstRoll = die[Int(arc4random_uniform(UInt32(die.count)))]
 let secondRoll = die[Int(arc4random_uniform(UInt32(die.count)))]

0

乱数またはランダム文字列をSwiftでコーディングしましょう:)

let quotes: NSArray = ["R", "A", "N", "D", "O", "M"]

      let randomNumber = arc4random_uniform(UInt32(quotes.count))
      let quoteString = quotes[Int(randomNumber)]
      print(quoteString)

ランダムに出力されます。


0

いくつかの数字が繰り返されることを忘れないでください!だからあなたは....のようなことをする必要があります

私のtotalQuestionsは47でした。

func getRandomNumbers(totalQuestions:Int) -> NSMutableArray
{

    var arrayOfRandomQuestions: [Int] = []

    print("arraySizeRequired = 40")
    print("totalQuestions = \(totalQuestions)")

    //This will output a 40 random numbers between 0 and totalQuestions (47)
    while arrayOfRandomQuestions.count < 40
    {

        let limit: UInt32 = UInt32(totalQuestions)

        let theRandomNumber = (Int(arc4random_uniform(limit)))

            if arrayOfRandomQuestions.contains(theRandomNumber)
            {
                print("ping")

            }
            else
            {
            //item not found
                arrayOfRandomQuestions.append(theRandomNumber)
            }

    }

    print("Random Number set = \(arrayOfRandomQuestions)")
    print("arrayOutputCount = \(arrayOfRandomQuestions.count)")


    return arrayOfRandomQuestions as! NSMutableArray

}

-2

見て、同じ問題がありましたが、関数をグローバル変数として挿入しました

なので

var RNumber = Int(arc4random_uniform(9)+1)

func GetCase(){

your code
}

明らかにこれは効率的ではないので、コードをコピーして関数に貼り付け、再利用できるようにします。その後、xcodeはvarを定数として設定することを提案するので、コードは

func GetCase() {

let RNumber = Int(arc4random_uniform(9)+1)

   if categoria == 1 {
    }
}

まあそれは私のコードの一部なので、xcodeは不変で初期化の何かを教えてくれますが、とにかくアプリを構築し、そのアドバイスは単に消えます

それが役に立てば幸い

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.