BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்

BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்

விளையாட்டு மேம்பாட்டில், நீங்கள் அடிக்கடி சீரற்ற தன்மையுடன் எதையாவது இணைக்க வேண்டும்: ஒற்றுமைக்கு அதன் சொந்த ரேண்டம் உள்ளது, அதற்கு இணையாக System.Random உள்ளது. ஒரு காலத்தில், திட்டங்களில் ஒன்றில், இரண்டும் வித்தியாசமாக வேலை செய்ய முடியும் என்ற எண்ணம் எனக்கு வந்தது (அவை சமமான விநியோகத்தைக் கொண்டிருக்க வேண்டும் என்றாலும்).

பின்னர் அவர்கள் விவரங்களுக்குச் செல்லவில்லை - System.Random க்கு மாறுவது போதுமானது. அனைத்து சிக்கல்களையும் சரிசெய்தது. இப்போது நாங்கள் அதை இன்னும் விரிவாகப் பார்த்து, ஒரு சிறிய ஆராய்ச்சி நடத்த முடிவு செய்தோம்: RNG கள் எவ்வளவு "சார்பு" அல்லது யூகிக்கக்கூடியவை மற்றும் எதைத் தேர்வு செய்வது. மேலும், அவர்களின் "நேர்மை" பற்றி முரண்பட்ட கருத்துக்களை நான் ஒன்றுக்கு மேற்பட்ட முறை கேட்டிருக்கிறேன் - உண்மையான முடிவுகள் அறிவிக்கப்பட்டவற்றுடன் எவ்வாறு ஒப்பிடுகின்றன என்பதைக் கண்டுபிடிக்க முயற்சிப்போம்.

சுருக்கமான கல்வித் திட்டம் அல்லது RNG உண்மையில் RNG ஆகும்

சீரற்ற எண் ஜெனரேட்டர்களை நீங்கள் ஏற்கனவே அறிந்திருந்தால், நீங்கள் உடனடியாக "சோதனை" பகுதிக்குச் செல்லலாம்.

ரேண்டம் எண்கள் (RN) என்பது என்ட்ரோபியின் ஆதாரமான சில சீரற்ற (குழப்பமான) செயல்முறையைப் பயன்படுத்தி உருவாக்கப்பட்ட எண்களின் வரிசையாகும். அதாவது, இது ஒரு வரிசையாகும், அதன் கூறுகள் எந்த கணித விதிகளாலும் ஒன்றோடொன்று இணைக்கப்படவில்லை - அவற்றுக்கு காரணம் மற்றும் விளைவு உறவு இல்லை.

சீரற்ற எண்ணை உருவாக்குவது சீரற்ற எண் ஜெனரேட்டர் (RNG) என்று அழைக்கப்படுகிறது. எல்லாம் ஆரம்பமானது என்று தோன்றுகிறது, ஆனால் நாம் கோட்பாட்டிலிருந்து நடைமுறைக்கு நகர்ந்தால், உண்மையில் அத்தகைய வரிசையை உருவாக்குவதற்கான மென்பொருள் வழிமுறையை செயல்படுத்துவது அவ்வளவு எளிதல்ல.

நவீன நுகர்வோர் மின்னணுவியலில் அதே குழப்பம் இல்லாததே காரணம். இது இல்லாமல், சீரற்ற எண்கள் சீரற்றதாக இருக்காது, மேலும் அவற்றின் ஜெனரேட்டர் வெளிப்படையாக வரையறுக்கப்பட்ட வாதங்களின் சாதாரண செயல்பாடாக மாறும். ஐடி துறையில் உள்ள பல சிறப்புகளுக்கு, இது ஒரு தீவிரமான பிரச்சனை (உதாரணமாக, குறியாக்கவியல்), ஆனால் மற்றவர்களுக்கு முற்றிலும் ஏற்றுக்கொள்ளக்கூடிய தீர்வு உள்ளது.

