BlessRNG te tirotiro ranei i te RNG mo te tika

BlessRNG te tirotiro ranei i te RNG mo te tika

I roto i te whakawhanaketanga o te keemu, he maha nga wa e hiahia ana koe ki te here i tetahi mea me te matapōkeretia: Kei a Unity tana ake Random mo tenei, me te rite ki a ia ko te System.Random. I tetahi wa, i runga i tetahi o nga kaupapa, i puta te whakaaro he rereke nga mahi e rua (ahakoa kia rite te tohatoha).

Na kaore i uru ki nga korero - he nui noa na te whakawhiti ki te System.Random i whakatika nga raru katoa. Inaianei kua whakatauhia e maatau ki te tirotiro i nga korero me te whakahaere rangahau iti: he pehea te "whakapae" me nga RNG e matapaehia ana, a ko tehea te mea hei whiriwhiri. I tua atu, neke atu i te kotahi nga wa kua rongo au i nga whakaaro tautohetohe mo o raatau "pono" - me ngana ki te whakaaro me pehea te whakataurite o nga hua pono ki nga mea kua whakahuahia.

Ko te kaupapa ako poto, ko te RNG ranei he RNG

Mena kua mohio koe ki nga kaihanga tau matapōkere, ka taea e koe te peke ki te waahanga "Whakamatau".

Ko nga tau matapōkere (RN) he raupapa tau i hangaia ma te whakamahi i etahi tukanga matapōkere (hepohepo), he puna o te entropy. Arā, he raupapa tenei karekau ona huānga e hono tahi e tetahi ture pangarau - karekau he hononga take-a-paanga.

Ko te mea ka hangaia te tau matapōkere ka kīia he kaihanga tau matapōkere (RNG). Te ahua nei he mea timatanga noa nga mea katoa, engari mena ka neke tatou mai i te ariā ki te mahi, he pono ehara i te mea ngawari ki te whakatinana i tetahi raupaparorohiko rorohiko hei whakaputa i taua raupapa.

Ko te take kei te kore o taua hepohepo i roto i nga hikohiko kaihoko hou. Ki te kore tenei, ka mutu te noho matapōkere o nga tau matapōkere, ka huri to ratou kaihanga ki te mahi noa o nga tohenga marama kua tautuhia. Mo te maha o nga tohungatanga i roto i te mara IT, he raruraru nui tenei (hei tauira, te tuhi tuhi), engari mo etahi atu he otinga tino pai.

E tika ana kia tuhia he algorithm ka hoki mai, ahakoa ehara i nga tau matapōkere, engari kia tata ki a raatau - ko nga nama pseudo-tupurangi (PRN) e kiia nei. Ko te algorithm i tenei keehi ka kiia ko te kaihanga tau pseudorandom (PRNG).

He maha nga whiringa mo te hanga PRNG, engari ko nga mea e whai ake nei ka tika mo te katoa:

  1. Ko te hiahia mo te arataki tuatahi.

    Karekau he puna o te entropy o te PRNG, no reira me hoatu he ahua tuatahi i mua i te whakamahi. Ka tohua hei tau (he vector ranei) ka kiia he kakano (kakano tupurangi). I te nuinga o te wa, ka whakamahia te karaka karaka, te taurite tau o te wa punaha hei kakano.

  2. Reproducibility raupapa.

    Ko te PRNG he tino whakatau, no reira ko te kakano i tohua i te wa o te aratakitanga ka whakatau i te raupapa katoa o nga tau kei te heke mai. Ko te tikanga ko te PRNG motuhake i arawhiti me te kakano kotahi (i nga wa rereke, i nga kaupapa rereke, i runga i nga taputapu rereke) ka whakaputa i te raupapa kotahi.

Me mohio ano koe ki te tuari tūponotanga e tohu ana i te PRNG - he aha nga tau ka puta, he aha te tupono. Ko te nuinga o nga wa he tohatoha noa, he tohatoha rite ranei.
BlessRNG te tirotiro ranei i te RNG mo te tika
Te tohatoha noa (maui) me te tohatoha rite (matau)

