Apple की स्विफ्ट भाषा में एक यादृच्छिक संख्या कैसे उत्पन्न होती है?


443

मुझे लगता है कि स्विफ्ट पुस्तक एक यादृच्छिक संख्या जनरेटर का कार्यान्वयन प्रदान करती है। क्या किसी के अपने कार्यक्रम में इस कार्यान्वयन को कॉपी और पेस्ट करना सबसे अच्छा अभ्यास है? या वहाँ एक पुस्तकालय है जो यह करता है कि हम अब उपयोग कर सकते हैं?

जवाबों:


466

स्विफ्ट 4.2+

Xcode 10 के साथ भेजा गया स्विफ्ट 4.2 कई डेटा प्रकारों के लिए नए आसान-से-उपयोग यादृच्छिक कार्यों का परिचय देता है। आप random()सांख्यिक प्रकारों पर विधि को कॉल कर सकते हैं।

let randomInt = Int.random(in: 0..<6)
let randomDouble = Double.random(in: 2.71828...3.14159)
let randomBool = Bool.random()

7
मुझे डार्विन
finneycanhelp

3
अपनी प्लेग्राउंड फ़ाइल में मुझे डार्विन को आयात करने की आवश्यकता थी क्योंकि मैं कुछ और आयात नहीं कर रहा था।
डोनाल्डिया

SoliQuiD: arc4 के बाद अतिरिक्त अंडरस्कोर को छोड़ दें, अर्थात arc4random_uniform (5)।
अली बीडल

3
चेतावनी : RC4 या ARC4 दिखाया गया है होना करने के लिए शुद्ध यादृच्छिक मान से अलग पहचाना । तो हालांकि आर्क 4 (एक धारा सिफर) क्रिप्टोग्राफिक रूप से सुरक्षित लगता है , यह वास्तव में नहीं है।
मार्टन बोडेवेस

2
@MaartenBodewes: अब सीधे तौर पर इस उत्तर के लिए प्रासंगिक नहीं है, लेकिन आर्क 4 आयामी वास्तव में RC4 सिफर का उपयोग नहीं करता है, इसके नाम के बावजूद, macOS या BSD पर। यह macOS पर एक सिस्टम-प्रदत्त CSPRNG और अधिकांश BSD पर ChaCha20 का उपयोग करता है। स्विफ्ट का डिफ़ॉल्ट आरएनजी (जैसा कि इस जवाब में इस्तेमाल किया गया है) इसे मैकओएस पर कार्यान्वयन विवरण के रूप में कहता है, लेकिन प्रत्येक समर्थित प्लेटफॉर्म पर एक उपयुक्त अंतर्निहित जनरेटर का उपयोग करता है।
स्टीफन कैनन

496

arc4random_uniform(n)0 और n-1 के बीच एक यादृच्छिक पूर्णांक के लिए उपयोग करें ।

let diceRoll = Int(arc4random_uniform(6) + 1)

Int को परिणाम के रूप में कास्ट करें ताकि आपको अपने vars को स्पष्ट रूप से टाइप न करना पड़े UInt32(जो अन-स्विफ्ट लगता है)।


7
बहुत आसान। मुझें यह पसंद है। वोट दें! लेकिन एक वास्तविक पासा नहीं है 0। आपके कोड में, diceRollहो सकता है 0। बस कह रहा हूं ...
एमके सफी

61
हाँ, आप वास्तव में चाहते हैं Int(arc4random_uniform(6)+1)
माइकल डोरस्ट

5
प्रायिकता = इंट (arc4random_uniform (UInt32 (कुल))) - मुझे भी UInt32
bshirley

4
चलो randomElementInArray = Int (arc4random_uniform (array.count))
cmario

पैरामीटर, एन, में प्रवेश कास्ट करने के लिए मत भूलना arc3random_uniform(n)एक करने के लिए UInt32(n)करता है, तो आपको लगता है कि उस प्रकार के पहले से ही नहीं है एक मूल्य का उपयोग कर रहे हैं।
डेव फॉन्टेनॉट

117

संपादित करें: स्विफ्ट 3.0 के लिए अपडेट किया गया

arc4randomस्विफ्ट में अच्छी तरह से काम करता है, लेकिन आधार फ़ंक्शन 32-बिट पूर्णांक प्रकार ( Intआईफोन 5 एस और आधुनिक मैकबुक पर 64-बिट) तक सीमित हैं । पूर्णांक शाब्दिक द्वारा व्यक्त किए गए एक प्रकार की यादृच्छिक संख्या के लिए यहां एक सामान्य कार्य है:

