BlessRNG oswa tcheke RNG pou jistis

BlessRNG oswa tcheke RNG pou jistis

Nan devlopman jwèt, ou souvan bezwen mare yon bagay ak owaza: Inite gen pwòp Random li yo pou sa a, ak nan paralèl ak li gen System.Random. Yon fwa sou youn nan pwojè yo, mwen te gen enpresyon ke tou de te kapab travay yon fason diferan (byenke yo ta dwe gen yon distribisyon menm).

Lè sa a, yo pa t 'antre nan detay - li te ase ke tranzisyon an nan System.Random korije tout pwoblèm yo. Koulye a, nou deside gade nan li an plis detay epi fè yon ti rechèch: ki jan "partialize" oswa previzib RNG yo, ak ki youn yo chwazi. Anplis, mwen te tande plis pase yon fwa opinyon konfli sou "onètete" yo - an n eseye konnen ki jan rezilta reyèl yo konpare ak sa yo deklare.

Pwogram edikasyon brèf oswa RNG se aktyèlman RNG

Si ou deja abitye ak dèlko nimewo o aza, Lè sa a, ou ka imedyatman sote nan seksyon "Tès".

Nimewo o aza (RN) se yon sekans nimewo ki pwodui lè l sèvi avèk kèk pwosesis o aza (chaotic), yon sous entropi. Sa vle di, sa a se yon sekans ki gen eleman yo pa entèkonekte pa okenn lwa matematik - yo pa gen okenn relasyon kòz ak efè.

Ki sa ki kreye nimewo o aza yo rele yon dèlko nimewo o aza (RNG). Li ta sanble ke tout bagay se elemantè, men si nou deplase soti nan teyori nan pratik, Lè sa a, an reyalite li pa tèlman senp aplike yon algorithm lojisyèl pou jenere yon sekans konsa.

Rezon ki fè la manti nan absans la nan menm dezòd sa a nan elektwonik konsomatè modèn. San li, nimewo o aza sispann yo dwe o aza, ak dèlko yo vire nan yon fonksyon òdinè nan agiman evidamman defini. Pou yon kantite espesyalite nan domèn IT, sa a se yon pwoblèm grav (pa egzanp, kriptografik), men pou lòt moun gen yon solisyon konplètman akseptab.

Li nesesè yo ekri yon algorithm ki ta retounen, byenke se pa nimewo vrèman o aza, men pi pre ke posib yo - sa yo rele nimewo pseudo-o aza (PRN). Algorithm la nan ka sa a rele yon dèlko nimewo pseudorandom (PRNG).

Gen plizyè opsyon pou kreye yon PRNG, men sa ki annapre yo pral enpòtan pou tout moun:

  1. Bezwen pou inisyalizasyon preliminè.

    PRNG a pa gen okenn sous entropi, kidonk li dwe bay yon premye eta anvan ou itilize. Li espesifye kòm yon nimewo (oswa vektè) epi yo rele yon grenn (grenn o aza). Souvan, kontwa revèy processeur a oswa ekivalan nimerik tan sistèm yo itilize kòm yon grenn.

  2. Repwodiksyon sekans.

    PRNG a se konplètman detèminist, kidonk grenn ki espesifye pandan inisyalizasyon inikman detèmine tout sekans nan fiti nan nimewo. Sa vle di ke yon PRNG separe inisyalize ak menm grenn (nan diferan moman, nan diferan pwogram, sou diferan aparèy) pral jenere menm sekans.

Ou bezwen tou konnen distribisyon pwobabilite ki karakterize PRNG a - ki nimewo li pral jenere ak ki pwobabilite. Pi souvan sa a se swa yon distribisyon nòmal oswa yon distribisyon inifòm.
BlessRNG oswa tcheke RNG pou jistis
Distribisyon nòmal (agòch) ak distribisyon inifòm (adwat)

Ann di nou gen yon mouri ki jis ak 24 kote. Si w lanse l, pwobabilite pou w jwenn yon sèl pral egal a 1/24 (menm ak pwobabilite pou w jwenn nenpòt lòt nimewo). Si ou fè anpil jete epi anrejistre rezilta yo, ou pral remake ke tout bor yo tonbe soti ak apeprè menm frekans lan. Esansyèlman, mouri sa a ka konsidere kòm yon RNG ak yon distribisyon inifòm.

E si ou jete 10 zo sa yo alafwa epi konte total pwen yo? Èske inifòmite ap kenbe pou li? Non. Pi souvan, kantite lajan an pral fèmen nan 125 pwen, se sa ki, nan kèk valè mwayèn. Epi kòm yon rezilta, menm anvan ou fè yon jete, ou ka apeprè estime rezilta nan lavni.

Rezon ki fè la se ke gen pi gwo kantite konbinezon yo jwenn nòt an mwayèn. Plis lwen li, mwens konbinezon yo - epi, kòmsadwa, pi ba pwobabilite pou yon pèt. Si done sa yo vizyalize, li pral vagman sanble ak fòm yon klòch. Se poutèt sa, ak kèk detire, yon sistèm nan 10 zo ka rele yon RNG ak yon distribisyon nòmal.

