BlessRNG noma uhlole i-RNG ukuthola ubulungisa

BlessRNG noma uhlole i-RNG ukuthola ubulungisa

Ekuthuthukisweni kwegeyimu, ngokuvamile kudingeka ubophe okuthile ngokungahleliwe: Ubunye bunokungahleliwe kwakho kwalokhu, futhi ngokuhambisana nakho kukhona i-System.Random. Ngesinye isikhathi, kwenye yamaphrojekthi, ngathola umbono wokuthi womabili angasebenza ngokuhlukile (yize kufanele abe nokusatshalaliswa okulinganayo).

Khona-ke abazange bangene emininingwaneni - kwanele ukuthi ukushintshela ku-System.Random kulungise zonke izinkinga. Manje sinqume ukukubheka kabanzi futhi senze ucwaningo oluncane: ukuthi ama-RNG “achemile” noma angabikezelwa kanjani, nokuthi iyiphi okufanele siyikhethe. Ngaphezu kwalokho, ngike ngezwa izikhathi ezingaphezu kwesisodwa imibono engqubuzanayo mayelana “nokwethembeka” kwabo - ake sizame ukuthola ukuthi imiphumela yangempela iqhathaniswa kanjani naleyo emenyezelwe.

Uhlelo lwezemfundo olufushane noma i-RNG empeleni iyi-RNG

Uma usuwajwayele kakade abakhiqizi bezinombolo abangahleliwe, ungakwazi ukweqela ngokushesha esigabeni "sokuhlola".

Izinombolo ezingahleliwe (RN) ziwukulandelana kwezinombolo ezikhiqizwa kusetshenziswa inqubo ethile engahleliwe (eyaxaka), umthombo we-entropy. Okusho ukuthi, lokhu ukulandelana okuyingxenye yayo engaxhunywanga yinoma yimuphi umthetho wezibalo - azinabudlelwane bembangela-nomphumela.

Okudala inombolo engahleliwe kubizwa ngokuthi i-random number generator (RNG). Kungase kubonakale sengathi yonke into iyisisekelo, kodwa uma sisuka kumbono wokuzijwayeza, empeleni akulula kakhulu ukusebenzisa i-algorithm yesofthiwe yokukhiqiza ukulandelana okunjalo.

Isizathu siwukuthi ukungabikho kwaleyo nxushunxushu kuma-elekthronikhi wabathengi besimanje. Ngaphandle kwakho, izinombolo ezingahleliwe ziyayeka ukuvela ngokungahleliwe, futhi ijeneretha yazo iphenduka umsebenzi ojwayelekile wezimpikiswano ezichazwe ngokusobala. Ngobuningi bezinto ezikhethekile emkhakheni we-IT, lokhu kuyinkinga enkulu (isibonelo, i-cryptography), kodwa kwabanye kunesixazululo esamukelekayo ngokuphelele.

Kuyadingeka ukubhala i-algorithm ezobuya, kungakhathaliseki ukuthi izinombolo ezingahleliwe ngempela, kodwa eduze ngangokunokwenzeka kuzo - okuthiwa izinombolo ze-pseudo-random (PRN). I-algorithm kuleli cala ibizwa ngokuthi i-pseudorandom number generator (PRNG).

Kunezinketho ezimbalwa zokwenza i-PRNG, kodwa okulandelayo kuzofaneleka kuwo wonke umuntu:

  1. Isidingo sokuqala sokuqala.

    I-PRNG ayinawo umthombo we-entropy, ngakho-ke kufanele inikezwe isimo sokuqala ngaphambi kokusetshenziswa. Icaciswa njengenombolo (noma i-vector) futhi ibizwa ngembewu (imbewu engahleliwe). Imvamisa, isibali sewashi leprosesa noma inani lezinombolo lesikhathi sohlelo lisetshenziswa njengembewu.

  2. Ukukhiqiza kabusha ngokulandelana.

    I-PRNG inquma ngokuphelele, ngakho imbewu ecaciswe ngesikhathi sokuqalisa inquma ngokuhlukile ukulandelana kwezinombolo okuzayo. Lokhu kusho ukuthi i-PRNG ehlukile eqaliswe ngembewu efanayo (ngezikhathi ezihlukene, ezinhlelweni ezihlukene, kumadivaysi ahlukene) izokhiqiza ukulandelana okufanayo.

Udinga futhi ukwazi ukusabalalisa kwamathuba okubonisa i-PRNG - ukuthi izokhiqiza ziphi izinombolo kanye nokuthi imaphi amathuba. Ngokuvamile lokhu kungaba ukusatshalaliswa okuvamile noma ukusatshalaliswa okufanayo.
BlessRNG noma uhlole i-RNG ukuthola ubulungisa
Ukusabalalisa okuvamile (kwesokunxele) nokusabalalisa okufanayo (kwesokudla)