public func arc4random<T: ExpressibleByIntegerLiteral>(_ type: T.Type) -> T {
    var r: T = 0
    arc4random_buf(&r, MemoryLayout<T>.size)
    return r
}

UInt64सीमा विस्तार के तर्क जोड़ने और मॉडुलो पूर्वाग्रह को कम करने के लिए हम इस नए सामान्य कार्य का उपयोग कर सकते हैं । (इसे arc4random.c से सीधे उठाया गया है )

public extension UInt64 {
    public static func random(lower: UInt64 = min, upper: UInt64 = max) -> UInt64 {
        var m: UInt64
        let u = upper - lower
        var r = arc4random(UInt64.self)

        if u > UInt64(Int64.max) {
            m = 1 + ~u
        } else {
            m = ((max - (u * 2)) + 1) % u
        }

        while r < m {
            r = arc4random(UInt64.self)
        }

        return (r % u) + lower
    }
}

इसके साथ, हम Int64एक ही तर्क के लिए विस्तार कर सकते हैं , अतिप्रवाह से निपटने:

public extension Int64 {
    public static func random(lower: Int64 = min, upper: Int64 = max) -> Int64 {
        let (s, overflow) = Int64.subtractWithOverflow(upper, lower)
        let u = overflow ? UInt64.max - UInt64(~s) : UInt64(s)
        let r = UInt64.random(upper: u)

        if r > UInt64(Int64.max)  {
            return Int64(r - (UInt64(~lower) + 1))
        } else {
            return Int64(r) + lower
        }
    }
}

परिवार को पूरा करने के लिए ...

private let _wordSize = __WORDSIZE

public extension UInt32 {
    public static func random(lower: UInt32 = min, upper: UInt32 = max) -> UInt32 {
        return arc4random_uniform(upper - lower) + lower
    }
}

public extension Int32 {
    public static func random(lower: Int32 = min, upper: Int32 = max) -> Int32 {
        let r = arc4random_uniform(UInt32(Int64(upper) - Int64(lower)))
        return Int32(Int64(r) + Int64(lower))
    }
}

public extension UInt {
    public static func random(lower: UInt = min, upper: UInt = max) -> UInt {
        switch (_wordSize) {
            case 32: return UInt(UInt32.random(UInt32(lower), upper: UInt32(upper)))
            case 64: return UInt(UInt64.random(UInt64(lower), upper: UInt64(upper)))
            default: return lower
        }
    }
}

public extension Int {
    public static func random(lower: Int = min, upper: Int = max) -> Int {
        switch (_wordSize) {
            case 32: return Int(Int32.random(Int32(lower), upper: Int32(upper)))
            case 64: return Int(Int64.random(Int64(lower), upper: Int64(upper)))
            default: return lower
        }
    }
}

आखिरकार, हम आखिरकार ऐसा कुछ कर सकते हैं:

let diceRoll = UInt64.random(lower: 1, upper: 7)

यह संकलन नहीं है var r = arc4random(UInt64):। कृपया सलाह दें कि आपका यहाँ क्या मतलब है?
ओस्सिर

@Ossir मेरे लिए ठीक संकलित करता है ... इसका मतलब है कि फ़ंक्शन को कॉल करें arc4random(पहले कोड ब्लॉक में परिभाषित) तर्क के साथ UInt64जो कि ए Type
jstn

क्या arc4random_buf (और इसलिए सभी 64-बिट एक्सटेंशन) modulo पूर्वाग्रह से पीड़ित हैं?
मैथ्यू सीमैन

मोडुलो पूर्वाग्रह केवल खेल में आता है जब आप ऊपरी सीमा जोड़ते हैं, तो यह लागू नहीं होता है arc4random_buf। इन एक्सटेंशन का उद्देश्य arc4random_uniform64-बिट प्रकारों को छोड़कर वास्तव में क्या करता है (modulo bias को कम करता है)।
jstn

फ्लोट फ़ंक्शंस का उपयोग करते समय, मैं संभावनाओं की श्रेणी में ऊपरी मूल्य को कैसे शामिल कर सकता हूं? तो मैं कहता हूं कि मैं 0.0 को निचले और 1.0 को ऊपरी के रूप में करता हूं। इस तर्क के साथ यह मुझे ०.० ९९९९९९ तक देगा। लेकिन इसके बजाय मैं एक संभावना के रूप में 1.0 को शामिल करना चाहूंगा। इसे कैसे प्राप्त किया जा सकता है?
MobileMon

80

स्विफ्ट 4.2 के लिए संपादित करें