Yon lòt egzanp, sèlman fwa sa a sou yon avyon - tire nan yon sib. Tirè a pral yon RNG ki jenere yon pè nimewo (x, y) ki parèt sou graf la.
BlessRNG oswa tcheke RNG pou jistis
Dakò ke opsyon ki sou bò gòch la pi pre lavi reyèl - sa a se yon RNG ak yon distribisyon nòmal. Men, si ou bezwen gaye zetwal nan yon syèl nwa, Lè sa a, opsyon ki dwat, jwenn lè l sèvi avèk RNG ak yon distribisyon inifòm, pi byen adapte. An jeneral, chwazi yon dèlko depann sou travay la nan men yo.

Koulye a, ann pale sou entropi sekans PNG la. Pou egzanp, gen yon sekans ki kòmanse tankou sa a:

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

Kouman o aza nimewo sa yo nan premye gade? Ann kòmanse tcheke distribisyon an.
BlessRNG oswa tcheke RNG pou jistis
Li sanble pre inifòm, men si ou li yon sekans de nimewo epi entèprete yo kòm kowòdone sou yon avyon, ou jwenn sa a:
BlessRNG oswa tcheke RNG pou jistis
Modèl yo vin klèman vizib. Epi depi done yo nan sekans yo bay lòd nan yon sèten fason (ki se, li gen entropi ki ba), sa a ka bay monte nan "patipri" sa a. Nan yon minimòm, tankou yon PRNG pa trè apwopriye pou jenere kowòdone sou yon avyon.

Yon lòt sekans:

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

Tout bagay sanble byen isit la menm sou avyon an:
BlessRNG oswa tcheke RNG pou jistis
Ann gade nan volim (li twa nimewo nan yon moman):
BlessRNG oswa tcheke RNG pou jistis
Epi ankò modèl yo. Li pa posib ankò pou konstwi yon vizyalizasyon nan kat dimansyon. Men, modèl yo ka egziste sou dimansyon sa a ak sou dimansyon ki pi gwo.

Nan kriptografik, kote kondisyon ki pi sevè yo enpoze sou PRNGs, yon sitiyasyon konsa se kategorikman akseptab. Se poutèt sa, algoritm espesyal yo te devlope pou evalye bon jan kalite yo, ki nou pa pral manyen sou kounye a. Sijè a vaste e li merite yon atik separe.

Tès

Si nou pa konnen yon bagay pou asire w, Lè sa a, ki jan yo travay avèk li? Èske li vo travèse wout la si ou pa konnen ki limyè trafik pèmèt li? Konsekans yo ka diferan.

Menm bagay la tou ale pou owaza notwa nan Inite. Li bon si dokiman an revele detay ki nesesè yo, men istwa a mansyone nan kòmansman atik la te rive jisteman paske nan mank de spesifik yo vle.

Men, si ou pa konnen ki jan zouti a travay, ou pa yo pral kapab sèvi ak li kòrèkteman. An jeneral, lè a rive pou tcheke ak fè yon eksperyans pou finalman asire w omwen sou distribisyon an.

Solisyon an te senp epi efikas - kolekte estatistik, jwenn done objektif epi gade rezilta yo.

Sijè etid

Gen plizyè fason pou jenere nimewo o aza nan Unity - nou teste senk.

  1. System.Random.Next(). Jenere nonb antye relatif nan yon seri valè bay yo.
  2. System.Random.NextDouble (). Jenere nimewo presizyon doub nan seri a soti nan [0; 1).
  3. UnityEngine.Random.Range(). Jenere nimewo presizyon sèl (flote) nan yon seri valè bay yo.
  4. UnityEngine.Random.value. Jenere nimewo presizyon sèl (flote) nan seri a soti nan [0; 1).
  5. Unity.Mathematics.Random.NextFloat(). Yon pati nan nouvo bibliyotèk Unity.Mathematics. Jenere nimewo presizyon sèl (flote) nan yon seri valè bay yo.

Prèske tout kote nan dokiman an te espesifye yon distribisyon inifòm, ak eksepsyon de UnityEngine.Random.value (kote distribisyon an pa te espesifye, men pa analoji ak UnityEngine.Random.Range() inifòm tou te espere) ak Unity.Mathematics.Random. .NextFloat() (kote nan baz la se algorithm nan xorshift, ki vle di ke ankò ou bezwen rete tann pou yon distribisyon inifòm).

Pa default, rezilta yo te espere yo te pran kòm sa yo espesifye nan dokiman an.

Metodoloji

Nou te ekri yon ti aplikasyon ki te pwodwi sekans nimewo o aza lè l sèvi avèk chak nan metòd prezante yo epi sove rezilta yo pou plis pwosesis.

Longè chak sekans se 100 chif.
Ranje nonm o aza se [0, 100).