Ake sithi sinezinhlangothi ezingu-24. Uma uyiphonsa, amathuba okuthola eyodwa azolingana no-1/24 (okufana nethuba lokuthola enye inombolo). Uma wenza ukuphonswa okuningi futhi urekhoda imiphumela, uzoqaphela ukuthi zonke iziphetho ziyawa cishe ngefrequency efanayo. Empeleni, lokhu kufa kungabhekwa njenge-RNG enokusabalalisa okufanayo.

Kuthiwani uma uphonsa amadayisi angu-10 ngesikhathi esisodwa futhi ubale amaphuzu aphelele? Ingabe ukufana kuyogcinwa kukho? Cha. Ngokuvamile, inani lizobe lisondele kumaphuzu angu-125, okungukuthi, inani elithile eliphakathi. Futhi ngenxa yalokho, nangaphambi kokuphonsa, ungakwazi ukulinganisa umphumela wesikhathi esizayo.

Isizathu ukuthi kunenani elikhulu lezinhlanganisela zokuthola amaphuzu amaphakathi. Ukuqhelana nayo, izinhlanganisela ezimbalwa - futhi, ngokufanele, aphansi amathuba okulahlekelwa. Uma le datha ibonwa ngeso lengqondo, izofana ngokungafani nesimo sensimbi. Ngakho-ke, ngokunwebeka okuthile, uhlelo lwamadayisi ayi-10 lungabizwa ngokuthi i-RNG enokusabalalisa okuvamile.

Esinye isibonelo, kulokhu kuphela endizeni - ukudubula ilitshe. Umdubuli uzoba yi-RNG ekhiqiza izinombolo ezimbili (x, y) eziboniswa kugrafu.
BlessRNG noma uhlole i-RNG ukuthola ubulungisa
Vumelana ukuthi inketho engakwesokunxele iseduze nempilo yangempela - lena i-RNG enokusabalalisa okuvamile. Kodwa uma udinga ukusabalalisa izinkanyezi esibhakabhakeni esimnyama, khona-ke inketho efanele, etholwe kusetshenziswa i-RNG ngokusabalalisa okufanayo, ifaneleka kangcono. Ngokuvamile, khetha i-generator kuye ngomsebenzi owenziwayo.

Manje ake sikhulume nge-entropy yokulandelana kwe-PNG. Isibonelo, kukhona ukulandelana okuqala kanje:

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, ...

Zingahleliwe kangakanani lezi zinombolo ekuqaleni? Ake siqale ngokubheka ukusatshalaliswa.
BlessRNG noma uhlole i-RNG ukuthola ubulungisa
Kubukeka kusondele kumfaniswano, kepha uma ufunda ukulandelana kwezinombolo ezimbili futhi uzihumushe njengezixhumanisi endizeni, uthola lokhu:
BlessRNG noma uhlole i-RNG ukuthola ubulungisa
Amaphethini abonakala ngokucacile. Futhi njengoba idatha elandelanayo ihlelwe ngendlela ethile (okungukuthi, ine-entropy ephansi), lokhu kungadala lokho "kuchema" kakhulu. Okungenani, i-PRNG enjalo ayifaneleki kakhulu ukukhiqiza izixhumanisi endizeni.

Okunye ukulandelana:

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, ...

Konke kubonakala kuhamba kahle lapha ngisho nasendizeni:
BlessRNG noma uhlole i-RNG ukuthola ubulungisa
Ake sibheke umthamo (funda izinombolo ezintathu ngesikhathi):
BlessRNG noma uhlole i-RNG ukuthola ubulungisa
Futhi futhi amaphethini. Akusenzeki ukwakha umfanekiso ngezinhlangothi ezine. Kodwa amaphethini angaba khona kulobu bukhulu nakumakhudlwana.

Ku-cryptography, lapho izidingo eziqine kakhulu zibekwe kuma-PRNGs, isimo esinjalo asamukeleki ngokwengxenye. Ngakho-ke, ama-algorithms akhethekile athuthukisiwe ukuhlola ikhwalithi yawo, esingeke siyithinte manje. Isihloko sibanzi futhi sifanele i-athikili ehlukile.

Ukuhlola

Uma singazi okuthile ngokuqinisekile, singasebenza kanjani ngakho? Ingabe kufanelekile ukuwela umgwaqo uma ungazi ukuthi yiliphi irobhothi elikuvumelayo? Imiphumela ingase yehluke.

Okufanayo kuya ngokungahleliwe okudume kabi e-Unity. Kuhle uma imibhalo yembula imininingwane edingekayo, kodwa indaba okukhulunywe ngayo ekuqaleni kwesihloko yenzeka ngokunembile ngenxa yokuntuleka kwemininingwane efiselekayo.

