BlessRNG okanye ukujonga i-RNG ngobulungisa

BlessRNG okanye ukujonga i-RNG ngobulungisa

Kuphuhliso lomdlalo, udla ngokufuna ukubopha into ngokungenamkhethe: Umanyano luneRandom yalo kule nto, kwaye ngokuhambelana nayo kukho iSystem.Random. Kudala, kwenye yeeprojekthi, ndafumana umbono wokuba zombini zinokusebenza ngokwahlukileyo (nangona zifanele zisasazwe ngokulinganayo).

Emva koko abazange bangene kwiinkcukacha - kwakwanele ukuba ukutshintshela kwi-System.Random kulungiswe zonke iingxaki. Ngoku sigqibe kwelokuba siyijonge ngakumbi kwaye siqhube uphando oluncinci: ukuba "icala" okanye ii-RNG eziqikelelwayo zinjani, kwaye yeyiphi ekufuneka ikhethe. Ngaphezu koko, ndikhe ndeva izimvo eziphikisanayo malunga "nokunyaniseka" kwabo - makhe sizame ukufumanisa ukuba iziphumo zokwenyani zithelekiswa njani nezibhengeziweyo.

Inkqubo yemfundo emfutshane okanye iRNG yiRNG ngokwenene

Ukuba sele uqhelene neejenereyitha zamanani angaqhelekanga, ngoko ungatsiba ngoko nangoko uye kwicandelo "loVavanyo".

Amanani angaqhelekanga (RN) lulandelelwano lwamanani avelisiweyo kusetyenziswa inkqubo ethile engaqhelekanga (chaotic), umthombo we-entropy. Oko kukuthi, olu lulandelelwano oluneziqalelo ezingadityaniswanga nguwuphi na umthetho wezibalo - azinabudlelwane besizathu-kunye nesiphumo.

Yintoni eyenza inani elingaqhelekanga libizwa ngokuba yi-random number generator (RNG). Kubonakala ngathi yonke into isisiseko, kodwa ukuba sisuka kwithiyori ukuya kuziqhelanisa, enyanisweni akulula kangako ukuphumeza i-algorithm yesoftware ukwenza ulandelelwano olunjalo.

Isizathu sikukuba akukho kwaloo mbhodamo kubathengi banamhlanje. Ngaphandle kwayo, amanani angaqhelekanga ayayeka ukubakho, kwaye ijeneretha yawo ijika ibe ngumsebenzi oqhelekileyo weengxoxo ezichazwe ngokucacileyo. Kwinani lezinto ezikhethekileyo kwintsimi ye-IT, oku kuyingxaki enkulu (umzekelo, i-cryptography), kodwa kwabanye kukho isisombululo esamkelekileyo ngokupheleleyo.

Kuyimfuneko ukuba ubhale i-algorithm eya kubuya, nangona ingekho amanani e-random ngokwenene, kodwa ngokusondeleyo kangangoko kunokwenzeka kubo - okubizwa ngokuba ngamanani angama-pseudo-random (PRN). I-algorithm kule meko ibizwa ngokuba yi-pseudorandom number generator (PRNG).

Kukho iindlela ezininzi onokukhetha kuzo ukwenza i-PRNG, kodwa oku kulandelayo kuya kufaneleka kuye wonke umntu:

  1. Imfuneko yokuqalisa kwangaphambili.

    I-PRNG ayinawo umthombo we-entropy, ngoko ke kufuneka inikwe imo yokuqala ngaphambi kokusetyenziswa. Ichazwa njengenani (okanye i-vector) kwaye ibizwa ngokuba yimbewu (imbewu engaqhelekanga). Rhoqo, ikhawuntara yewotshi yeprosesa okanye inani elilinganayo lexesha lenkqubo lisetyenziswa njengembewu.

  2. Ukulandelelanisa ukuveliswa kwakhona.

    I-PRNG ixhomekeke ngokupheleleyo, ngoko ke imbewu ekhankanyiweyo ngexesha lokuqalisa imisela ngokukodwa ulandelelwano lwamanani lwexesha elizayo. Oku kuthetha ukuba i-PRNG eyahlukileyo eqaliswe ngembewu efanayo (ngamaxesha ahlukeneyo, kwiinkqubo ezahlukeneyo, kwizixhobo ezahlukeneyo) iya kuvelisa ukulandelelana okufanayo.

Kufuneka kwakhona ukwazi unikezelo olunokwenzeka olubonakalisa i-PRNG - ngawaphi amanani aya kuvelisa kunye nokuba yintoni na. Amaxesha amaninzi oku kukwabiwa okuqhelekileyo okanye ukwabiwa okufanayo.
BlessRNG okanye ukujonga i-RNG ngobulungisa
Usasazo oluqhelekileyo (ekhohlo) kunye nokuhanjiswa okufanayo (ekunene)