Done yo te kolekte nan plizyè platfòm sib:

  • Windows
    — Unity v2018.3.14f1, Editè mòd, Mono, .NET Standard 2.0
  • MacOS
    — Unity v2018.3.14f1, Editè mòd, Mono, .NET Standard 2.0
    — Unity v5.6.4p4, Editè mòd, Mono, .NET Standard 2.0
  • android
    — Unity v2018.3.14f1, bati pou chak aparèy, Mono, .NET Standard 2.0
  • yo
    — Unity v2018.3.14f1, bati pou chak aparèy, il2cpp, .NET Standard 2.0

Aplikasyon

Nou gen plizyè fason diferan pou jenere nimewo o aza. Pou chak nan yo, nou pral ekri yon klas wrapper separe, ki ta dwe bay:

  1. Posibilite yo mete seri a nan valè [min / max). Yo pral mete atravè konstrukteur la.
  2. Metòd retounen MF. Ann chwazi flote kòm kalite a, kòm li se pi jeneral.
  3. Non metòd jenerasyon an pou make rezilta yo. Pou konvenyans, nou pral retounen kòm yon valè non konplè klas la + non metòd yo itilize pou jenere MF la.

Premyèman, ann deklare yon abstraksyon ki pral reprezante pa koòdone IRandomGenerator:

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

        float Generate();
    }
}

Aplikasyon System.Random.Next ()

Metòd sa a pèmèt ou mete yon seri valè, men li retounen nonb antye relatif, men yo bezwen flote. Ou ka senpleman entèprete nonb antye relatif kòm yon flote, oswa ou ka elaji seri a nan valè pa plizyè lòd nan grandè, konpanse yo ak chak jenerasyon nan mitan an. Rezilta a pral yon bagay tankou yon pwen fiks ak yon lòd bay presizyon. Nou pral sèvi ak opsyon sa a paske li se pi pre valè reyèl la flote.

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

Aplikasyon System.Random.NextDouble ()

Isit la seri a fiks nan valè [0; 1). Pou pwojte li sou youn ki espesifye nan konstrukteur a, nou itilize senp aritmetik: 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;
    }
}

Aplikasyon UnityEngine.Random.Range()

Metòd sa a nan klas la UnityEngine.Random estatik pèmèt ou mete yon seri de valè epi retounen yon kalite flote. Ou pa bezwen fè okenn transfòmasyon adisyonèl.

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

Aplikasyon UnityEngine.Random.value

Pwopriyete valè a nan klas estatik UnityEngine.Random retounen yon kalite flote soti nan yon seri fiks de valè [0; 1). Ann projet li sou yon seri bay menm jan ak lè nou aplike 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;
    }
}

Aplikasyon Unity.Mathematics.Random.NextFloat()

Metòd NextFloat() klas Unity.Mathematics.Random la retounen yon pwen k ap flote nan kalite flote epi li pèmèt ou presize yon seri valè. Sèl nuans la se ke chak egzanp nan Unity.Mathematics.Random pral dwe inisyalize ak kèk grenn - fason sa a nou pral evite jenere sekans repete.

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

Aplikasyon MainController

Plizyè aplikasyon IRandomGenerator pare. Apre sa, ou bezwen jenere sekans epi sove dataset ki kapab lakòz pou trete. Pou fè sa, nou pral kreye yon sèn ak yon ti MainController script nan Inite, ki pral fè tout travay ki nesesè yo epi an menm tan an responsab pou entèraksyon ak UI a.

Ann mete gwosè a nan seri done a ak seri a nan valè MF, epi tou jwenn yon metòd ki retounen yon etalaj de dèlko configuré ak pare pou travay.

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

        ...
    }
}

Koulye a, ann kreye yon seri done. Nan ka sa a, jenerasyon done yo pral konbine avèk anrejistreman rezilta yo nan yon kouran tèks (nan fòma csv). Pou estoke valè chak IRandomGenerator, yo bay pwòp kolòn separe li yo, epi premye liy lan gen Non dèlko a.

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

        ...
    }
}

Tout sa ki rete se rele metòd GenerateCsvDataSet epi sove rezilta a nan yon dosye, oswa imedyatman transfere done yo sou rezo a soti nan aparèy la fen nan sèvè k ap resevwa a.

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

        ...
    }
}

Sous pwojè yo se nan GitLab.

Jwenn

Pa gen mirak ki te rive. Sa yo te espere se sa yo te resevwa - nan tout ka, yon distribisyon menm san yon allusion nan konspirasyon. Mwen pa wè pwen nan mete graf separe pou platfòm - yo tout montre apeprè menm rezilta yo.

Reyalite a se:
BlessRNG oswa tcheke RNG pou jistis

Vizyalizasyon sekans sou yon avyon nan tout senk metòd jenerasyon:
BlessRNG oswa tcheke RNG pou jistis

Ak vizyalizasyon nan 3D. Mwen pral kite sèlman rezilta System.Random.Next () pou yo pa pwodwi yon pakèt kontni ki idantik.
BlessRNG oswa tcheke RNG pou jistis

Istwa a te di nan entwodiksyon an sou distribisyon nòmal nan UnityEngine.Random pa t 'repete tèt li: swa li te okòmansman inègza, oswa depi yon bagay te chanje nan motè a. Men kounye a nou sèten.

Sous: www.habr.com

Add nouvo kòmantè