स्विफ्ट 4.2 में शुरू, आयातित C फंक्शन आर्क 4random_uniform () का उपयोग करने के बजाय, अब आप स्विफ्ट के अपने मूल कार्यों का उपयोग कर सकते हैं।

// Generates integers starting with 0 up to, and including, 10
Int.random(in: 0 ... 10)

आप random(in:)अन्य आदिम मूल्यों के लिए यादृच्छिक मान प्राप्त करने के लिए उपयोग कर सकते हैं ; जैसे कि इंट, डबल, फ्लोट और यहां तक ​​कि बूल।

स्विफ्ट संस्करण <4.2

यह विधि Intदिए गए न्यूनतम और अधिकतम के बीच एक यादृच्छिक मान उत्पन्न करेगी

func randomInt(min: Int, max: Int) -> Int {
    return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}

61

मैंने इस कोड का उपयोग किया है:

var k: Int = random() % 10;

20
आपको पहले srandom (UInt32 (समय (निल)))) को कॉल करना होगा, अन्यथा यह हमेशा एक ही नंबर अनुक्रम लौटाएगा
होला सोया एडु

3
मैंने ऐप्पल डॉक्स को यादृच्छिक पर पढ़ा () दो बार लेकिन इसके उपयोग को चमक नहीं सका ... मैं चाहता हूं कि वे ऊपर दिए गए कोड कोड को इस तरह शामिल करें। "यादृच्छिक () फ़ंक्शन एक गैर-रैखिक, एडिटिव फीडबैक, यादृच्छिक संख्या जनरेटर का उपयोग करता है, जो आकार के लंबे लंबे पूर्णांक की एक डिफ़ॉल्ट तालिका को नियोजित करता है। यह 0 से (2 31) -1 तक सीमा में क्रमिक छद्म यादृच्छिक संख्या देता है ।" इस यादृच्छिक संख्या जनरेटर की अवधि बहुत बड़ी है, लगभग 16 * ((2 31) -1)। " ... बहुत बहुत धन्यवाद सेब ... मैं अपनी अगली थीसिस में इसका संदर्भ देना सुनिश्चित करूंगा।
nocarrier

1
यादृच्छिक () कभी-कभी iPads पर अचानक दुर्घटना की ओर जाता है। यदि ऐसा होता है, तो ऊपर से arc4random_uniform (6) का उपयोग करें। यदि आप यादृच्छिक () का उपयोग करते हैं तो आप srandomdev () का उपयोग करके अधिक यादृच्छिक मान बना सकते हैं।
जैकपियर

1
मुझे संकलक त्रुटि संदेश मिला:random is unavailable in Swift: Use arc4random instead.
माइक केस्किनोव

1
इस समाधान में modulo bias है: zuttobenkyou.wordpress.com/2012/10/18/…
rgov

33

IOS 9 के रूप में, आप नए GameplayKit वर्गों का उपयोग विभिन्न तरीकों से यादृच्छिक संख्या उत्पन्न करने के लिए कर सकते हैं।

आपके पास चुनने के लिए चार स्रोत प्रकार हैं: एक सामान्य यादृच्छिक स्रोत (अनाम नाम, यह चुनने के लिए सिस्टम के नीचे), रैखिक बधाई, ARC4 और Mersenne Twister। ये यादृच्छिक ints, फ़्लोट्स और बूल उत्पन्न कर सकते हैं।

सरलतम स्तर पर, आप सिस्टम के अंतर्निहित यादृच्छिक स्रोत से इस तरह एक यादृच्छिक संख्या उत्पन्न कर सकते हैं:

GKRandomSource.sharedRandom().nextInt()

यह -2,147,483,648 और 2,147,483,647 के बीच एक संख्या उत्पन्न करता है। यदि आप 0 और एक ऊपरी सीमा (अनन्य) के बीच एक संख्या चाहते हैं, तो आप इसका उपयोग करेंगे:

GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

गेमप्लेकिट में पासा के साथ काम करने के लिए कुछ सुविधा निर्माणकर्ता हैं। उदाहरण के लिए, आप इस तरह से छह-पक्षीय मर रोल कर सकते हैं:

let d6 = GKRandomDistribution.d6()
d6.nextInt()

साथ ही आप GKShuffledDistribution जैसी चीजों का उपयोग करके यादृच्छिक वितरण को आकार दे सकते हैं। यह थोड़ा और समझाने वाला है, लेकिन अगर आप रुचि रखते हैं तो आप GameplayKit यादृच्छिक संख्याओं पर मेरे ट्यूटोरियल को पढ़ सकते हैं