Me kii he mate tika me nga taha e 24. Mēnā ka whiua e koe, ko te tūponotanga ka whiwhi i te kotahi ka rite ki te 1/24 (he rite tonu ki te tūponotanga ka whiwhi i tetahi atu tau). Mena ka mahia e koe he maha o nga whiu me te tuhi i nga hua, ka kite koe ka taka katoa nga tapa ki waho he rite tonu te auau. Ko te tikanga, ka kiia tenei mate he RNG me te tohatoha rite.

Ka pewhea mehemea ka maka e koe kia 10 o enei mataono i te wa kotahi ka tatauhia nga piro katoa? Ka mau tonu te rite mo taua mea? Kao. Ko te nuinga o nga wa, ka tata te moni ki te 125 nga tohu, ara, ki etahi uara toharite. Ko te mutunga mai, ahakoa i mua i te maka, ka taea e koe te whakatau tata i te hua a meake nei.

Ko te take he maha nga huinga huinga hei whiwhi i te kaute toharite. Ko te tawhiti atu, ka iti ake nga huinga - a, na reira, ka iti ake te tupono o te mate. Mena ka tirohia enei raraunga, ka rite ki te ahua o te pere. Na reira, me etahi totoro, ka taea te kiia he punaha 10 mataono he RNG me te tohatoha noa.

Ko tetahi atu tauira, ko tenei wa anake i runga i te waka rererangi - te pupuhi ki te whainga. Ko te kaikopere he RNG ka whakaputa i nga tau takirua (x, y) ka whakaatuhia ki te kauwhata.
BlessRNG te tirotiro ranei i te RNG mo te tika
Whakaae ko te kowhiringa kei te taha maui he tata ki te ora tonu - he RNG tenei me te tohatoha noa. Engari ki te hiahia koe ki te marara whetu i roto i te rangi pouri, ka pai ake te kowhiringa tika, ka whiwhi ma te whakamahi i te RNG me te tohatoha rite. I te nuinga o te waa, kowhiria he miihini i runga i te mahi kei a koe.

Inaianei me korero mo te entropy o te raupapa PNG. Hei tauira, he raupapa ka timata penei:

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

He pehea te matapōkere o enei tau i te titiro tuatahi? Me timata ma te tirotiro i te tohatoha.
BlessRNG te tirotiro ranei i te RNG mo te tika
He tata ki te kakahu, engari ki te panui koe i te raupapa o nga tau e rua ka whakamaoritia hei taunga i runga i te rererangi, ka whiwhi koe i tenei:
BlessRNG te tirotiro ranei i te RNG mo te tika
Ka tino kitea nga tauira. A, i te mea ko nga raraunga i roto i te raupapa kua whakatauhia i runga i tetahi huarahi (ara, he iti te entropy), ka puta tenei ki te "bias". I te iti rawa, ko taua PRNG kaore e tino pai mo te whakaputa i nga taunga i runga i te rererangi.

Tetahi atu raupapa:

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

He pai nga mea katoa i konei ahakoa i runga i te waka rererangi:
BlessRNG te tirotiro ranei i te RNG mo te tika
Me titiro ki te rōrahi (pānui e toru ngā tau i te wā kotahi):
BlessRNG te tirotiro ranei i te RNG mo te tika
Na ano nga tauira. Kua kore e taea te hanga whakakitenga ki nga taha e wha. Engari ka noho pea nga tauira i runga i tenei waahanga me nga mea nui ake.

I roto i te tuhinga tuhi, kei te utaina nga whakaritenga tino kaha ki runga i nga PRNG, kaore e taea te ahua o taua ahuatanga. Na reira, kua whakawhanakehia nga algorithms motuhake hei aromatawai i to raatau kounga, kaore e pa atu ki a maatau inaianei. He whanui te kaupapa me te tika kia whai tuhinga motuhake.

Te whakamātautau

Ki te kore tatou e tino mohio ki tetahi mea, me pehea e mahi ai? He pai te whakawhiti i te huarahi ki te kore koe e mohio ko tehea rama rama ka whakaaetia? He rereke pea nga hua.

He pera ano mo te ohorere rongonui i roto i te Unity. He pai mena ka whakaatuhia e nga tuhinga nga korero e tika ana, engari ko te korero i whakahuahia i te timatanga o te tuhinga i puta tika na te kore o nga waahanga e hiahiatia ana.