உண்மையான சீரற்ற எண்கள் இல்லாவிட்டாலும், அவர்களுக்கு முடிந்தவரை நெருக்கமாக இருக்கும் - போலி-ரேண்டம் எண்கள் (PRN) என்று அழைக்கப்படும் ஒரு வழிமுறையை எழுதுவது அவசியம். இந்த வழக்கில் உள்ள அல்காரிதம் ஒரு சூடோராண்டம் எண் ஜெனரேட்டர் (PRNG) என்று அழைக்கப்படுகிறது.

PRNG ஐ உருவாக்க பல விருப்பங்கள் உள்ளன, ஆனால் பின்வருபவை அனைவருக்கும் பொருத்தமானதாக இருக்கும்:

  1. பூர்வாங்க துவக்கத்தின் தேவை.

    PRNG க்கு என்ட்ரோபியின் ஆதாரம் இல்லை, எனவே பயன்பாட்டிற்கு முன் அதற்கு ஆரம்ப நிலை கொடுக்கப்பட வேண்டும். இது ஒரு எண்ணாக (அல்லது திசையன்) குறிப்பிடப்படுகிறது மற்றும் ஒரு விதை (சீரற்ற விதை) என்று அழைக்கப்படுகிறது. பெரும்பாலும், செயலி கடிகார கவுண்டர் அல்லது கணினி நேரத்தின் எண் சமமான ஒரு விதை பயன்படுத்தப்படுகிறது.

  2. வரிசை மறுஉருவாக்கம்.

    PRNG முற்றிலும் உறுதியானது, எனவே துவக்கத்தின் போது குறிப்பிடப்பட்ட விதை எண்களின் முழு எதிர்கால வரிசையையும் தனித்துவமாக தீர்மானிக்கிறது. அதாவது, ஒரே விதையுடன் (வெவ்வேறு நேரங்களில், வெவ்வேறு நிரல்களில், வெவ்வேறு சாதனங்களில்) தொடங்கப்பட்ட ஒரு தனி PRNG ஒரே வரிசையை உருவாக்கும்.

PRNG-ஐ வகைப்படுத்தும் நிகழ்தகவு பரவலையும் நீங்கள் அறிந்து கொள்ள வேண்டும் - அது என்ன எண்களை உருவாக்கும் மற்றும் எந்த நிகழ்தகவுடன். பெரும்பாலும் இது ஒரு சாதாரண விநியோகம் அல்லது ஒரு சீரான விநியோகம்.
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்
இயல்பான விநியோகம் (இடது) மற்றும் சீரான விநியோகம் (வலது)

24 பக்கங்கள் கொண்ட ஒரு நியாயமான சாவு என்று வைத்துக்கொள்வோம். நீங்கள் அதைத் தூக்கி எறிந்தால், ஒன்றைப் பெறுவதற்கான நிகழ்தகவு 1/24 க்கு சமமாக இருக்கும் (வேறு எந்த எண்ணையும் பெறுவதற்கான நிகழ்தகவு). நீங்கள் பல வீசுதல்களைச் செய்து முடிவுகளைப் பதிவு செய்தால், எல்லா விளிம்புகளும் தோராயமாக ஒரே அதிர்வெண்ணில் விழுவதை நீங்கள் கவனிப்பீர்கள். அடிப்படையில், இந்த இறக்கமானது ஒரு சீரான விநியோகத்துடன் கூடிய RNG ஆகக் கருதப்படலாம்.

இந்த 10 பகடைகளை ஒரே நேரத்தில் எறிந்து மொத்த புள்ளிகளை எண்ணினால் என்ன செய்வது? அதற்கு சீரான தன்மை பேணப்படுமா? இல்லை. பெரும்பாலும், தொகை 125 புள்ளிகளுக்கு அருகில் இருக்கும், அதாவது சில சராசரி மதிப்பு. இதன் விளைவாக, வீசுவதற்கு முன்பே, எதிர்கால முடிவை நீங்கள் தோராயமாக மதிப்பிடலாம்.