1
इस टिप के लिए धन्यवाद, यह सबसे अच्छे उत्तरों में से एक है। इन कार्यों का उपयोग करने के लिए किसी को जोड़ना होगा import GameplayKit। स्विफ्ट 3 ने सिंटैक्स को बदल दियाGKRandomSource.sharedRandom().nextInt(upperBound: 6)
पेट्रसिन

7
इस किट को आयात करना कितना भारी है? मैं अपने कोड को ब्लोट नहीं करना चाहता।
μολ16ν.λαβέ

25

आप इसे उसी तरह से कर सकते हैं जैसे आप C में करेंगे:

let randomNumber = arc4random()

randomNumberप्रकार का होने का अनुमान है UInt32(एक 32-बिट अहस्ताक्षरित पूर्णांक)


12
परिशिष्ट: rand, arc4random, drand48और दोस्तों के सभी कर रहे हैं Darwinमॉड्यूल। यदि आप कोको, यूआईकिट या फाउंडेशन ऐप का निर्माण कर रहे हैं तो यह आपके लिए पहले से ही आयातित है, लेकिन आपको import Darwinखेल के मैदानों में इसकी आवश्यकता होगी ।
रिकस्टर

5
और Int4 के लिए arc4random () के परिणाम को डालने का प्रयास न करें - यह 64-बिट प्लेटफॉर्म पर ठीक काम करेगा, लेकिन 32-बिट प्लेटफॉर्म पर, Ints 32-बिट पर हस्ताक्षर किए जाते हैं, इसलिए आपको अप्रत्याशित नकारात्मक मिलेगा संख्या। इसने कुछ लोगों को पहले ही फंसा दिया है, इसलिए मुझे लगा कि मैं इसका उल्लेख यहां करूंगा।
मैट गिब्सन

23

उपयोग arc4random_uniform()

उपयोग:

arc4random_uniform(someNumber: UInt32) -> UInt32

यह आपको श्रेणी में यादृच्छिक पूर्णांक देता 0है someNumber - 1

अधिकतम मूल्य UInt324,294,967,295 (जो है 2^32 - 1)।

उदाहरण:

  • सिक्का उछालो

    let flip = arc4random_uniform(2) // 0 or 1
  • पासा फेंकना

    let roll = arc4random_uniform(6) + 1 // 1...6
  • अक्टूबर में रैंडम दिन

    let day = arc4random_uniform(31) + 1 // 1...31
  • 1990 के दशक में रैंडम वर्ष

    let year = 1990 + arc4random_uniform(10)

सामान्य फ़ॉर्म:

let number = min + arc4random_uniform(max - min + 1)

कहाँ number, maxऔर minहैं UInt32

व्हाट अबाउट...

arc4random ()

आप उपयोग करके एक यादृच्छिक संख्या भी प्राप्त कर सकते हैं arc4random(), जो UInt320 से 2 ^ 32-1 के बीच पैदा करता है । इस प्रकार 0और के बीच एक यादृच्छिक संख्या प्राप्त करने के लिए x-1, आप इसे विभाजित कर सकते हैं xऔर शेष ले सकते हैं । या दूसरे शब्दों में, शेष संचालक (%) का उपयोग करें :

let number = arc4random() % 5 // 0...4

हालांकि, यह मामूली मोडुलो पूर्वाग्रह ( यहां और यहां भी देखें ) पैदा करता है , इसीलिए arc4random_uniform()इसकी सिफारिश की जाती है।

और से परिवर्तित Int

सामान्य रूप से इसे परिवर्तित वापस करने के लिए आगे और पीछे के बीच क्रम में इस तरह कुछ करने के लिए ठीक होगा Intऔर UInt32:

let number: Int = 10
let random = Int(arc4random_uniform(UInt32(number)))

समस्या है, हालांकि, वह यह है कि Intकी एक श्रृंखला है -2,147,483,648...2,147,483,64732 बिट सिस्टम पर और की एक सीमा -9,223,372,036,854,775,808...9,223,372,036,854,775,80764 बिट सिस्टम पर। इसकी UInt32रेंज से तुलना करें 0...4,294,967,295Uके UInt32साधन अहस्ताक्षरित

निम्नलिखित त्रुटियों पर विचार करें:

UInt32(-1) // negative numbers cause integer overflow error
UInt32(4294967296) // numbers greater than 4,294,967,295 cause integer overflow error

इसलिए आपको केवल यह सुनिश्चित करने की आवश्यकता है कि आपके इनपुट पैरामीटर UInt32सीमा के भीतर हैं और आपको उस आउटपुट की आवश्यकता नहीं है जो उस सीमा के बाहर भी है।


19

10 (0-9) के बीच यादृच्छिक संख्या के लिए उदाहरण;