Futhi uma ungazi ukuthi ithuluzi lisebenza kanjani, ngeke ukwazi ukulisebenzisa ngendlela efanele. Ngokuvamile, isikhathi sesifikile sokuhlola nokwenza isilingo ukuze ekugcineni uqiniseke okungenani mayelana nokusabalalisa.

Isixazululo sasilula futhi sisebenza kahle - qoqa izibalo, thola idatha yenhloso futhi ubheke imiphumela.

Isihloko sokufunda

Kunezindlela ezimbalwa zokwenza izinombolo ezingahleliwe ku-Unity - sihlole ezinhlanu.

  1. Uhlelo.Okungahleliwe.Okulandelayo(). Ikhiqiza izinombolo ebangeni elinikeziwe lamanani.
  2. System.Random.NextDouble(). Ikhiqiza izinombolo ezinembayo eziphindwe kabili kububanzi ukusuka ku-[0; 1).
  3. I-UnityEngine.Random.Range(). Ikhiqiza izinombolo ezinembayo (ziyantanta) ebangeni elinikeziwe lamanani.
  4. I-UnityEngine.Random.value. Ikhiqiza izinombolo ezinembayo (ezintantayo) ebangeni ukusuka ku-[0; 1).
  5. I-Unity.Mathematics.Random.NextFloat(). Ingxenye yomtapo wolwazi omusha we-Unity.Mathematics. Ikhiqiza izinombolo ezinembayo (ziyantanta) ebangeni elinikeziwe lamanani.

Cishe yonke indawo kumadokhumenti kwacaciswa ukusatshalaliswa okufanayo, ngaphandle kwe-UnityEngine.Random.value (lapho ukusatshalaliswa kwakungacaciswanga khona, kodwa ngesifaniso ne-UnityEngine.Random.Range() umfaniswano bekulindeleke futhi) kanye ne-Unity.Mathematics.Okungahleliwe. .NextFloat() (lapho kokuthi Isisekelo kuyi-algorithm ye-xorshift, okusho ukuthi futhi udinga ukulinda ukusabalalisa okufanayo).

Ngokuzenzakalelayo, imiphumela elindelekile ithathwe njengaleyo eshiwo kumadokhumenti.

Indlela yokwenza

Sibhale uhlelo lokusebenza oluncane olukhiqize ukulandelana kwezinombolo ezingahleliwe sisebenzisa indlela ngayinye ethulwayo futhi sagcina imiphumela ukuze iqhubeke nokusebenza.

Ubude bokulandelana ngakunye izinombolo eziyi-100.
Ububanzi bezinombolo ezingahleliwe ngu-[0, 100).

Idatha iqoqwe kusuka ezinkundleni ezimbalwa eziqondiwe:

  • Windows
    — Ubunye v2018.3.14f1, Imodi Yomhleli, Mono, .NET Standard 2.0
  • macOS
    — Ubunye v2018.3.14f1, Imodi Yomhleli, Mono, .NET Standard 2.0
    — Ubunye v5.6.4p4, Imodi yomhleli, iMono, .NET Standard 2.0
  • Android
    — Ubunye v2018.3.14f1, ukwakha idivayisi ngayinye, Mono, .NET Standard 2.0
  • iOS
    — Ubunye v2018.3.14f1, ukwakha idivayisi ngayinye, il2cpp, .NET Standard 2.0

Ukuqaliswa

Sinezindlela eziningana ezahlukene zokwenza izinombolo ezingahleliwe. Ngamunye wabo, sizobhala ikilasi elihlukile le-wrapper, okufanele linikeze:

  1. Amathuba okusetha ububanzi bamanani[min/max). Izosethwa kusetshenziswa umakhi.
  2. Indlela yokubuyisela i-MF. Ake sikhethe ukuntanta njengohlobo, njengoba kuvame kakhulu.
  3. Igama lendlela yokukhiqiza yokumaka imiphumela. Ukuze kube lula, sizobuyisela njengenani igama eligcwele lekilasi + igama lendlela esetshenziswe ukukhiqiza i-MF.

Okokuqala, ake simemezele amazwibela azomelwa isixhumi esibonakalayo se-IRAndomGenerator:

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

        float Generate();
    }
}

Ukwenziwa Kwesistimu.Okungahleliwe.Okulandelayo()

Le ndlela ikuvumela ukuthi usethe uhla lwamanani, kodwa ibuyisela izinombolo, kodwa ama-float ayadingeka. Ungavele uhumushe inani eliphelele njengokuntanta, noma unganweba ububanzi bamanani ngama-oda amaningana wobukhulu, uwanxephezele ngesizukulwane ngasinye se-midrange. Umphumela uzoba into efana nephoyinti elingashintshi elinohlelo olunikeziwe lokunemba. Sizosebenzisa le nketho njengoba iseduze nenani langempela lokuntanta.

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;
    }
}

Ukwenziwa Kwesistimu.Okungahleliwe.NextDouble()

Lapha uhla olungaguquki lwamanani[0; 1). Ukuyiveza kuleyo eshiwo kumakhi, sisebenzisa i-arithmetic elula: X * (ubuningi − min) + min.

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;
    }
}

Ukusetshenziswa kwe-UnityEngine.Random.Range()

Le ndlela yesigaba se-UnityEngine.Random static ikuvumela ukuthi usethe uhla lwamanani futhi ubuyisele uhlobo lokuntanta. Akudingekile ukuba wenze izinguquko ezengeziwe.

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);
    }
}

Ukusetshenziswa kwe-UnityEngine.Random.value

Isakhiwo senani sesigaba esimile se-UnityEngine.Random ibuyisela uhlobo lokuntanta olusuka ebangeni elingaguquki lamanani[0; 1). Masiyifake kububanzi obunikeziwe ngendlela efanayo nalapho sisebenzisa i-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;
    }
}

Ukwenziwa Kobunye.Izibalo.Random.NextFloat()

Indlela ye-NextFloat() yesigaba se-Unity.Mathematics.Random ibuyisela iphoyinti elintantayo lohlobo lokuntanta futhi ikuvumela ukuthi ucacise ububanzi bamanani. I-nuance kuphela ukuthi isenzakalo ngasinye se-Unity.Mathematics.Okungahleliwe kuyodingeka ukuthi kuqalwe ngembewu ethile - ngale ndlela sizogwema ukukhiqiza ukulandelana okuphindaphindayo.

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);
    }
}

Ukusetshenziswa kwe-MainController

Ukuqaliswa okuningana kwe-IRandomGenerator sekulungile. Okulandelayo, udinga ukukhiqiza ukulandelana futhi ulondoloze idathasethi ewumphumela ukuze icutshungulwe. Ukuze senze lokhu, sizodala indawo kanye neskripthi esincane se-MainController ku-Unity, esizokwenza wonke umsebenzi odingekayo futhi ngesikhathi esifanayo sibe nesibopho sokusebenzisana ne-UI.

Ake simise usayizi wedathasethi kanye nobubanzi bamanani e-MF, futhi sithole indlela ebuyisela uxhaxha lwamajeneretha amisiwe futhi alungele ukusebenza.

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)
            };
        }

        ...
    }
}

Manje masidale isethi yedatha. Kulesi simo, ukukhiqizwa kwedatha kuzohlanganiswa nokurekhoda imiphumela ibe ukusakaza kombhalo (ngefomethi ye-csv). Ukugcina amanani e-IRandomGenerator ngayinye, ikholomu yayo ehlukile inikezwa, futhi umugqa wokuqala uqukethe Igama le-generator.

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();
            }
        }

        ...
    }
}

Okusele nje ukushayela indlela ye-GenerateCsvDataSet bese ulondoloza umphumela efayelini, noma udlulise ngokushesha idatha ngenethiwekhi isuka ecingweni iye kuseva eyamukelayo.

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();
            }
        }

        ...
    }
}

Imithombo yephrojekthi iku I-GitLab.

Imiphumela

Akukho simangaliso esenzekayo. Ababekulindele yilokhu abakuthola - kuzo zonke izimo, ukusatshalaliswa okulinganayo ngaphandle kokwenza uzungu. Angiboni phuzu ekubekeni amagrafu ahlukene ezinkundla - wonke abonisa cishe imiphumela efanayo.

Iqiniso liwukuthi:
BlessRNG noma uhlole i-RNG ukuthola ubulungisa

Ukubona ngeso lengqondo ukulandelana endizeni kuzo zonke izindlela ezinhlanu zezizukulwane:
BlessRNG noma uhlole i-RNG ukuthola ubulungisa

Futhi ukubona ngeso lengqondo 3D. Ngizoshiya kuphela umphumela we-System.Random.Next() ukuze ngingakhiqizi inqwaba yokuqukethwe okufanayo.
BlessRNG noma uhlole i-RNG ukuthola ubulungisa

Indaba ekhulunywe esingenisweni mayelana nokusatshalaliswa okuvamile kwe-UnityEngine.Ngokungahleliwe ayizange iziphinde: kungenzeka ukuthi yayinephutha ekuqaleni, noma kukhona okushintshile enjinini. Kodwa manje siqinisekile.

Source: www.habr.com

Engeza amazwana