காரணம், சராசரி மதிப்பெண்ணைப் பெறுவதற்கு அதிக எண்ணிக்கையிலான சேர்க்கைகள் உள்ளன. அதிலிருந்து தொலைவில், குறைவான சேர்க்கைகள் - மற்றும், அதன்படி, இழப்பின் நிகழ்தகவு குறைவாக இருக்கும். இந்தத் தரவு காட்சிப்படுத்தப்பட்டால், அது தெளிவற்ற முறையில் மணியின் வடிவத்தை ஒத்திருக்கும். எனவே, சில நீட்டிப்புகளுடன், 10 பகடைகளின் அமைப்பை சாதாரண விநியோகத்துடன் RNG என்று அழைக்கலாம்.

மற்றொரு உதாரணம், இந்த முறை மட்டுமே விமானத்தில் - இலக்கை நோக்கி சுடுவது. ஷூட்டர் என்பது வரைபடத்தில் காட்டப்படும் ஒரு ஜோடி எண்களை (x, y) உருவாக்கும் RNG ஆக இருக்கும்.
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்
இடதுபுறத்தில் உள்ள விருப்பம் நிஜ வாழ்க்கைக்கு நெருக்கமாக இருப்பதை ஒப்புக்கொள்கிறேன் - இது சாதாரண விநியோகத்துடன் கூடிய RNG ஆகும். ஆனால் நீங்கள் ஒரு இருண்ட வானத்தில் நட்சத்திரங்களை சிதறடிக்க வேண்டும் என்றால், ஒரு சீரான விநியோகத்துடன் RNG ஐப் பயன்படுத்தி பெறப்பட்ட சரியான விருப்பம் மிகவும் பொருத்தமானது. பொதுவாக, கையில் உள்ள பணியைப் பொறுத்து ஒரு ஜெனரேட்டரைத் தேர்ந்தெடுக்கவும்.

இப்போது PNG வரிசையின் என்ட்ரோபி பற்றி பேசலாம். எடுத்துக்காட்டாக, இப்படித் தொடங்கும் ஒரு வரிசை உள்ளது:

89, 93, 33, 32, 82, 21, 4, 42, 11, 8, 60, 95, 53, 30, 42, 19, 34, 35, 62, 23, 44, 38, 74, 36, 52 18, 58, 79, 65, 45, 99, 90, 82, 20, 41, 13, 88, 76, 82, 24, 5, 54, 72, 19, 80, 2, 74, 36, 71, 9, ...

முதல் பார்வையில் இந்த எண்கள் எவ்வளவு சீரற்றவை? விநியோகத்தை சரிபார்த்து ஆரம்பிக்கலாம்.
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்
இது சீரானதாகத் தெரிகிறது, ஆனால் நீங்கள் இரண்டு எண்களின் வரிசையைப் படித்து அவற்றை ஒரு விமானத்தில் ஆயத்தொலைவுகளாக விளக்கினால், நீங்கள் இதைப் பெறுவீர்கள்:
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்
வடிவங்கள் தெளிவாகத் தெரியும். மற்றும் வரிசையில் உள்ள தரவு ஒரு குறிப்பிட்ட வழியில் வரிசைப்படுத்தப்பட்டிருப்பதால் (அதாவது, இது குறைந்த என்ட்ரோபியைக் கொண்டுள்ளது), இது "சார்பு" க்கு வழிவகுக்கும். குறைந்தபட்சம், அத்தகைய PRNG ஒரு விமானத்தில் ஒருங்கிணைப்புகளை உருவாக்க மிகவும் பொருத்தமானது அல்ல.

மற்றொரு வரிசை:

42, 72, 17, 0, 30, 0, 15, 9, 47, 19, 35, 86, 40, 54, 97, 42, 69, 19, 20, 88, 4, 3, 67, 27, 42 56, 17, 14, 20, 40, 80, 97, 1, 31, 69, 13, 88, 89, 76, 9, 4, 85, 17, 88, 70, 10, 42, 98, 96, 53, ...