import UIKit

let randomNumber = Int(arc4random_uniform(10))

बहुत आसान कोड - सरल और संक्षिप्त।


16

मैं सिर्फ rand()एक यादृच्छिक CInt पाने के लिए उपयोग करने में सक्षम है । आप इसे कुछ इस तरह से उपयोग करके एक इंट बना सकते हैं:

let myVar: Int = Int(rand())

आप अपने पसंदीदा सी रैंडम फ़ंक्शन का उपयोग कर सकते हैं, और यदि आवश्यक हो तो बस मान में परिवर्तित कर सकते हैं।


हां, टाइप रूपांतरण अन्यथा एक मुश्किल व्यवसाय हो सकता है और इंट कंस्ट्रक्टर के साथ सौदा करना असली दर्द सेवर है।
कजरबिल

4
ध्यान दें कि यदि आप रैंड () का उपयोग करने से पहले सरैंड (...) (केवल एक बार कॉल करें) नहीं कर रहे हैं, तो संख्याओं का क्रम हमेशा आपके प्रोग्राम के प्रत्येक निष्पादन के बीच समान होगा। यदि आप ऐसा नहीं चाहते हैं, तो
बजे

2
आप यह भी इस्तेमाल कर सकते हैं random(), जो @ के Intबजाय एक रिटर्न देता है UInt32- और @SomeGuy का उल्लेख किया है, बस srandom(arc4random())इसका उपयोग करने से पहले एक बार कहीं भी कॉल करें यह सुनिश्चित करने के लिए कि आपके कार्यक्रम के प्रत्येक निष्पादन के लिए एक अलग, यादृच्छिक बीज है।
ब्रिटलविस 12

1
क्या कोई रैंड () बनाम arc4random_uniform () पर टिप्पणी कर सकता है?
रुबेन मार्टिनेज जूनियर

16

@ jstn का जवाब अच्छा है, लेकिन थोड़ा क्रियात्मक है। स्विफ्ट को एक प्रोटोकॉल-उन्मुख भाषा के रूप में जाना जाता है, इसलिए हम प्रोटोकॉल एक्सटेंशन के लिए एक डिफ़ॉल्ट कार्यान्वयन जोड़कर पूर्णांक परिवार में हर वर्ग के लिए बॉयलरप्लेट कोड को लागू किए बिना एक ही परिणाम प्राप्त कर सकते हैं।

public extension ExpressibleByIntegerLiteral {
    public static func arc4random() -> Self {
        var r: Self = 0
        arc4random_buf(&r, MemoryLayout<Self>.size)
        return r
    }
}

अब हम कर सकते हैं:

let i = Int.arc4random()
let j = UInt32.arc4random()

और अन्य सभी पूर्णांक वर्ग ठीक हैं।


11

में स्विफ्ट 4.2 आपको कॉल करके यादृच्छिक संख्या उत्पन्न कर सकते हैं random(), जो कुछ भी सांख्यिक प्रकार आप चाहते हैं पर विधि रेंज आप के साथ काम करना चाहते हैं प्रदान करते हैं। उदाहरण के लिए, यह 9 के माध्यम से रेंज 1 में एक यादृच्छिक संख्या उत्पन्न करता है, दोनों तरफ समावेशी

let randInt = Int.random(in: 1..<10)

अन्य प्रकारों के साथ भी

let randFloat = Float.random(in: 1..<20)
let randDouble = Double.random(in: 1...30)
let randCGFloat = CGFloat.random(in: 1...40)

9

यहाँ एक पुस्तकालय है जो अच्छी तरह से काम करता है https://github.com/thellimist/SwiftRandom

public extension Int {
    /// SwiftRandom extension
    public static func random(lower: Int = 0, _ upper: Int = 100) -> Int {
        return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
    }
}