Masithi sinokufa okufanelekileyo kunye namacala angama-24. Ukuba uyaliphosa, amathuba okufumana elinye ayakulingana no 1/24 (kufana namathuba okufumana naliphi na elinye inani). Ukuba wenza ukujula okuninzi kwaye urekhode iziphumo, uya kuqaphela ukuba yonke imiphetho iyawa malunga nokuphindaphinda okufanayo. Ngokusisiseko, oku kufa kunokuqwalaselwa njenge-RNG enokuhanjiswa okufanayo.

Kuthekani ukuba ujule i-10 kula dayisi ngexesha elinye kwaye ubale amanqaku ewonke? Ngaba kuya kugcinwa ukufana kwayo? Hayi. Amaxesha amaninzi, isixa siya kuba sisondele kumanqaku angama-125, oko kukuthi, kwixabiso elithile eliphakathi. Kwaye ngenxa yoko, nangaphambi kokuba wenze ukuphosa, unokuqikelela isiphumo sexesha elizayo.

Isizathu sesokuba kukho elona nani likhulu lendibaniselwano ukufumana amanqaku aphakathi. Ukude ukusuka kuyo, imidibaniso embalwa - kwaye, ngokufanelekileyo, isezantsi amathuba okulahleka. Ukuba le datha ibonakalisiwe, iya kufana ngokucacileyo nemilo yentsimbi. Ngoko ke, kunye nokwelula, inkqubo yeedayisi ezili-10 ingabizwa ngokuba yi-RNG kunye nokusabalalisa okuqhelekileyo.

Omnye umzekelo, ngeli xesha kuphela kwinqwelomoya - ukudubula kwindawo ekujoliswe kuyo. Umdubuli uya kuba yi-RNG eyenza amanani amabini (x, y) aboniswe kwigrafu.
BlessRNG okanye ukujonga i-RNG ngobulungisa
Vumelana ukuba inketho ekhohlo isondele kubomi bokwenyani - le yi-RNG enolwabiwo oluqhelekileyo. Kodwa ukuba ufuna ukusabalalisa iinkwenkwezi esibhakabhakeni esimnyama, ngoko ukhetho olufanelekileyo, olufunyenwe usebenzisa i-RNG kunye nokusabalalisa okufanayo, lufanelekile ngakumbi. Ngokubanzi, khetha i-generator ngokuxhomekeke kumsebenzi okhoyo.

Ngoku makhe sithethe nge-entropy yokulandelelana kwe-PNG. Umzekelo, kukho ulandelelwano oluqala ngolu hlobo:

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

Ingaba la manani ngokungakhethiyo xa uqala ukuwajonga? Masiqale ngokujonga ukuhanjiswa.
BlessRNG okanye ukujonga i-RNG ngobulungisa
Ijongeka isondele kwiyunifomu, kodwa ukuba ufunda ukulandelelana kwamanani amabini kwaye uwatolike njengolungelelwaniso kwinqwelomoya, ufumana oku:
BlessRNG okanye ukujonga i-RNG ngobulungisa
Iipateni zibonakala ngokucacileyo. Kwaye ekubeni idatha ngokulandelelana iyalwe ngendlela ethile (oko kukuthi, ine-entropy ephantsi), oku kunokunika ukuba "i-bias" kakhulu. Ubuncinci, i-PRNG enjalo ayifanelekanga kakhulu ukuvelisa ulungelelwaniso kwinqwelomoya.

Olunye ulandelelwano:

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

Yonke into ibonakala ilungile apha nakwinqwelomoya:
BlessRNG okanye ukujonga i-RNG ngobulungisa
Masijonge umthamo (funda amanani amathathu ngexesha):
BlessRNG okanye ukujonga i-RNG ngobulungisa
Kwaye kwakhona iipateni. Akusenakwenzeka ukwenza umfanekiso ngemilinganiselo emine. Kodwa iipateni zinokubakho kulo mlinganiso nakwimikhulu.

Kwi-cryptography, apho ezona mfuno zingqongqo zibekwe kwi-PRNGs, imeko enjalo ayamkelekanga ngokwahlukileyo. Ngoko ke, ii-algorithms ezikhethekileyo ziye zaphuhliswa ukuvavanya umgangatho wazo, esingayi kuchukumisa ngoku. Isihloko sibanzi kwaye sifanele inqaku elahlukileyo.

Ukuvavanywa

Ukuba asiyazi into ethile ngokuqinisekileyo, ngoko sisebenza njani nayo? Ngaba kufanelekile ukuwela indlela ukuba awuyazi ukuba yeyiphi na isibane esikuvumelayo? Imiphumo isenokwahluka.

Okufanayo kuya ku-randomness notorious ku-Unity. Kulungile ukuba amaxwebhu atyhila iinkcukacha eziyimfuneko, kodwa ibali elikhankanywe ekuqaleni kwenqaku lenzeke ngokuchanekileyo ngenxa yokungabikho kwezinto ezifunwayo.

Kwaye ukuba awukwazi ukuba isixhobo sisebenza njani, awuyi kukwazi ukusisebenzisa ngokuchanekileyo. Ngokubanzi, ixesha lifikile lokujonga kunye nokwenza umfuniselo ukuze ekugqibeleni uqiniseke malunga nokuhanjiswa.

Isisombululo sasilula kwaye sisebenza kakuhle - ukuqokelela izibalo, ukufumana idatha yenjongo kwaye ujonge iziphumo.

Umxholo wokufunda

Kukho iindlela ezininzi zokuvelisa amanani angaqhelekanga kuManyano- sivavanye ezintlanu.

  1. System.Random.Okulandelayo(). Yenza amanani apheleleyo kuluhlu olunikiweyo lwamaxabiso.
  2. System.Random.NextDouble(). Ivelisa amanani achanekileyo kabini kuluhlu ukusuka [0; 1).
  3. UnityEngine.Random.Range(). Yenza amanani achanekileyo (adadayo) kuluhlu olunikiweyo lwamaxabiso.
  4. I-UnityEngine.Random.value. Ivelisa amanani achanekileyo (adadayo) kuluhlu ukusuka ku- [0; 1).
  5. Ubunye.Mathematics.Random.NextFloat(). Inxalenye yethala leencwadi elitsha le-Unity.Mathematics. Yenza amanani achanekileyo (adadayo) kuluhlu olunikiweyo lwamaxabiso.

Phantse kuyo yonke indawo kuxwebhu unikezelo olufanayo luchaziwe, ngaphandle kweNjini yoBunye.Random.value (apho usasazo lwalungachazwanga, kodwa ngothelekiso neNjini yoBunye.Random.Range() iyunifomu nayo yayilindelwe) kunye neUnity.Mathematics.Random. .NextFloat() (apho kwisiseko yi xorshift algorithm, ethetha ukuba kwakhona kufuneka ulinde unikezelo olufanayo).

Ngokungagqibekanga, iziphumo ezilindelekileyo zithathwe njengezo zichazwe kumaxwebhu.

Indlela

Sibhale isicelo esincinci esenza ulandelelwano lwamanani angaqhelekanga kusetyenziswa indlela nganye enikezelweyo kwaye sagcina iziphumo zokuqhubela phambili.

Ubude bolandelelwano ngalunye ngamanani angama-100.
Uluhlu lwamanani angaqhelekanga [0, 100].

Idatha yaqokelelwa kumaqonga ekujoliswe kuwo amaninzi:

  • Windows
    — Umanyano v2018.3.14f1, imowudi yoMhleli, iMono, .NET Standard 2.0
  • Mac
    — Umanyano v2018.3.14f1, imowudi yoMhleli, iMono, .NET Standard 2.0
    — Umanyano v5.6.4p4, imowudi yoMhleli, iMono, .NET Standard 2.0
  • Android
    — Umanyano v2018.3.14f1, ukwakha isixhobo ngasinye, Mono, .NET Standard 2.0
  • iOS
    - Umanyano v2018.3.14f1, ukwakha ngesixhobo, il2cpp, .NET Standard 2.0

Ukuphunyezwa

Sineendlela ezininzi ezahlukeneyo zokuvelisa amanani angaqhelekanga. Ngamnye wabo, siya kubhala iklasi eyahlukileyo yokugoqa, ekufuneka ibonelele:

  1. Ukubanakho ukuseta uluhlu lwamaxabiso [min/max). Iza kusekwa ngokusebenzisa umakhi.
  2. Indlela yokubuyisela iMF. Masikhethe ukudada njengohlobo, njengoko iqhelekile.
  3. Igama lendlela yokuvelisa yokumakisha iziphumo. Ukuze kube lula, siya kubuyisela njengexabiso igama elipheleleyo leklasi + igama lendlela esetyenziselwa ukuvelisa iMF.

Okokuqala, makhe sibhengeze into ethathwayo eya kumelwa lujongano lwe-IRAndomGenerator:

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

        float Generate();
    }
}

Ukuphunyezwa kweSixokelelwano.Random.Okulandelayo()

Le ndlela ikuvumela ukuba usete uluhlu lwamaxabiso, kodwa ibuyisela inani elipheleleyo, kodwa izinto ezidadayo ziyafuneka. Unokutolika nje inani elipheleleyo njengento edadayo, okanye unokwandisa uluhlu lwamaxabiso ngeeodolo ezininzi zobukhulu, ubabuyekeze ngesizukulwana ngasinye semidrange. Isiphumo siya kuba yinto efana ne-fixed-point kunye nomyalelo onikiweyo wokuchaneka. Siza kusebenzisa olu khetho njengoko lukufutshane kwixabiso lokwenyani lokudada.

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

Ukuphunyezwa kweSixokelelwano.Random.NextDouble()

Apha uluhlu olumiselweyo lwamaxabiso [0; 1). Ukuyiprojektha kuleyo ichaziweyo kumakhi, sisebenzisa i-arithmetic elula: X * (ubuninzi − 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;
    }
}

Ukuphunyezwa kwe-UnityEngine.Random.Range()

Le ndlela ye-UnityEngine.Random iklasi engatshintshiyo ikuvumela ukuba usete uluhlu lwamaxabiso kwaye ubuyisele uhlobo lokudada. Akukho mfuneko yokuba wenze naluphi na utshintsho olongezelelweyo.

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

Ukuphunyezwa kwe-UnityEngine.Random.value

Ixabiso lepropathi yodidi lwe-static UnityEngine.Random ibuyisela udidi oludadayo olusuka kuluhlu olusisigxina lwamaxabiso[0; 1). Masiyiprojekthi kuluhlu olunikiweyo ngendlela efanayo naxa siphumeza 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;
    }
}

Ukuphunyezwa koManyano.Mathematics.Random.NextFloat()

I-NextFloat () indlela ye Unity.Mathematics.Random ibuyisela indawo edadayo yohlobo lokudada kwaye ikuvumela ukuba uchaze uluhlu lwamaxabiso. I-nuance kuphela kukuba isiganeko ngasinye se-Unity.Mathematics.Random kuya kufuneka iqalwe ngembewu ethile - ngale ndlela siya kuphepha ukuvelisa ulandelelwano oluphindaphindiweyo.

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

Ukuphunyezwa koMlawuli oyiNtloko

Ukuphunyezwa okuliqela kwe-IRandomGenerator sele ilungile. Okulandelayo, kufuneka uvelise ulandelelwano kwaye ugcine i-dataset enesiphumo sokuqhubekeka. Ukwenza oku, siya kudala indawo kunye neskripthi esincinci se-MainController kwi-Unity, eya kwenza wonke umsebenzi oyimfuneko kwaye ngexesha elifanayo libe noxanduva lokusebenzisana ne-UI.

Masisete ubungakanani bedatha kunye noluhlu lwamaxabiso eMF, kwaye sifumane nendlela ebuyisela uluhlu lweejeneretha ezimiselweyo kwaye zilungele 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)
            };
        }

        ...
    }
}

Ngoku makhe senze iseti yedatha. Kule meko, ukuveliswa kwedatha kuya kudibaniswa nokurekhoda iziphumo kwi-text stream (kwifomathi ye-csv). Ukugcina amaxabiso e-IRandomGenerator nganye, ikholamu yayo eyahlukileyo yabelwe, kwaye umgca wokuqala unegama 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();
            }
        }

        ...
    }
}

Konke okuseleyo kukufowunela indlela ye-GenerateCsvDataSet kwaye ugcine umphumo kwifayile, okanye udlulise ngokukhawuleza idatha kwinethiwekhi ukusuka kwisixhobo sokugqibela ukuya kwiseva yokufumana.

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 yeprojekthi iku GitLab.

Iziphumo

Akukho mmangaliso wenzekayo. Into ebebeyilindele yile nto bayifumanayo - kuzo zonke iimeko, ukusasazwa ngokulinganayo ngaphandle kokwenza iyelenqe. Andiyiboni ingongoma yokubeka iigrafu ezahlukeneyo zamaqonga - zonke zibonisa iziphumo ezifanayo.

Inyani yile:
BlessRNG okanye ukujonga i-RNG ngobulungisa

Ukubona ulandelelwano kwinqwelomoya kuzo zonke iindlela ezihlanu zesizukulwana:
BlessRNG okanye ukujonga i-RNG ngobulungisa

Kwaye umboniso kwi-3D. Ndizakushiya kuphela isiphumo se-System.Random.Next() ukuze ndingavelisi isiqulatho esifanayo.
BlessRNG okanye ukujonga i-RNG ngobulungisa

Ibali elixelwe kwintshayelelo malunga nokusabalalisa okuqhelekileyo kwe-UnityEngine.Random ayizange iphinde iphinde: mhlawumbi yayiyimpazamo ekuqaleni, okanye kukho into etshintshileyo kwi-injini. Kodwa ngoku siqinisekile.

umthombo: www.habr.com

Yongeza izimvo