விமானத்தில் கூட இங்கே எல்லாம் நன்றாக இருக்கிறது.
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்
தொகுதியைப் பார்ப்போம் (ஒரு நேரத்தில் மூன்று எண்களைப் படிக்கவும்):
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்
மீண்டும் வடிவங்கள். நான்கு பரிமாணங்களில் காட்சிப்படுத்தலை உருவாக்குவது இனி சாத்தியமில்லை. ஆனால் இந்த பரிமாணத்திலும் பெரியவற்றிலும் வடிவங்கள் இருக்கலாம்.

கிரிப்டோகிராஃபியில், PRNG களில் மிகக் கடுமையான தேவைகள் விதிக்கப்பட்டால், அத்தகைய நிலைமை திட்டவட்டமாக ஏற்றுக்கொள்ள முடியாதது. எனவே, அவற்றின் தரத்தை மதிப்பிடுவதற்கு சிறப்பு வழிமுறைகள் உருவாக்கப்பட்டுள்ளன, அதை நாம் இப்போது தொட மாட்டோம். தலைப்பு விரிவானது மற்றும் ஒரு தனி கட்டுரைக்கு தகுதியானது.

சோதனை

நமக்கு ஏதாவது உறுதியாகத் தெரியாவிட்டால், அதை எவ்வாறு கையாள்வது? எந்த போக்குவரத்து விளக்கு அனுமதிக்கிறது என்று உங்களுக்குத் தெரியாவிட்டால் சாலையைக் கடப்பது மதிப்புக்குரியதா? விளைவுகள் வேறுபட்டிருக்கலாம்.

யூனிட்டியில் உள்ள மோசமான சீரற்ற தன்மைக்கும் இதுவே செல்கிறது. ஆவணங்கள் தேவையான விவரங்களை வெளிப்படுத்தினால் நல்லது, ஆனால் கட்டுரையின் ஆரம்பத்தில் குறிப்பிடப்பட்ட கதை, விரும்பிய விவரங்கள் இல்லாததால் துல்லியமாக நடந்தது.

கருவி எவ்வாறு செயல்படுகிறது என்பது உங்களுக்குத் தெரியாவிட்டால், அதைச் சரியாகப் பயன்படுத்த முடியாது. பொதுவாக, விநியோகம் பற்றி இறுதியாக உறுதிசெய்ய ஒரு பரிசோதனையை சரிபார்த்து நடத்த வேண்டிய நேரம் வந்துவிட்டது.

தீர்வு எளிமையானது மற்றும் பயனுள்ளது - புள்ளிவிவரங்களைச் சேகரித்து, புறநிலைத் தரவைப் பெறவும் மற்றும் முடிவுகளைப் பார்க்கவும்.

ஆய்வுப் பொருள்

யூனிட்டியில் சீரற்ற எண்களை உருவாக்க பல வழிகள் உள்ளன - நாங்கள் ஐந்தை சோதித்தோம்.

  1. System.Random.Next(). கொடுக்கப்பட்ட மதிப்புகளின் வரம்பில் முழு எண்களை உருவாக்குகிறது.
  2. System.Random.NextDouble(). [0 இலிருந்து வரம்பில் இரட்டை துல்லிய எண்களை உருவாக்குகிறது; 1)
  3. UnityEngine.Random.Range(). கொடுக்கப்பட்ட மதிப்புகளின் வரம்பில் ஒற்றை துல்லிய எண்களை (மிதவைகள்) உருவாக்குகிறது.
  4. UnityEngine.Random.value. [0] இலிருந்து வரம்பில் ஒற்றை துல்லிய எண்களை (மிதவைகள்) உருவாக்குகிறது; 1)
  5. Unity.Mathematics.Random.NextFloat(). புதிய யூனிட்டி.கணித நூலகத்தின் ஒரு பகுதி. கொடுக்கப்பட்ட மதிப்புகளின் வரம்பில் ஒற்றை துல்லிய எண்களை (மிதவைகள்) உருவாக்குகிறது.

UnityEngine.Random.value (விநியோகம் குறிப்பிடப்படவில்லை, ஆனால் UnityEngine.Random.Range() சீருடையுடன் ஒப்பிடுவதன் மூலம் எதிர்பார்க்கப்பட்டது) மற்றும் Unity.Mathematics.Random தவிர, ஆவணத்தில் கிட்டத்தட்ட எல்லா இடங்களிலும் சீரான விநியோகம் குறிப்பிடப்பட்டுள்ளது. .NextFloat() (அடிப்படையில் xorshift அல்காரிதம் உள்ளது, அதாவது மீண்டும் நீங்கள் சீரான விநியோகத்திற்காக காத்திருக்க வேண்டும்).

இயல்பாக, எதிர்பார்த்த முடிவுகள் ஆவணத்தில் குறிப்பிடப்பட்டவையாக எடுக்கப்பட்டன.

நுட்பம்

வழங்கப்பட்ட ஒவ்வொரு முறையையும் பயன்படுத்தி சீரற்ற எண்களின் வரிசைகளை உருவாக்கி, மேலும் செயலாக்கத்திற்கான முடிவுகளைச் சேமித்த ஒரு சிறிய பயன்பாட்டை நாங்கள் எழுதினோம்.

ஒவ்வொரு வரிசையின் நீளமும் 100 எண்கள்.
சீரற்ற எண்களின் வரம்பு [0, 100) ஆகும்.

பல இலக்கு தளங்களில் இருந்து தரவு சேகரிக்கப்பட்டது:

  • விண்டோஸ்
    — Unity v2018.3.14f1, Editor mode, Mono, .NET Standard 2.0
  • MacOS
    — Unity v2018.3.14f1, Editor mode, Mono, .NET Standard 2.0
    — யூனிட்டி v5.6.4p4, எடிட்டர் பயன்முறை, மோனோ, .NET ஸ்டாண்டர்ட் 2.0
  • அண்ட்ராய்டு
    — யூனிட்டி v2018.3.14f1, ஒவ்வொரு சாதனத்திற்கும் உருவாக்கம், மோனோ, .NET ஸ்டாண்டர்ட் 2.0
  • iOS,
    — யூனிட்டி v2018.3.14f1, ஒவ்வொரு சாதனத்திற்கும் உருவாக்கம், il2cpp, .NET ஸ்டாண்டர்ட் 2.0

Реализация

சீரற்ற எண்களை உருவாக்க எங்களிடம் பல்வேறு வழிகள் உள்ளன. அவை ஒவ்வொன்றிற்கும், நாங்கள் ஒரு தனி ரேப்பர் வகுப்பை எழுதுவோம், இது வழங்க வேண்டும்:

  1. மதிப்புகளின் வரம்பை அமைக்கும் சாத்தியம் [நிமிடம்/அதிகபட்சம்). கன்ஸ்ட்ரக்டர் மூலம் அமைக்கப்படும்.
  2. MF திரும்பும் முறை. float ஐ வகையாக தேர்வு செய்வோம், ஏனெனில் இது மிகவும் பொதுவானது.
  3. முடிவுகளைக் குறிப்பதற்கான தலைமுறை முறையின் பெயர். வசதிக்காக, வகுப்பின் முழுப் பெயர் + MF ஐ உருவாக்கப் பயன்படுத்தப்படும் முறையின் பெயரை மதிப்பாகத் தருவோம்.

முதலில், IrandomGenerator இடைமுகத்தால் குறிப்பிடப்படும் சுருக்கத்தை அறிவிப்போம்:

namespace RandomDistribution
{
    public interface IRandomGenerator
    {
        string Name { get; }

        float Generate();
    }
}

System.Random.Next() செயல்படுத்துதல்

இந்த முறை மதிப்புகளின் வரம்பை அமைக்க உங்களை அனுமதிக்கிறது, ஆனால் இது முழு எண்களை வழங்குகிறது, ஆனால் மிதவைகள் தேவை. நீங்கள் முழு எண்ணை ஒரு மிதவையாக விளக்கலாம் அல்லது மதிப்புகளின் வரம்பை பல ஆர்டர்களால் விரிவாக்கலாம், மிட்ரேஞ்சின் ஒவ்வொரு தலைமுறையிலும் அவற்றை ஈடுசெய்யலாம். கொடுக்கப்பட்ட துல்லியமான வரிசையுடன் நிலையான புள்ளி போன்ற முடிவு இருக்கும். இது உண்மையான மிதவை மதிப்புக்கு நெருக்கமாக இருப்பதால், இந்த விருப்பத்தைப் பயன்படுத்துவோம்.

using System;

namespace RandomDistribution
{
    public class SystemIntegerRandomGenerator : IRandomGenerator
    {
        private const int DefaultFactor = 100000;
        
        private readonly Random _generator = new Random();
        private readonly int _min;
        private readonly int _max;
        private readonly int _factor;


        public string Name => "System.Random.Next()";


        public SystemIntegerRandomGenerator(float min, float max, int factor = DefaultFactor)
        {
            _min = (int)min * factor;
            _max = (int)max * factor;
            _factor = factor;
        }


        public float Generate() => (float)_generator.Next(_min, _max) / _factor;
    }
}

System.Random.NextDouble() செயல்படுத்துதல்

இங்கே மதிப்புகளின் நிலையான வரம்பு [0; 1) கன்ஸ்ட்ரக்டரில் குறிப்பிடப்பட்டுள்ளவற்றில் அதைத் திட்டமிட, எளிய எண்கணிதத்தைப் பயன்படுத்துகிறோம்: X * (அதிகபட்சம் - நிமிடம்) + நிமிடம்.

using System;

namespace RandomDistribution
{
    public class SystemDoubleRandomGenerator : IRandomGenerator
    {
        private readonly Random _generator = new Random();
        private readonly double _factor;
        private readonly float _min;


        public string Name => "System.Random.NextDouble()";


        public SystemDoubleRandomGenerator(float min, float max)
        {
            _factor = max - min;
            _min = min;
        }


        public float Generate() => (float)(_generator.NextDouble() * _factor) + _min;
    }
}

UnityEngine.Random.Range() செயல்படுத்துதல்

UnityEngine.Random நிலையான வகுப்பின் இந்த முறையானது மதிப்புகளின் வரம்பை அமைக்க உங்களை அனுமதிக்கிறது மற்றும் மிதவை வகையை வழங்குகிறது. நீங்கள் எந்த கூடுதல் மாற்றங்களையும் செய்ய வேண்டியதில்லை.

using UnityEngine;

namespace RandomDistribution
{
    public class UnityRandomRangeGenerator : IRandomGenerator
    {
        private readonly float _min;
        private readonly float _max;


        public string Name => "UnityEngine.Random.Range()";


        public UnityRandomRangeGenerator(float min, float max)
        {
            _min = min;
            _max = max;
        }


        public float Generate() => Random.Range(_min, _max);
    }
}

UnityEngine.Random.value ஐ செயல்படுத்துதல்

நிலையான வகுப்பு UnityEngine இன் மதிப்பு சொத்து. ரேண்டம் ஒரு நிலையான வரம்பில் இருந்து ஒரு மிதவை வகையை வழங்குகிறது [0; 1) System.Random.NextDouble() ஐச் செயல்படுத்தும்போது அதே வழியில் கொடுக்கப்பட்ட வரம்பில் அதைத் திட்டமிடுவோம்.

using UnityEngine;

namespace RandomDistribution
{
    public class UnityRandomValueGenerator : IRandomGenerator
    {
        private readonly float _factor;
        private readonly float _min;


        public string Name => "UnityEngine.Random.value";


        public UnityRandomValueGenerator(float min, float max)
        {
            _factor = max - min;
            _min = min;
        }


        public float Generate() => (float)(Random.value * _factor) + _min;
    }
}

ஒற்றுமை.கணிதம்.Random.NextFloat() செயல்படுத்துதல்

Unity.Mathematics.Random class இன் NextFloat() முறையானது மிதவை வகையின் மிதக்கும் புள்ளியை வழங்குகிறது மற்றும் மதிப்புகளின் வரம்பைக் குறிப்பிட உங்களை அனுமதிக்கிறது. ஒரே நுணுக்கம் என்னவென்றால், யூனிட்டி.கணிதம்.ரேண்டம் ஆகியவற்றின் ஒவ்வொரு நிகழ்வும் சில விதைகளுடன் தொடங்கப்பட வேண்டும் - இந்த வழியில் நாம் மீண்டும் மீண்டும் வரிசைகளை உருவாக்குவதைத் தவிர்ப்போம்.

using Unity.Mathematics;

namespace RandomDistribution
{
    public class UnityMathematicsRandomValueGenerator : IRandomGenerator
    {
        private Random _generator;
        private readonly float _min;
        private readonly float _max;


        public string Name => "Unity.Mathematics.Random.NextFloat()";


        public UnityMathematicsRandomValueGenerator(float min, float max)
        {
            _min = min;
            _max = max;
            _generator = new Random();
            _generator.InitState(unchecked((uint)System.DateTime.Now.Ticks));
        }


        public float Generate() => _generator.NextFloat(_min, _max);
    }
}

MainController ஐ செயல்படுத்துதல்

IrandomGenerator இன் பல செயலாக்கங்கள் தயாராக உள்ளன. அடுத்து, நீங்கள் வரிசைகளை உருவாக்கி, செயலாக்கத்திற்கான தரவுத்தொகுப்பைச் சேமிக்க வேண்டும். இதைச் செய்ய, யூனிட்டியில் ஒரு காட்சி மற்றும் ஒரு சிறிய மெயின்கண்ட்ரோலர் ஸ்கிரிப்டை உருவாக்குவோம், இது தேவையான அனைத்து வேலைகளையும் செய்யும் மற்றும் அதே நேரத்தில் UI உடனான தொடர்புக்கு பொறுப்பாகும்.

தரவுத்தொகுப்பின் அளவு மற்றும் MF மதிப்புகளின் வரம்பை அமைப்போம், மேலும் உள்ளமைக்கப்பட்ட மற்றும் வேலை செய்யத் தயாராக உள்ள ஜெனரேட்டர்களின் வரிசையை வழங்கும் முறையைப் பெறுவோம்.

namespace RandomDistribution
{
    public class MainController : MonoBehaviour
    {
        private const int DefaultDatasetSize = 100000;

        public float MinValue = 0f;
        public float MaxValue = 100f;

        ...

        private IRandomGenerator[] CreateRandomGenerators()
        {
            return new IRandomGenerator[]
            {
                new SystemIntegerRandomGenerator(MinValue, MaxValue),
                new SystemDoubleRandomGenerator(MinValue, MaxValue),
                new UnityRandomRangeGenerator(MinValue, MaxValue),
                new UnityRandomValueGenerator(MinValue, MaxValue),
                new UnityMathematicsRandomValueGenerator(MinValue, MaxValue)
            };
        }

        ...
    }
}