public extension Double {
    /// SwiftRandom extension
    public static func random(lower: Double = 0, _ upper: Double = 100) -> Double {
        return (Double(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
    }
}

public extension Float {
    /// SwiftRandom extension
    public static func random(lower: Float = 0, _ upper: Float = 100) -> Float {
        return (Float(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
    }
}

public extension CGFloat {
    /// SwiftRandom extension
    public static func random(lower: CGFloat = 0, _ upper: CGFloat = 1) -> CGFloat {
        return CGFloat(Float(arc4random()) / Float(UINT32_MAX)) * (upper - lower) + lower
    }
}


6

मैं मौजूदा उत्तरों में जोड़ना चाहूंगा कि स्विफ्ट पुस्तक में रैंडम संख्या जनरेटर उदाहरण एक रैखिक कांग्रेंस जनरेटर (LCG) है, यह एक गंभीर रूप से सीमित है और इसे तुच्छ उदाहरणों के अलावा नहीं होना चाहिए, जहां यादृच्छिकता की गुणवत्ता है। 'बिल्कुल बात नहीं है। और क्रिप्टोग्राफिक प्रयोजनों के लिए एक एलसीजी का उपयोग कभी नहीं किया जाना चाहिए

arc4random()बहुत बेहतर है और इसका उपयोग अधिकांश उद्देश्यों के लिए किया जा सकता है, लेकिन फिर से क्रिप्टोग्राफ़िक उद्देश्यों के लिए उपयोग नहीं किया जाना चाहिए।

यदि आप कुछ ऐसा चाहते हैं जो क्रिप्टोग्राफिक रूप से सुरक्षित होने की गारंटी है, तो उपयोग करें SecCopyRandomBytes()। ध्यान दें कि यदि आप किसी चीज़ में एक यादृच्छिक संख्या जनरेटर का निर्माण करते हैं, तो कोई अन्य व्यक्ति (क्रिप्टोग्राफ़िक उद्देश्यों (जैसे पासवर्ड, कुंजी या नमक उत्पादन) के लिए इसे गलत कर सकता है), तो आपको SecCopyRandomBytes()वैसे भी उपयोग करने पर विचार करना चाहिए , भले ही आपकी ज़रूरत न हो ' टी की आवश्यकता है कि


6

चूंकि स्विफ्ट 4.2 है

एपीआई का एक नया सेट है:

let randomIntFrom0To10 = Int.random(in: 0 ..< 10)
let randomDouble = Double.random(in: 1 ... 10)
  • सभी संख्यात्मक प्रकारों में अब random(in:)विधि है जो लेती है range

  • यह उस सीमा में समान रूप से वितरित संख्या देता है।


टी एल; डॉ

खैर, "अच्छे" पुराने तरीके से क्या गलत है?

  1. आपको आयातित सी एपीआई का उपयोग करना होगा (वे प्लेटफार्मों के बीच भिन्न हैं)

  2. और इसके अलावा...

क्या होगा अगर मैंने आपको बताया कि यादृच्छिक वह यादृच्छिक नहीं है?

यदि आप arc4random() (शेष की गणना करने के लिए) का उपयोग करते हैं arc4random() % aNumber, तो परिणाम समान रूप से और के बीच वितरित नहीं होता है । एक समस्या है जिसे मोडुलो बायस कहा जाता है ।0aNumber

मोडुलो पूर्वाग्रह

आम तौर पर, फ़ंक्शन अधिकतम0 और अधिकतम (प्रकार आदि पर निर्भर करता है) के बीच एक यादृच्छिक संख्या उत्पन्न करता है । एक त्वरित, आसान उदाहरण बनाने के लिए, मान लें कि अधिकतम संख्या है 7और आप रेंज में एक यादृच्छिक संख्या 0 ..< 2 (या अंतराल [0, 3) की परवाह करते हैं यदि आप इसे पसंद करते हैं)

व्यक्तिगत नंबरों की संभावनाएं हैं:

  • 0: 3/8 = 37.5%
  • 1: 3/8 = 37.5%
  • 2: 2/8 = 25%

दूसरे शब्दों में, आप 2 से 0 या 1 के साथ समाप्त होने की अधिक संभावना है । बेशक, यह ध्यान में रखते हुए कि यह बेहद सरल है और MAX संख्या बहुत अधिक है, जिससे यह अधिक "उचित" हो जाता है।

इस समस्या को SE-0202 द्वारा संबोधित किया गया है - स्विफ्ट 4.2 में यादृच्छिक एकीकरण


5

X4 के कुछ संस्करणों में arc4Random_uniform () के बिना (7.1 में यह चलता है लेकिन मेरे लिए स्वत: पूर्ण नहीं है)। आप इसके बजाय यह कर सकते हैं।

0-5 से एक यादृच्छिक संख्या उत्पन्न करने के लिए। प्रथम

import GameplayKit

फिर

let diceRoll = GKRandomSource.sharedRandom().nextIntWithUpperBound(6)

5
var randomNumber = Int(arc4random_uniform(UInt32(5)))

यहां 5 यह सुनिश्चित करेगा कि यादृच्छिक संख्या शून्य से चार के माध्यम से उत्पन्न होती है। आप अपने अनुसार मूल्य निर्धारित कर सकते हैं।


1
यदि आप 5 पास करते हैं तो यह शून्य से चार तक 5 संभावित परिणाम लौटाएगा। 0 ... 4
लियो डबस

3

स्विफ्ट 4.2

नींव सी lib आयात करने के लिए अलविदा arc4random_uniform()

// 1  
let digit = Int.random(in: 0..<10)

// 2
if let anotherDigit = (0..<10).randomElement() {
  print(anotherDigit)
} else {
  print("Empty range.")
}

// 3
let double = Double.random(in: 0..<1)
let float = Float.random(in: 0..<1)
let cgFloat = CGFloat.random(in: 0..<1)
let bool = Bool.random()
  1. आप यादृच्छिक का उपयोग करते हैं (:) में श्रेणियों से यादृच्छिक अंक उत्पन्न करने के लिए।
  2. randomElement () रिटर्न शून्य है यदि रेंज खाली है, तो आप वापस किए गए इंट को अनप्लग करें? अगर साथ है।
  3. आप एक यादृच्छिक बूल वापस करने के लिए यादृच्छिक (:) में एक यादृच्छिक डबल, फ्लोट या CGFloat और यादृच्छिक () उत्पन्न करने के लिए उपयोग करते हैं।

अधिक @ आधिकारिक


2

निम्न कोड 0 और 255 के बीच एक सुरक्षित यादृच्छिक संख्या का उत्पादन करेगा:

extension UInt8 {
  public static var random: UInt8 {
    var number: UInt8 = 0
    _ = SecRandomCopyBytes(kSecRandomDefault, 1, &number)
    return number
  }
}

आप इसे इस तरह कहते हैं:

print(UInt8.random)

बड़ी संख्या के लिए यह अधिक जटिल हो जाता है।
यह सबसे अच्छा मैं के साथ आ सकता है:

extension UInt16 {
  public static var random: UInt16 {
    let count = Int(UInt8.random % 2) + 1
    var numbers = [UInt8](repeating: 0, count: 2)
    _ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
    return numbers.reversed().reduce(0) { $0 << 8 + UInt16($1) }
  }
}

extension UInt32 {
  public static var random: UInt32 {
    let count = Int(UInt8.random % 4) + 1
    var numbers = [UInt8](repeating: 0, count: 4)
    _ = SecRandomCopyBytes(kSecRandomDefault, count, &numbers)
    return numbers.reversed().reduce(0) { $0 << 8 + UInt32($1) }
  }
}

ये विधियां यह निर्धारित करने के लिए एक अतिरिक्त यादृच्छिक संख्या का UInt8उपयोग करती हैं कि यादृच्छिक संख्या बनाने के लिए कितने s का उपयोग किया जा रहा है। अंतिम पंक्ति धर्मान्तरित [UInt8]करने के लिए UInt16या UInt32

मैं नहीं जानता कि अगर पिछले दो अभी भी वास्तव में यादृच्छिक के रूप में गिना जाता है, लेकिन आप इसे अपनी पसंद के लिए ट्वीक कर सकते हैं :)


आपने चतुराई से मॉडुलो द्वारा शुरू किए गए पूर्वाग्रह से बचा लिया, उसके लिए the1। आपने पाठकों को चेतावनी दी होगी कि आपने ऐसा क्यों किया।
jww

यह दिलचस्प है, मैं वास्तव में इस बात पर विचार नहीं करता था कि मॉडुलो पूर्वाग्रह यहाँ खेलने में हो सकता है। शायद एक छोटी संख्या प्राप्त करने की संभावना एक बड़ी संख्या प्राप्त करने के समान नहीं है।
१:06:०२ पर Zyphrax

2

स्विफ्ट 4.2

स्विफ्ट 4.2 में मानक पुस्तकालय में एक देशी और काफी पूर्ण-यादृच्छिक रैंडम एपीआई शामिल है। ( स्विफ्ट इवोल्यूशन प्रस्ताव SE-0202 )

let intBetween0to9 = Int.random(in: 0...9) 
let doubleBetween0to1 = Double.random(in: 0...1)

सभी संख्या प्रकारों में स्थिर रैंडम होता है (:) में जो रेंज लेता है और दिए गए रेंज में रैंडम नंबर देता है


1

स्विफ्ट 4.2, एक्सकोड 10.1

IOS, macOS और tvOS के लिए आप Xcode के फ्रेमवर्क में सिस्टम-वाइड यादृच्छिक स्रोत का उपयोग कर सकते हैं GameKit। यहाँ आप GKRandomSourceइसकी sharedRandom()कक्षा विधि के साथ कक्षा पा सकते हैं :

import GameKit

let number: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

func randomGenerator() -> Int {
    let random = GKRandomSource.sharedRandom().nextInt(upperBound: number.count)
    return number[random]
}
randomGenerator()

या बस एक randomElement()विधि का उपयोग करें जो संग्रह का एक यादृच्छिक तत्व लौटाता है:

let number: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let randomNumber = number.randomElement()!
print(randomNumber)

0

आप GeneratorOfइस तरह का उपयोग कर सकते हैं :

var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
    _ -> Int? in
    fibs.append(fibs.reduce(0, combine:+))
    return fibs.removeAtIndex(0)
}

println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())
println(fibGenerator.next())

3
कैसा है फिबोनाची यादृच्छिक?
निकोलाई रुहे

हाय निकोलाई, यह कोड ब्लॉक पुराना संस्करण स्विफ्ट 1.2 है। अगर आप नई स्विफ्ट 2.0 को आजमाते हैं। यह काम नहीं करेगा।
दुरुल दल्कानत

2
मैं समझता हूं, लेकिन फिर भी यह मेरे लिए एक रिटेनर जनरेटर की तरह दिखता है, यादृच्छिक संख्या नहीं, जैसे प्रश्न में पूछा गया है।
निकोलाई रुहे

0

मैं एक यादृच्छिक संख्या उत्पन्न करने के लिए इस कोड का उपयोग करता हूं:

//
//  FactModel.swift
//  Collection
//
//  Created by Ahmadreza Shamimi on 6/11/16.
//  Copyright © 2016 Ahmadreza Shamimi. All rights reserved.
//

import GameKit

struct FactModel {

