当前位置: 动力学知识库 > 问答 > 编程问答 >

srand - What is the equivalent of seeded random in Swift3 (Xcode8 beta 1)

问题描述:

I need to start the same random number list over every execution of my app.

srand/rand do not exist anymore. What should I do then?

private extension Array {

private func randomValues(_ seed: UInt32, num: Int) -> [Element] {

srand (seed)

var indices = [Int]()

indices.reserveCapacity(num)

let range = 0..<self.count

for _ in 0..<num {

var random = 0

repeat {

random = randomNumberInRange(range)

} while indices.contains(random)

indices.append(random)

}

return indices.map { self[$0] }

}

网友答案:

You can use srand48(seed) and drand48() in Swift3.

网友答案:

Unless you're developing with Swift for non-Apple platforms, you can get a much better randomization API in GameplayKit: several algorithms (trade randomness vs speed), seedable, distribution control, etc.

网友答案:

I can't find a way to use seeded random in Swift 3 Beta 1. Had to write a silly wrapper function in C:

// ----------------------------------------------
// my_random.h
// ----------------------------------------------
#ifndef my_random_h
#define my_random_h

#include <stdio.h>

#endif /* my_random_h */

long next_random();


// ----------------------------------------------
// my_random.c
// ----------------------------------------------
#include <stdlib.h>
#include "my_random.h"

long next_random() {
    return random();
}

You can use the bridging header to import it into Swift. Then you can call it in Swift like this:

srandom(42)
for _ in 0..<10 {
    let x = next_random()
    print(x)
}

random is better than rand. Read the man pages for discussion on these 2 functions.


Edit:

A workaround, as @riskter suggested, is to use GameKit:

import GameKit

let seed = Data(bytes: [42]) // Use any array of [UInt8]
let source = GKARC4RandomSource(seed: seed)

for _ in 0..<10 {
    let x = source.nextInt()
    print(x)
}
网友答案:

For a simple repeatable random list try using a Linear Congruential Generator:

import Foundation

class LinearCongruntialGenerator
{

    var state = 0 //seed of 0 by default
    let a, c, m, shift: Int

    //we will use microsoft random by default
    init() {
        self.a = 214013
        self.c = 2531011
        self.m = Int(pow(2.0, 31.0)) //2^31 or 2147483648
        self.shift = 16
    }

    init(a: Int, c: Int, m: Int, shift: Int) {
        self.a = a
        self.c = c
        self.m = m //2^31 or 2147483648
        self.shift = shift
    }

    func seed(seed: Int) -> Void {
        state = seed;
    }

    func random() -> Int {
        state = (a * state + c) % m
        return state >> shift
    }
}

let microsoftLinearCongruntialGenerator = LinearCongruntialGenerator()

print("Microsft Rand:")

for i in 0...10
{
    print(microsoftLinearCongruntialGenerator.random())
}

More info here: https://rosettacode.org/wiki/Linear_congruential_generator

分享给朋友:
您可能感兴趣的文章:
随机阅读: