BlessRNG na manamarina ny RNG ho an'ny rariny

BlessRNG na manamarina ny RNG ho an'ny rariny

Amin'ny fampivoarana lalao dia matetika mila mamatotra zavatra amin'ny kisendrasendra ianao: manana ny Random azy manokana ny Unity, ary miaraka amin'izany dia misy System.Random. Indray mandeha, tamin'ny tetikasa iray, nahazo ny fahatsapana aho fa samy afaka miasa amin'ny fomba hafa (na dia tokony hanana fizarana mitovy aza izy ireo).

Avy eo dia tsy niditra tamin'ny antsipiriany izy ireo - ampy fa ny fifindrana mankany amin'ny System.Random dia nanitsy ny olana rehetra. Ankehitriny dia nanapa-kevitra ny hijery azy io amin'ny antsipiriany bebe kokoa izahay ary hanao fikarohana kely: ahoana ny RNGs "miangatra" na azo vinavinaina, ary iza no hofidiana. Ankoatr'izay, imbetsaka aho no naheno hevitra mifanohitra momba ny "fahamarinan'izy ireo" - andeha hojerentsika hoe ahoana no ampitahaina amin'ny vokatra tena izy amin'ireo nambara.

Ny programa fanabeazana fohy na RNG dia RNG

Raha efa zatra amin'ny mpamokatra nomerao kisendrasendra ianao dia afaka mitsambikina avy hatrany any amin'ny fizarana "Fitsapana".

Ny isa kisendrasendra (RN) dia filaharan'ny isa novokarina tamin'ny alalan'ny dingana kisendrasendra (korontana), loharanon'ny entropy. Izany hoe, filaharan'ireo singa tsy mifandray amin'ny lalàna matematika - tsy misy ifandraisany amin'ny antony sy ny vokany.

Ny mamorona ny isa kisendrasendra dia antsoina hoe mpamokatra nomerao kisendrasendra (RNG). Toa tsotra ny zava-drehetra, fa raha mifindra amin'ny teoria mankany amin'ny fampiharana isika, raha ny marina dia tsy dia tsotra loatra ny fampiharana algorithm algorithm amin'ny famoronana filaharana toy izany.

Ny antony dia ny tsy fisian'ny korontana mitovy amin'ny elektronika mpanjifa maoderina. Raha tsy misy izany, dia mijanona ho kisendrasendra ny isa kisendrasendra, ary ny mpamokatra azy dia mivadika ho asa mahazatra amin'ny tohan-kevitra voafaritra mazava tsara. Ho an'ny manam-pahaizana maromaro amin'ny sehatry ny IT dia olana lehibe izany (ohatra, cryptography), fa ho an'ny hafa dia misy vahaolana azo ekena tanteraka.

Ilaina ny manoratra algorithm izay hiverina, na dia tsy isa tena kisendrasendra aza, fa araka izay azo atao amin'izy ireo - ilay antsoina hoe isa pseudo-random (PRN). Ny algorithm amin'ity tranga ity dia antsoina hoe pseudorandom number generator (PRNG).

Misy safidy maromaro amin'ny famoronana PRNG, fa ireto manaraka ireto dia mety ho an'ny rehetra:

  1. Ilaina ny fanombohana mialoha.

    Ny PRNG dia tsy manana loharanon'ny entropy, noho izany dia tsy maintsy omena fanjakana voalohany alohan'ny hampiasana azy. Voatondro ho isa (na véctor) izy io ary antsoina hoe voa (voa kisendrasendra). Matetika, ny kaontera famantaranandro processeur na ny isa mitovy amin'ny fotoanan'ny rafitra dia ampiasaina ho voa.

  2. Reproducibility sequence.

    Ny PRNG dia voafaritra tanteraka, ka ny voa voatondro mandritra ny fanombohana dia mamaritra manokana ny filaharan'ny isa ho avy. Midika izany fa ny PRNG misaraka natomboka tamin'ny voa iray ihany (amin'ny fotoana samy hafa, amin'ny programa samihafa, amin'ny fitaovana samihafa) dia hiteraka filaharana mitovy.

Ilainao koa ny mahafantatra ny fitsinjarana ny mety ho famantarana ny PRNG - isa inona no havoakany ary inona no mety. Matetika izany dia fizarana ara-dalàna na fizarana fanamiana.
BlessRNG na manamarina ny RNG ho an'ny rariny
Fizarana mahazatra (ankavia) sy fizarana fanamiana (ankavanana)

Andeha hatao hoe manana fatiantoka ara-drariny misy lafiny 24 isika. Raha atsipy ianao dia mitovy amin'ny 1/24 (mitovy amin'ny mety hahazoana isa hafa) ny mety hahazoana iray. Raha manao tifitra maro ianao ary raketinao ny valiny, dia ho hitanao fa milatsaka mitovy ny matetika ny sisiny rehetra. Amin'ny ankapobeny, ity maty ity dia azo raisina ho RNG misy fizarana fanamiana.

Ahoana raha manipy 10 amin'ireo dice ireo indray mandeha ianao ary manisa ny totalin'ny isa? Ho tazonina ve ny fitoniana amin’izany? Tsia. Matetika indrindra, ny vola dia ho akaiky ny 125 isa, izany hoe, ny sasany eo ho eo ny sandany. Ary vokatr'izany, na dia alohan'ny hanaovana tifitra aza, dia azonao atao ny manombatombana ny vokatra ho avy.

Ny antony dia ny fisian'ny fitambarana be indrindra hahazoana ny isa antonony. Arakaraka ny lavitry izany, ny tsikombakomba vitsy kokoa - ary, araka izany, ny ambany ny mety hisian'ny fatiantoka. Raha aseho an-tsary ity angona ity dia hitovy amin'ny endriky ny lakolosy. Noho izany, miaraka amin'ny fanitarana kely, ny rafitra misy dice 10 dia azo antsoina hoe RNG misy fizarana ara-dalàna.

Ohatra iray hafa, tamin'ity indray mitoraka ity tamin'ny fiaramanidina - nitifitra lasibatra. Ny tifitra dia RNG izay miteraka isa roa (x, y) izay aseho amin'ny grafika.
BlessRNG na manamarina ny RNG ho an'ny rariny
Ekeo fa ny safidy eo amin'ny ankavia dia akaiky kokoa ny tena fiainana - izany dia RNG misy fizarana ara-dalàna. Fa raha mila manaparitaka kintana amin'ny lanitra maizina ianao, dia mety kokoa ny safidy mety, azo amin'ny fampiasana RNG miaraka amin'ny fizarana fanamiana. Amin'ny ankapobeny, mifidiana gropy iray arakaraka ny asa atao.

Andeha isika hiresaka momba ny entropy amin'ny filaharana PNG. Ohatra, misy filaharana manomboka toy izao:

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

Ahoana no kisendrasendra ireo isa ireo raha vao jerena? Andeha isika hanomboka amin'ny fanamarinana ny fizarana.
BlessRNG na manamarina ny RNG ho an'ny rariny
Toa manakaiky ny fanamiana izy io, fa raha mamaky andiana isa roa ianao ary mandika azy ireo ho koordinate amin'ny fiaramanidina dia azonao izao:
BlessRNG na manamarina ny RNG ho an'ny rariny
Lasa hita mazava tsara ny lamina. Ary satria ny angon-drakitra ao amin'ny filaharana dia voalahatra amin'ny fomba iray (izany hoe, manana entropy ambany izy), dia mety hiteraka izany "fitongilanana" izany. Farafaharatsiny, ny PRNG toy izany dia tsy mety amin'ny famoronana koordinate amin'ny fiaramanidina.

Fitohizana hafa:

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

Toa milamina ny zava-drehetra eto na dia ao anaty fiaramanidina aza:
BlessRNG na manamarina ny RNG ho an'ny rariny
Andeha hojerentsika ny boky (vakio isa telo isaky ny mandeha):
BlessRNG na manamarina ny RNG ho an'ny rariny
Ary indray ny lamina. Tsy azo atao intsony ny manamboatra sary amin'ny lafiny efatra. Saingy mety hisy lamina amin'ity refy ity sy amin'ny lehibe kokoa.

Amin'ny kriptografika, izay ametrahana ny fepetra hentitra indrindra amin'ny PRNG, ny toe-javatra toy izany dia tsy azo ekena. Noho izany, ny algorithm manokana dia novolavolaina mba hanombanana ny kalitaony, izay tsy hokasihintsika ankehitriny. Ny lohahevitra dia midadasika ary mendrika ny lahatsoratra manokana.

fitiliana

Raha tsy mahafantatra zavatra azo antoka isika, dia ahoana no fomba hiarahana aminy? Mendrika ny hiampitana ny arabe ve raha tsy fantatrao izay jiron'ny fifamoivoizana mamela azy? Mety tsy hitovy ny vokany.

Torak'izany koa ny kisendrasendra malaza ao amin'ny Unity. Tsara raha manambara ny antsipiriany ilaina ny antontan-taratasy, fa ny tantara voalaza teo am-piandohan'ny lahatsoratra dia nitranga marina noho ny tsy fahampian'ny antsipiriany irina.

Ary raha tsy fantatrao ny fomba fiasan'ilay fitaovana, dia tsy ho afaka hampiasa azy tsara ianao. Amin'ny ankapobeny, tonga ny fotoana hijerena sy hanaovana andrana mba hahazoana antoka farafaharatsiny momba ny fizarana.

Tsotra sy nahomby ny vahaolana - manangona antontan'isa, mahazo angona tanjona ary jereo ny valiny.

Lohahevitra fianarana

Misy fomba maro hamoronana isa kisendrasendra ao amin'ny Unity - nanandrana dimy izahay.

  1. System.Random.Next(). Mamorona isa amin'ny sanda nomena.
  2. System.Random.NextDouble(). Mamokatra isa avo roa heny ao anatin'ny salan'isa [0; 1).
  3. UnityEngine.Random.Range(). Mamorona isa tokana tokana (mitsingevana) amin'ny sanda nomena.
  4. UnityEngine.Random.value. Mamokatra isa tokana (mitsingevana) amin'ny salan'isa manomboka amin'ny [0; 1).
  5. Unity.Mathematics.Random.NextFloat(). Anisan'ny tranomboky vaovao Unity.Mathematics. Mamorona isa tokana tokana (mitsingevana) amin'ny sanda nomena.

Saika na aiza na aiza ao amin'ny antontan-taratasy dia misy fizarana fanamiana voafaritra, afa-tsy ny UnityEngine.Random.value (izay tsy voafaritra ny fizarana, fa raha oharina amin'ny UnityEngine.Random.Range() fanamiana ihany koa no andrasana) sy Unity.Mathematics.Random .NextFloat() (izay ao amin'ny The base dia ny xorshift algorithm, izay midika fa mila miandry fizarana fanamiana indray ianao).

Amin'ny alàlan'ny default, ny vokatra andrasana dia noraisina araka ny voalaza ao amin'ny antontan-taratasy.

teknika

Nanoratra fampiharana kely izahay izay niteraka filaharan'ny isa kisendrasendra amin'ny fampiasana ny fomba rehetra naseho ary nitahiry ny valiny ho an'ny fanodinana bebe kokoa.

Ny halavan'ny filaharana tsirairay dia isa 100.
Ny isan'ny isa kisendrasendra dia [0, 100).

Nangonina avy amin'ny sehatra kendrena maromaro ny angona:

  • Windows
    — Unity v2018.3.14f1, maody tonian-dahatsoratra, Mono, .NET Standard 2.0
  • macOS
    — Unity v2018.3.14f1, maody tonian-dahatsoratra, Mono, .NET Standard 2.0
    — Firaisankina v5.6.4p4, maody tonian-dahatsoratra, Mono, .NET Standard 2.0
  • Android
    — Unity v2018.3.14f1, manorina isaky ny fitaovana, Mono, .NET Standard 2.0
  • iOS
    — Unity v2018.3.14f1, manorina isaky ny fitaovana, il2cpp, .NET Standard 2.0

fanatanterahana

Manana fomba maro samihafa hamokarana isa kisendrasendra izahay. Ho an'ny tsirairay amin'izy ireo, dia hanoratra kilasy wrapper misaraka isika, izay tokony hanome:

  1. Azo atao ny mametraka ny isan'ny soatoavina [min/max). Hapetraka amin'ny alalan'ny constructor.
  2. Fomba famerenana MF. Andao hisafidy mitsingevana ho karazana, satria ankapobeny kokoa.
  3. Ny anaran'ny fomba famokarana hanamarihana ny vokatra. Ho an'ny fanamorana, dia haverintsika ho sanda ny anarana fenon'ny kilasy + ny anaran'ny fomba ampiasaina hamokarana ny MF.

Voalohany, andao hanambara abstraction izay asehon'ny interface IRandomGenerator:

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

        float Generate();
    }
}

Fampiharana ny System.Random.Next()

Ity fomba ity dia ahafahanao mametraka sanda isan-karazany, saingy mamerina integer, fa ilaina ny mitsingevana. Azonao atao ny mandika tsotra izao ny integer ho toy ny mitsingevana, na azonao atao ny manitatra ny isan'ny soatoavina amin'ny alàlan'ny baiko maromaro, manonitra azy ireo isaky ny taranaka midrange. Ny vokatra dia ho toy ny teboka raikitra miaraka amin'ny filaharan'ny marina. Hampiasa ity safidy ity izahay satria akaiky kokoa ny sandan'ny float tena izy.

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

Fampiharana ny System.Random.NextDouble()

Eto ny sanda raikitra [0; 1). Mba hamolavola azy amin'ny iray voatondro ao amin'ny constructor dia mampiasa arithmetika tsotra izahay: X * (max − 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;
    }
}

Fampiharana ny UnityEngine.Random.Range()

Ity fomba fiasa UnityEngine.Random static ity dia ahafahanao mametraka sanda maromaro ary mamerina karazana mitsingevana. Tsy mila manao fanovana fanampiny ianao.

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

Fampiharana ny UnityEngine.Random.value

Ny fananana sanda an'ny kilasy static UnityEngine.Random dia mamerina karazana mitsingevana avy amin'ny sanda raikitra [0; 1). Andeha hojerentsika amin'ny sehatra iray mitovy amin'ny fampiharana 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;
    }
}

Fampiharana ny Unity.Mathematics.Random.NextFloat()

Ny fomba NextFloat() an'ny kilasy Unity.Mathematics.Random dia mamerina teboka mitsingevana karazana mitsingevana ary ahafahanao mamaritra sanda maromaro. Ny hany tokana dia ny hoe isaky ny tranga tsirairay ao amin'ny Unity.Mathematics.Random dia tsy maintsy atomboka amin'ny voa sasany - amin'izany fomba izany dia hisoroka ny famokarana filaharana miverimberina.

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

Fampiharana ny MainController

Efa vonona ny fampiharana maromaro an'ny IRandomGenerator. Manaraka, mila mamorona filaharana ianao ary mitahiry ny angon-drakitra ho an'ny fanodinana. Mba hanaovana izany dia hamorona sehatra sy script MainController kely ao amin'ny Unity isika, izay hanao ny asa rehetra ilaina ary miaraka amin'izay koa, tompon'andraikitra amin'ny fifandraisana amin'ny UI.

Andao apetraka ny haben'ny angon-drakitra sy ny sandan'ny MF, ary alao ihany koa ny fomba iray mamerina ireo mpamokatra mpamokatra efa namboarina sy vonona hiasa.

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

        ...
    }
}

Andeha isika hamorona angon-drakitra. Amin'ity tranga ity, ny famokarana angona dia hatambatra amin'ny firaketana ny valiny ao anaty rindran-tsoratra (amin'ny endrika csv). Mba hitahiry ny soatoavin'ny IRandomGenerator tsirairay dia atokana ny tsanganany manokana, ary ny andalana voalohany dia misy ny Anaran'ny mpamokatra.

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

        ...
    }
}

Ny hany sisa tavela dia ny miantso ny fomba GenerateCsvDataSet ary mitahiry ny valiny amin'ny rakitra, na mamindra avy hatrany ny angona amin'ny tambajotra avy amin'ny fitaovana farany mankany amin'ny mpizara mpandray.

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

        ...
    }
}

Ny loharanon'ny tetikasa dia ao amin'ny GitLab.

vokatra

Tsy nisy fahagagana nitranga. Ny zavatra nandrasan'izy ireo dia izay azony - amin'ny tranga rehetra, fizarana mitovy tsy misy tsikombakomba. Tsy hitako ny teboka amin'ny fametrahana grafika misaraka ho an'ny sehatra - mitovy avokoa ny valiny.

Ny zava-misy dia izao:
BlessRNG na manamarina ny RNG ho an'ny rariny

Famaritana ny filaharana amin'ny fiaramanidina avy amin'ireo fomba dimy taranaka rehetra:
BlessRNG na manamarina ny RNG ho an'ny rariny

Ary visualization amin'ny 3D. Ny vokatry ny System.Random.Next() ihany no avelako mba tsy hamokatra votoaty mitovy.
BlessRNG na manamarina ny RNG ho an'ny rariny

Ny tantara voalaza ao amin'ny fampidirana momba ny fizarana ara-dalàna ny UnityEngine.Random dia tsy niverimberina: na diso tamin'ny voalohany, na nisy zavatra niova tao amin'ny motera. Azo antoka anefa izao.

Source: www.habr.com

Add a comment