A, ki te kore koe e mohio ki te mahi o te taputapu, kaore e taea e koe te whakamahi tika. I te nuinga o te waa, kua tae ki te wa ki te tirotiro me te whakahaere i tetahi whakamatautau kia tino mohio mo te tohatoha.

He ngawari, he whai hua te otinga - kohia nga tatauranga, whiwhi raraunga whainga me te titiro ki nga hua.

Kaupapa ako

He maha nga huarahi ki te whakaputa tau matapōkere i roto i te Unity - i whakamatauria e matou e rima.

  1. Pūnaha.Random.Next(). Ka whakaputa tauoti i roto i te whānuitanga o nga uara.
  2. Pūnaha.Random.NextDouble(). Ka whakaputa i nga tau tika rua i te awhe mai i te [0; 1).
  3. UnityEngine.Random.Range(). Ka whakaputa i nga tau tika kotahi (maangi) i roto i te whānuitanga o nga uara.
  4. UnityEngine.Random.value. Ka whakaputa i nga tau tika kotahi (maangi) i te awhe mai i te [0; 1).
  5. Unity.Mathematics.Random.NextFloat(). He wahanga o te whare pukapuka Unity.Pangarau hou. Ka whakaputa i nga tau tika kotahi (maangi) i roto i te whānuitanga o nga uara.

Tata ki nga waahi katoa i roto i nga tuhinga i tohua he tohatoha taurite, haunga te UnityEngine.Random.value (ki te kore i tohua te tohatoha, engari ma te whakataurite me te UnityEngine.Random.Range() i tumanakohia te kakahu) me te Unity.Mathematics.Random .NextFloat() (kei reira ko te kaupapa ko te xorshift algorithm, ko te tikanga me tatari ano koe mo te tohatoha rite).

Ma te taunoa, ko nga hua e tumanakohia ana i tangohia kia rite ki era i tohua i roto i nga tuhinga.

Tikanga

I tuhia e matou he tono iti i hanga raupapa o nga tau matapōkere ma te whakamahi i ia o nga tikanga kua whakaatuhia me te tiaki i nga hua mo te tukatuka ano.

Ko te roa o ia raupapa he 100 tau.
Ko te awhe o nga tau matapōkere he [0, 100).

I kohia nga raraunga mai i te maha o nga papaa wharangi:

  • Windows
    — Unity v2018.3.14f1, Aratau Kaiwhakatika, Mono, .NET Paerewa 2.0
  • MacOS
    — Unity v2018.3.14f1, Aratau Kaiwhakatika, Mono, .NET Paerewa 2.0
    — Unity v5.6.4p4, Aratau Kaiwhakatika, Mono, .NET Paerewa 2.0
  • Android
    — Unity v2018.3.14f1, hanga mo ia taputapu, Mono, .NET Paerewa 2.0
  • iOS
    — Unity v2018.3.14f1, hanga mo ia taputapu, il2cpp, .NET Paerewa 2.0

Реализация

He maha nga huarahi rereke hei whakaputa tau matapōkere. Mo ia o ratou, ka tuhia e matou he akomanga takai motuhake, me whakarato:

  1. Ka taea te tautuhi i te awhe o nga uara [min/max). Ka tautuhia ma te kaihanga.
  2. Tikanga whakahoki MF. Me kowhiria te maanu hei momo, i te mea he whanui ake.
  3. Te ingoa o te tikanga whakatipuranga hei tohu i nga hua. Mo te watea, ka whakahokia e matou hei uara te ingoa katoa o te akomanga + te ingoa o te tikanga i whakamahia hei whakaputa i te MF.

Tuatahi, me whakaatu he tangohanga ka whakaatuhia e te atanga IRandomGenerator:

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

        float Generate();
    }
}

Whakatinanatanga o te Pūnaha.Random.Next()

Ma tenei tikanga ka taea e koe te whakarite i te whānuitanga o nga uara, engari ka whakahoki tauoti, engari me maanu. Ka taea e koe te whakamaori noa i te integer hei maanu, ka taea ranei e koe te whakawhānui ake i te whānuitanga o nga uara ma te maha o nga ota o te rahi, me te utu i a raatau ki ia whakatipuranga o te tau waenga. Ko te hua ka rite ki te tohu-whakapumau me te raupapa tika. Ka whakamahia e matou tenei whiringa na te mea he tata ki te uara rewa tuturu.

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

Whakatinanatanga o System.Random.NextDouble()

Anei te awhe kua whakaritea [0; 1). Hei tohu ki runga i te mea kua tohua i roto i te kaihanga, ka whakamahi tatou i te tataunga ngawari: 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;
    }
}

Whakatinanatanga o UnityEngine.Random.Range()

Ko tenei tikanga o te UnityEngine.Random static class ka taea e koe te whakarite i te whānuitanga o nga uara me te whakahoki i tetahi momo rewa. Kaore koe e mahi i etahi atu huringa.

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

Te whakatinanatanga o UnityEngine.Random.value

Ko te taonga uara o te karaehe pateko UnityEngine.Random ka whakahoki mai i tetahi momo rewa mai i te awhe uara [0; 1). Me tohu ki runga i tetahi awhe kua rite ki te whakatinana i te 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;
    }
}

Whakatinanatanga o Unity.Mathematics.Random.NextFloat()

Ko te tikanga NextFloat() o te karaehe Unity.Mathematics.Random ka whakahoki i te ira maanu o te momo rewa ka taea e koe te tautuhi i te awhe o nga uara. Ko te ahua anake ko ia tauira o Unity.Mathematics.Random me arawhiti ki etahi kakano - ma tenei ka karo tatou i te whakaputa raupapa tukurua.

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

Te whakatinanatanga o te MainController

He maha nga whakatinanatanga o IRandomGenerator kua rite. I muri mai, me whakaputa e koe nga raupapa me te tiaki i nga huingararaunga kua puta hei tukatuka. Ki te mahi i tenei, ka hangahia e matou he waahi me tetahi tuhi MainController iti i roto i te Unity, ka mahi i nga mahi e tika ana, i te wa ano ka whai kawenga mo te taunekeneke me te UI.

Me whakarite te rahi o te huingararaunga me te awhe o nga uara MF, me te tiki tikanga hoki e whakahoki mai ai i te huinga o nga kaihanga kua whirihorahia, kua rite ki te mahi.

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

        ...
    }
}

Inaianei me hanga he huingararaunga. I tenei keehi, ka honoa te whakaputanga raraunga me te tuhi i nga hua ki roto i te awa kupu (i te whakatakotoranga csv). Hei penapena i nga uara o ia IRandomGenerator, ka tohatohahia tana ake pou motuhake, kei te rarangi tuatahi te Ingoa o te kaihanga.

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

        ...
    }
}

Ko nga mea katoa e toe ana ko te waea atu ki te tikanga GenerateCsvDataSet me te tiaki i te hua ki te konae, ka whakawhiti tonu ranei i nga raraunga i runga i te whatunga mai i te taputapu mutunga ki te kaimau whiwhi.

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

        ...
    }
}

Ko nga puna kaupapa kei GitLab.

Результаты

Kaore he merekara i tupu. Ko ta ratou i tumanako ko nga mea i riro mai - i roto i nga keehi katoa, he tohatoha noa kaore he tohu o te whakaaro. Kare au e kite i te take ki te whakatakoto kauwhata motuhake mo nga papaaho - he rite tonu nga hua.

Ko te mea pono ko:
BlessRNG te tirotiro ranei i te RNG mo te tika

Te tirohanga o nga raupapa i runga i te waka rererangi mai i nga tikanga whakatipuranga e rima:
BlessRNG te tirotiro ranei i te RNG mo te tika

Me te tirohanga ki te 3D. Ka waiho noa e ahau te hua o te System.Random.Next() kia kore ai e whakaputa i te paihere o nga ihirangi rite.
BlessRNG te tirotiro ranei i te RNG mo te tika

Ko te korero i korerohia i roto i te whakataki mo te tohatoha noa o UnityEngine.Random kaore i puta ano: i te tuatahi he he, he mea kua rereke mai i te miihini. Inaianei kua tino mohio matou.

Source: will.com

Tāpiri i te kōrero