    let fun  = ["I love swift","My name is Ahmadreza","I love coding" ,"I love PHP","My name is ALireza","I love Coding too"]


    func getRandomNumber() -> String {

        let randomNumber  = GKRandomSource.sharedRandom().nextIntWithUpperBound(fun.count)

        return fun[randomNumber]
    }
}

2
एसओ में आपका स्वागत है। कोड केवल उत्तर हतोत्साहित करता है - कृपया अपने उत्तर को यह समझाने के लिए संपादित करें कि यह कोड प्रश्न का उत्तर क्यों देता है, और यह कैसे काम करता है। अधिक जानकारी के लिए stackoverflow.com/help/how-to-answer देखें।
टिम मेलोन

2
कृपया अपने उत्तर के आसपास कुछ संदर्भ प्रदान करें, और स्टैकओवरफ़्लो में आपका स्वागत है। :)
जोनाथन यूस्टेस

0

विवरण

xCode 9.1, स्विफ्ट 4

गणित उन्मुख समाधान (1)

import Foundation

class Random {

    subscript<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
        get {
            return rand(min-1, max+1)
        }
    }
}

let rand = Random()

func rand<T>(_ min: T, _ max: T) -> T where T : BinaryInteger {
    let _min = min + 1
    let difference = max - _min
    return T(arc4random_uniform(UInt32(difference))) + _min
}