இப்போது ஒரு தரவுத்தொகுப்பை உருவாக்குவோம். இந்த வழக்கில், தரவு உருவாக்கம் முடிவுகளை உரை ஸ்ட்ரீமில் (csv வடிவத்தில்) பதிவு செய்வதோடு இணைக்கப்படும். ஒவ்வொரு IRandomGenerator இன் மதிப்புகளையும் சேமிக்க, அதன் சொந்த தனி நெடுவரிசை ஒதுக்கப்பட்டுள்ளது, மேலும் முதல் வரியில் ஜெனரேட்டரின் பெயர் உள்ளது.

namespace RandomDistribution
{
    public class MainController : MonoBehaviour
    {
        ...
		
        private void GenerateCsvDataSet(TextWriter writer, int dataSetSize, params IRandomGenerator[] generators)
        {
            const char separator = ',';
            int lastIdx = generators.Length - 1;

            // write header
            for (int j = 0; j <= lastIdx; j++)
            {
                writer.Write(generators[j].Name);
                if (j != lastIdx)
                    writer.Write(separator);
            }
            writer.WriteLine();

            // write data
            for (int i = 0; i <= dataSetSize; i++)
            {
                for (int j = 0; j <= lastIdx; j++)
                {
                    writer.Write(generators[j].Generate());
                    if (j != lastIdx)
                        writer.Write(separator);
                }

                if (i != dataSetSize)
                    writer.WriteLine();
            }
        }

        ...
    }
}

எஞ்சியிருப்பது GenerateCsvDataSet முறையை அழைத்து முடிவை ஒரு கோப்பில் சேமிக்கவும் அல்லது உடனடியாக நெட்வொர்க்கில் உள்ள தரவை இறுதி சாதனத்திலிருந்து பெறும் சேவையகத்திற்கு மாற்றவும்.

namespace RandomDistribution
{
    public class MainController : MonoBehaviour
    {
        ...
		
        public void GenerateCsvDataSet(string path, int dataSetSize, params IRandomGenerator[] generators)
        {
            using (var writer = File.CreateText(path))
            {
                GenerateCsvDataSet(writer, dataSetSize, generators);
            }
        }


        public string GenerateCsvDataSet(int dataSetSize, params IRandomGenerator[] generators)
        {
            using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
            {
                GenerateCsvDataSet(writer, dataSetSize, generators);
                return writer.ToString();
            }
        }

        ...
    }
}

திட்ட ஆதாரங்கள் உள்ளன GitLab.

Результаты

எந்த அதிசயமும் நடக்கவில்லை. அவர்கள் எதிர்பார்த்தது அவர்களுக்குக் கிடைத்தது - எல்லா சந்தர்ப்பங்களிலும், சதிகளின் குறிப்பு இல்லாமல் சமமான விநியோகம். பிளாட்ஃபார்ம்களுக்கு தனித்தனி வரைபடங்களை வைப்பதில் எனக்கு முக்கியமில்லை - அவை அனைத்தும் தோராயமாக ஒரே மாதிரியான முடிவுகளைக் காட்டுகின்றன.

யதார்த்தம் இதுதான்:
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்

அனைத்து ஐந்து தலைமுறை முறைகளிலிருந்தும் ஒரு விமானத்தில் காட்சிகளின் காட்சிப்படுத்தல்:
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்

மற்றும் 3டியில் காட்சிப்படுத்தல். ஒரே மாதிரியான உள்ளடக்கத்தை உருவாக்காமல் இருக்க, System.Random.Next() இன் முடிவை மட்டும் விட்டுவிடுகிறேன்.
BlessRNG அல்லது RNGயை நியாயமானதா என சரிபார்க்கவும்

UnityEngine.Random இன் இயல்பான விநியோகம் பற்றிய அறிமுகத்தில் கூறப்பட்ட கதை மீண்டும் மீண்டும் வரவில்லை: ஒன்று ஆரம்பத்தில் தவறாக இருந்தது அல்லது இயந்திரத்தில் ஏதோ மாற்றம் ஏற்பட்டுள்ளது. ஆனால் இப்போது உறுதியாக இருக்கிறோம்.

ஆதாரம்: www.habr.com

கருத்தைச் சேர்