समाधान का उपयोग (1)

let x = rand(-5, 5)       // x = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
let x = rand[0, 10]       // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

प्रोग्रामर उन्मुख समाधान (2)

के लिए मत भूलना गणित उन्मुख समाधान को जोड़ने (1) कोड यहाँ

import Foundation

extension CountableRange where Bound : BinaryInteger {

    var random: Bound {
        return rand(lowerBound-1, upperBound)
    }
}

extension CountableClosedRange where Bound : BinaryInteger {

    var random: Bound {
        return rand[lowerBound, upperBound]
    }
}

समाधान का उपयोग (2)

let x = (-8..<2).random           // x = [-8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
let x = (0..<10).random           // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let x = (-10 ... -2).random       // x = [-10, -9, -8, -7, -6, -5, -4, -3, -2]

पूरा नमूना

के लिए मत भूलना समाधान (1) और समाधान (2) कोड जोड़ यहाँ

private func generateRandNums(closure:()->(Int)) {

    var allNums = Set<Int>()
    for _ in 0..<100 {
        allNums.insert(closure())
    }
    print(allNums.sorted{ $0 < $1 })
}

generateRandNums {
    (-8..<2).random
}

generateRandNums {
    (0..<10).random
}

generateRandNums {
    (-10 ... -2).random
}

generateRandNums {
    rand(-5, 5)
}
generateRandNums {
    rand[0, 10]
}

नमूना परिणाम

यहां छवि विवरण दर्ज करें


2
यह उत्तर बंद विषय है। सवाल यह था कि एक यादृच्छिक संख्या कैसे उत्पन्न की जाए। यादृच्छिक संख्या पुस्तकालय बनाने का तरीका नहीं। शीश।
एंड्रयू पॉल सिमंस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.