Juhuslike arvude generaator. Õnnetus, kokkusattumus, muster

Kingi ideid

Ma ei alustanud artiklit ainult selle hüüatusega. On juhtunud, et programmeerija arsenalis on mugav tööriist, mis võimaldab tal saada etteantud intervallis juhusliku täisarvu. Teiste programmeerimiskeelte standardfunktsioonid genereerisid murdarvu vahemikus 0 kuni 1. See pole eriti mugav arv, mille kasutamiseks peate tegema eriti palju tööd, et saada näiteks juhuslik jada teatud vahemikus 1 kuni 5.

Mugav tööriist vajab kontrollimist, sageli pole RNG-d väga kvaliteetsed ja lisaks tuleb harjutada matemaatikat, et genereeritud arvude juhuslikkust suurendada, et halvasti segunenud pseudojadadest lahti saada. Usaldame sageli juhuslikke numbreid, mis sisaldavad saladusi, rahalisi ressursse, meelelahutust, modelleerimist, kriitiliste automatiseeritud juhtimissüsteemide testimist, testimisprogramme, mistõttu on väga oluline omada unikaalset seeriate jada, millel on mitmesugused kindlaksmääratud omadused väärtusvahemikest kuni kraadini. järjenumbrite segamisest.

Lubage mul tuua teile näide ebaõnnestunud juhuslike numbrite genereerimisest. Veel 1993. aastal, kui 640x480 eraldusvõimega mittevärvilist VGA-kuvarit peeti heaks ja programmeerijate silmad sellest vähem väsinud, oli Paradox DBMS laialt levinud. Borland Internationali ahned inimesed otsustasid rohkem raha teenida ja nõudsid võrgule juurdepääsuks 10 numbrist koosnevat võtit. Mida rohkem võtmeid sisestate, seda rohkem kasutajaid saavad üheaegselt andmebaasiga ühenduse luua.

Nüüd hakkan oma õnnestumistega kiitlema :). Erinevatel viisidel tuli mulle 3 klahvi ja mulle jõudis kohale, et jada oli pseudojuhuslik ja halvasti miksitud. Ilma igasuguse tehnoloogiata, keeruliste arvutusteta ja isegi ilma kalkulaatorita õnnestus mul neid klahve kätte saada suvaline arv. Borlandi firma muidugi suuri kahjusid ei kandnud, aga kuna te juba tegelete kaitsega, siis tehke seda hästi või ärge raisake aega asjatu töö peale. Ma ei võta siit moraali, loodan, et saab selgemaks, et RNG on oluline asi.

Pseudojuhuslike jadade kaitseks ütlen, et mõnikord on need vajalikud, näiteks kui turvavõti arvutatakse valemi abil ja programm otsustab võtit kohalikus režiimis edukalt kontrollida. 1993. aastal ei olnud Internet laialt levinud ja programmeerijad pidid välja pakkuma järjestusalgoritme ilma neid kolmandate osapoolte serverites testimata. Kuid segage kindlasti hästi. Võrkude kaasaegse arenguga on saanud võimalikuks nii programmide kui ka seadmete seerianumbri kontrollimine kinnitusserverite abil. See süsteem on oluliselt suurendanud vastupanuvõimet võltsimisele, kuid pole saladus, et vaatamata sellele esineb tarkvara volitamata kasutamist endiselt.

Järeldus on järgmine: lukud ja kõhukinnisused paigaldavad ausad inimesed.

Objekti käsitsemine platvormil 1C on äärmiselt lihtne, kuigi sellel on mõned iseärasused.

RNG = UusJuhuslikNumberGenerator(Initsialiseerimine); //Siin saab muuta juhuslike arvude generaatori tööd, numbri initsialiseerimise muutmine annab erinevaid tulemusi Return RNG.RandomNumber(1, SettingsOption);

Kui te ei määra Initsialiseerimist, genereeritakse jadad juhuslikult, lähtestades ise. Antud lähtestamisnumber tagastab ennustatava jada, mis on mõnikord vajalik ja kasulik. Ja kui määrate iga kord erineva numbri, saate numbrite jada väga hea segunemise.

Juhuslike arvude generaatori töö uurimiseks 1C-s lõin paar raviviisi ja ühe huvitavamaks muutmiseks mängu näol, aga mäng hiljem, äri enne.

Loodi 500 juhuslikku numbrit vahemikus 0 kuni 10 000, kusjuures generaatorit initsialiseeris pidevalt funktsioon CurrentUniversalDateInMilliseconds(). Diagramm näitab head väärtuste jaotust. Uhke muster. Y-teljel on arvu väärtus, X-teljel on iteratsiooniarv.

Punktide asukohad on üsna hõredad, peaaegu ei kleepu üksteise külge, mis on väga hea, mis tähendab, et genereeritud numbrid on väga mitmekesised.

Loome kunstlikult diagrammi halva versiooni:

Hea põlvkonna puhul ei tohiks see nii olla.

Juhuslike arvude generaatori seaded on väga oluline punkt. Neid on vähe, aga kõik sõltub neist.

Selle seadistuse korral moodustatakse 500 numbrist koosnev jada vahemikus 0 kuni 10000 ja generaatorit initsialiseeritakse pidevalt uue numbriga.

Vaatame genereeritud väärtuste tabelit, olles selle eelnevalt väärtuste järgi sorteerinud, et näha, kas seal on generaatori väljastatud korduvaid numbreid.

Sorteeritud nimekirja kiire visuaalne kontroll näitas, et kordusi oli, kuigi nende esinemise tõenäosus oli väike. Genereerimiseks määrati suur hulk numbreid, kuid sammudes 10 ja 30 korrati numbreid.

Järeldame: juhusliku arvu generaatori objekt suudab genereerida korduvaid numbreid.

See on mõnikord vastuvõetamatu. Näiteks genereerime ebajärjekindlalt juhusliku dokumendinumbri, et teavitada kasutajat, kes saab konkreetse dokumendi avada. Sel juhul on kordused vastuvõetamatud, vastasel juhul on kordumisel ebaselge, millist dokumenti avada.

Miks on vaja juhuslikku nummerdamist? Oletame, et väljastame oma partneritele remondiks üle antud seadmetele dokumentide numbrid. Pidevaid järjestikuseid nummerdusnumbreid saab väljastada, kuid klient, kellel on üks number, saab vaadata vähemalt naabernumbriid ja nummerdamisvahemikku teades saab vaadata kõiki dokumente. Toodud näites ei ole see nii saladus, kuid mõnikord on vaja teistest dokumentidest saadavat teavet salajas hoida.

Põlvkonnanumbrite väärtuste suurte intervallidega väheneb sündmuste kordumise tõenäosus, kuid kui sündmus võib toimuda, siis see kindlasti toimub.

Lahenduseks võiks olla genereeritud numbri kordumatuse kontrollimine, kuid väga pikkade jadade puhul võtab see palju aega. Peame mõtlema keerulisema segamise peale, aga see teeb ülesande huvitavamaks ;).

Väärtuste kuvamisel diagrammis hakkab töötlemine märgatavalt aeglustuma, minu arvutis pärast 1000 väärtuse lisamist, nii et seadetes on märkeruut "Ära genereeri diagrammi". Paigaldamisel suureneb töökiirus oluliselt pikkade jadade genereerimisel, seega olge uurides ettevaatlik genereeritavate numbrite arvu määramisel.

Generaatorile saab anda kindla lähtestamisväärtuse, siis olenemata sellest, mitu korda genereerida vajutad, on tulemus sama. Kui töötlemisväli "RNG lähtestamisnumber" on seatud väärtusele 0, toimub numbrijada genereerimisel pseudojuhuslik lähtestamine.

Generaatori kiirus on hea, näiteks 100 000 numbrit genereeriti vähem kui 0,5 sekundiga.

Näitan näidet RNG kasutamisest väikesel arvuvahemikul, kasutades mängu Rock, Paper, Scissors näidet.

Reeglid on lihtsad: kaks mängijat näitavad näidatud objekte žestidega. Võidab see, kellel on parasjagu tugevam figuur.

Rock võidab Scissorsi.

Käärid võidavad paberit.

Paber võidab Stone'i.

Selle variandi puhul on kõik samaväärne ja võiduvõimalused samad.

Pärast 99 mängu mängimist tegin igal figuuril sama palju klikke, 33 korda, seda on näha all paremal diagrammil. Arvuti võitis sagedamini kui mina, millest oli natuke kahju. Arvuti kasutas paberit sagedamini, nagu on näha alumises vasakpoolses diagrammis. Keskel olev graafik näitab, et ma ei olnud võitja. Arvuti võitude punane graafik on kõrgem kui roheline (minu võidud).

Proovi oma õnne! Vaatamata samale tükkide väljakukkumise tõenäosusele on tulemus alati erinev.

Mängu statistika kuvatakse keskel, ülaosas roosas elementide rühmas.

Klõpsates hiirega nuppu üks kord, saate seejärel kasutada klaviatuuril olevaid numbreid (mitte täiendavat) soovitud kujundi valimiseks. Klahve vajutades saate andmeid sisestada veidi kiiremini, eriti kui peate statistika kogumiseks mängima mõttetuid mänge.

Teeme mängu keerulisemaks. Lisame klassikalistele kujunditele kaevu.

Rock võidab Scissorsi.

Käärid võidavad paberit.

Paber võidab Rocki ja Welli.

Hästi alistab Rock and Scissors.

Selle variandi puhul ilmneb tükkide ebavõrdne väärtus ja teoreetiliselt on Paber ja Kaev valides võiduvõimalusi rohkem, kuna nende arsenalis suudavad nad alistada kaks kaasnuppu. Kontrollime seda praktikas:

Klõpsasin ainult tugevatel tükkidel ja võitsin. Teooriat kinnitas praktika.

Ainult nõrkadel tükkidel klikkimine andis ka tulemusi, kaotasin.

Mängu veelgi keerulisem versioon on viienda tüki Fire sissejuhatus.

Rock võidab Scissorsi ja Well kaotab Paberile ja tulele.

Scissors alistab Paper ja Fire kaotab Rock and Wellile.

Paber võidab Rock and Welli, kaotab Fire and Scissorsile.

No võidab Fire ja Scissors kaotab Rock and Paperile.

Fire võidab Paperi ja Rock kaotab Scissors and Wellile.

Selles variandis on nupud võrdsed, kuid kaks nuppu võidavad ja kaotavad, see lisab intriigi ja vähendab viikide tõenäosust.

Minu klõpsud olid kaootilised ja arvuti peksis mind uuesti. Mängu ajal on selle info põhjal näha, millist tükki arvuti sagedamini kasutab, saab proovida mängida mitte kaootiliselt, vaid läbimõeldult ja võimalusel oma eduvõimalusi suurendada.

Juhuslike arvude generaatori seadistamisel on oma omadused. Kui lipp "Ära kasuta kasutaja vastust" kustutatakse, kasutatakse RNG lähtestamisel mängija poolt vajutatud klahvi numbrit, mis lisab genereerimisele juhuslikkust. Inimene on suurepärane juhuslike arvude generaator, kuid siiski on ajus ka pseudojärjestusi. Kui sundida inimest tegema 100 klahvivajutust, siis saab seda protseduuri teha kohusetundlikult, võimalikult palju erinevaid klahve vajutades või teha seda hooletult, vajutades vaid ühte nuppu. Kui see lipp on seatud, töötab ainult arvuti segamine.

Inimeselt juhusliku järjestuse saamisel, näiteks elektroonilise allkirjavõtme loomiseks, on soovitav arvestada mitte ainult vajutatava klahvi, vaid ka vajutuste vahelise intervalliga. See on väga juhuslik teave, kuigi hea muusik võib sama jada mitu korda genereerida.

Lipp "Ära kasuta RNG lähtestamist" lülitab lähtestamisrežiimi sisse/välja. Kui Random Number Generator objekti loomisel initsialiseerimist ei määrata, siis genereeritakse segajada Nagu ma aru saan, on kaasas mingi initsialiseerimine, mis tundus mulle üsna tõhus.

RNG = UusJuhuslikNumberGenerator();

Samuti saate töötlemise käigus määrata oma initsialiseerimisnumbri, siis genereeritakse etteaimatavalt sama number.

Võitude arvutamise protseduuri kirjutades puutusin kokku tulemuse kirjeldamise probleemiga, eriti viiekohalise mängu puhul. Olles selle välja mõelnud, mõistsin, et tähti on palju, kuna nii paljude kujunditega on palju võimalusi. Kombinatoorika ütleb meile, et kolme numbriga on meil maksimaalselt 9 valikut, neljaga 16 valikut ja viiega 25 võimalust. Loosimise kõrvale heites, see on siis, kui valitakse sama kujund, sain aru, et pean kirjutama 19 tingimuste varianti.

Mõtlesin selle peale, kuna see tooks ilmselgelt kaasa halvasti loetava koodi ja leidsin minu arvates ilusa lahenduse. Kokku 9 tingimusega.

Res = Player - Comp; Kui SettingsOption = 3 Siis If (Res = -1) VÕI (Res = 2) Siis Return 1; //Võida muidu Return 2; //Lüüa EndIf; ElseIfSettingsOption = 4 Siis If (Res = -1) VÕI (Res = 2) VÕI (Res = 3) Siis Return 1; //Võida muidu Return 2; //Lüüa EndIf; ElseIf Sätted Valik = 5 Siis If (Res = -1) VÕI (Res = 2) VÕI (Res = -3) VÕI (Res = 4) Siis Return 1; //Võida muidu Return 2; //Lüüa EndIf; endIf;

Kompaktne, selge, hõlpsasti redigeeritav.

Arvasin, et igal kujundil on oma number: 1 – kivi, 2 – käärid, 3 – paber, 4 – noh, 5 – tuli. Mängu tulemusena arvutan välja nuppe numbrite vahe ja see vahe annab mulle selge vastuse küsimusele, kes võitis.

Töötlemine, mis aitab uurida hallatud rakenduse juhuslike jadade omadusi ja on kirjutatud ilma konfiguratsioonile viitamata. Testitud platvormil 8.3.10, 8.3.11 õhukeses kliendis.

Selle artikliga lootsin anda edasi juhuslike arvujadade genereerimise tähtsust ja tõsidust.

21
//Funktsioon genereerib lihtsalt loetava väärtuste esituse. // Numbrite vormindamise näited ValueFormat = Format(123456.789, " NRT=10; NRT=2"); //ValueFormat = "123 456,79"ValueFormat = vorming(123456,789, "HH=0; NHV=2"); //Väärtus 16
Täistekstiotsing – võimaldab leida tekstiteavet, mis asub peaaegu kõikjal kasutatavas konfiguratsioonis. Sel juhul saate vajalikke andmeid otsida kas kogu konfiguratsioonist tervikuna või kitsendades... 8
"Ajapunkt" on virtuaalne väli, mida andmebaasi ei salvestata. Sisaldab objekti ajahetke (mis sisaldab kuupäeva ja DOKUMENDI LINKI) 7.7-s oli mõiste Dokumendi asukoht ja 8.x-s Point in Time To get... 6
8.x jaoks FindByLinks (FindDataByRef) Süntaks: FindByLinks (Linkide loend) Parameetrid: Nõutav linkide loend Tüüp: massiiv. Massiivi linkide loendiga objektidele, mille linke on vaja leida. ...


Märksõnad: generaator, juhuslik, numbrid, arv, algoritm, juhuslik, juhuslik, jaotus, ühtlane, loterii

Ma ei arvanud, et see 1C-s kasulik oleks, aga siin sa oled... kliendid otsustasid korraldada promotsiooni nagu "kogu korgid kokku", ainult teil on vaja sõnu koguda, kes kogub oma komplektist õige sõna. kirjad võidavad. Üldiselt tundub ülesanne lihtne: on tähestik, on teatud sõna, mida tuleb koguda, näiteks "konjak", sellel on 6 tähte, nagu näete.

Peate: genereerima tähestiku mis tahes tähtedest teatud arvu juhuslikke kuuetähelisi kombinatsioone, lisama sellele teatud arvu valikuid, millesse saab sõna siiski lisada, näiteks “nkkoya” - sõna moodustatakse, aga "kavry" ilmselgelt ei sobi.

Lisatingimus: kõik need valikud (õiged ja mitte) peavad olema nummerdatud, et “auhinnakaardi” saamisel saaksid numbrit kontrollida (kas seda oli).

Näib, mis on 1C-l sellega pistmist? Seega tahetakse nende kaartide ja auhindade arvestus lisada raamatupidamisprogrammi ning samas paluti genereerida juhuslikke kombinatsioone (noh, mitte käsitsi koostada).
Iga kampaania puhul genereeritakse kombinatsioonid üks kord, seejärel tehakse nende põhjal kaardid, st. järgmine kord on sõna erinev jne.

Üldiselt taandub ülesanne järgmisele:
1. Looge juhuslikud arvud, eelistatavalt suure levikuga.
2. Arvutage numbri abil välja tähtede kombinatsioon (s.t. leia mingi vastavus võimalike kombinatsioonide ja nende numbrite vahel).
3. Eelmise vastandpunkt – kontrolli numbrite kaupa kombinatsiooni.

Lahendus:
1. sest avb ja NS generaator andis juhuslike arvude väikese jaotuse, pidin kasutama veidi teist algoritmi:

Funktsioon Random(), kui tühiväärtus(randSeed) = 1, siis randSeed = _getperformancecounter(); endif; randSeed=(a*randSeed+c)%m; tagasta randSeed; lõppfunktsioon

Siin:
a=1664525; c=1013904223; m = 4294967296;
viimane muutuja on 2 kuni 32. astmeni, ülejäänud kaks on selleks otstarbeks soovitatavad koefitsiendid

Maksimaalne väärtuse piirang 2^32 valiti kombinatsioonide maksimaalse arvu põhjal (kärbitud tähestiku puhul, millest igaüks koosneb 28 tähest ja 7 sõnast, kuna tegelikus ülesandes on neid täpselt 7, on kombinatsioonide koguarv 28 ^7, seega jääb valitud limiit ligikaudu intervalli keskele, mis on 20-30 tuhandest valikust koosneva valimi jaoks täiesti piisav)

Vajame ka veel ühte abifunktsiooni - positiivse täisarvu astmeni tõstmist:

Funktsioon Degree(Väärtus a, Väärtus b, Res=1) If b>0 then Res=Res*a; b=b-1; Kraad(a,b,Res); Return Res; Vastasel juhul Retur Res; endIf; EndFunction

Siin: a - astme alus, b - eksponent, Res - tulemus

2. Järjestikuste kombinatsioonide vahelise seose tuvastamine osutus üllatavalt lihtsaks:

Pärast mitme elemendi järjestamist paljastasin sümbolite paigutuse sarnasuse numbrisüsteemiga, ainult mitte kümnendsüsteemiga, vaid antud juhul "kuueteistkümnendsüsteemiga" (saadud "sõna" märkide arvu järgi).
Seega oli kombinatsiooni arvu järgi arvutamiseks vaja selle arv teisendada just sellesse arvusüsteemi.

Meie numbrisüsteemi jaoks on aluseks kuue astmed, st. vasakpoolse esimese numbri saamiseks peate jagama meie kombinatsiooni numbri 6-ga 5. astmeni, seejärel jagamise ülejäänud osa 6-ga 4. astmeni jne.

Seega saame kuuest numbrist koosneva komplekti, mis on sisuliselt meie tähestiku tähtede seerianumbrid.

Saadud kood:

Funktsioon GetCharacters(Pos,TechChar=1 ,SymStr="") Kui TechChar<к Тогда Делитель=Степень(СтрДлина(Буквы),к-ТекСимв); ТекОст=Поз%Делитель; СимСтр=Строка(СимСтр)+Сред(Буквы,Цел(Поз/Делитель+?(ТекОст>0 ,1 ,0 )),1); GetSymbols(TekOst,TekSymv+1,SymStr); tagasta SimStr; Muidu SimStr=SimStr+Keskmine(Tähed,(?(Pos=0 ,Pikkus(Tähed),Pos)),1 ); tagasta SimStr; endIf; EndFunction

Siin:
Pos – kombinatsiooni number (pseudojuhuslik arv)
TechSym – praegust sümbolit töödeldakse
SimStr – saadud tähemärkide jada
Tähed = string, mis sisaldab tähestiku tähti standardses järjekorras ("abv...yuya")
k - märkide arv otsingusõnas (antud juhul = 6)

3. Pöördteisendus on samuti triviaalne:

Funktsioon GetCombination(Word, TechCharacter=0 , Pos=0 ) NomCharacter=Find(Tähed, Medium(Word, to-Tech Character, 1 )); Kui TechCym>0, siis kui TechSym<к Тогда Поз=Поз+(НомСимв-1 )*Степень(СтрДлина(Буквы),ТекСимв); ПолучитьКомбинацию(Слово,ТекСимв+1 ,Поз); Иначе Возврат Поз; КонецЕсли; Иначе Поз=?(НомСимв=СтрДлина(Буквы),0 ,НомСимв); ПолучитьКомбинацию(Слово,ТекСимв+1 ,Поз); Возврат Поз; КонецЕсли; КонецФункции

Siin:
Sõna on märkide kombinatsioon, mille numbrit me otsime
TekSymv – praegune töödeldav sümbol (sisuliselt kuueteistkümnendsüsteemi numbri number)
Pos - nõutav kombinatsiooni number

Sega N numbrit:

A=1 kuni N silmuse massiiv[a]=a; tsükli lõpp; a=1 kuni N-1 tsükli korral Cl=juhtum(a,N); // Täisarv juhuslik arv intervallis [a..N] K = massiiv[a]; massiiv[a] = massiiv[Sl]; massiiv[Sl]=K; EndCycle;

Sc = CreateObject("MSScriptControl.ScriptControl "); Sc.language = "VBscript"; sc.executeStatement("juhuslikuks muutmine"); see on siin = Sc.eval("rnd ");

Kuidas teha juhuslikult valitud numbreid vahemikus 1 kuni 100?

Rand=_GetPerformanceCounter()%(100 +1 );
tundub, et see on parim

Raamatukogu matt. funktsioonid, kus on sl. numbrid:
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=92&lid=2688

8.0-s saate juhuslike numbrite genereerimiseks kasutada sisseehitatud GUID-generaatorit.
Siin on näide lihtsast funktsioonist:

//ainult täisarvude jaoks Funktsioon GetRandomNumber(Min,Max) //Juhusliku asemel n = 1 korda 100 Tsükkel Unikaalne = Uus kordumatu identifikaator; EndCycle; //genereerige kordumatu GUID = AbbrLP(uus kordumatu identifikaator); //hoida ainult numbreid Unikaalne = StrReplace(Unikaalne,"- ",""); Unikaalne = StrReplace(Unikaalne,"a ",""); Unikaalne = StrReplace(Unikaalne,"b ",""); Unikaalne = StrReplace(Unikaalne,"c ",""); Unikaalne = StrReplace(Unikaalne,"d ",""); Unikaalne = StrReplace(Unikaalne,"e ",""); Unikaalne = StrReplace(Unikaalne,"f ",""); //nimetajas peab olema sama arv nulle + 1 Nimetaja = 10 ; For n = 2 By (Tugevus(StrAsenda(Unikaalne,Märgid.NPP,""))) Tsükli nimetaja = Nimetaja * 10 ; EndCycle; Suurtäht = arv (unikaalne) / nimetaja; //siit saame murdosa juhusliku arvu 0-st 1-ni //teisendab selle antud intervallist juhuslikuks arvuks, ümardades lähima täisarvuni Intervalli arv = min(Max(Ab(Min + (Max-Min)*Rand),Min),Max); return NumberFromInterval; EndFunction

Teine süsteemivalik:
Rnd = CreateObject("Süsteem.Juhuslik"); Raport(Rnd.Next());

Märksõnad: generaator, juhuslik, numbrid, arv, algoritm, juhuslik, juhuslik, jaotus, ühtlane, loterii

Ma ei arvanud, et see 1C-s kasulik oleks, aga teile... kliendid otsustasid korraldada promotsiooni nagu "kogu korgid kokku", ainult teil on vaja sõnu koguda, kes kogub oma tähekomplektist õige sõna võidab. Üldiselt tundub ülesanne lihtne: on tähestik, on teatud sõna, mida tuleb koguda, näiteks "konjak", sellel on 6 tähte, nagu näete.

Peate: genereerima tähestiku mis tahes tähtedest teatud arvu juhuslikke kuuetähelisi kombinatsioone, lisama sellele teatud arvu valikuid, millesse saab sõna siiski lisada, näiteks “nkkoya” - sõna moodustatakse, aga “kavry” ilmselgelt ei sobi.

Lisatingimus: kõik need valikud (õiged ja mitte) peavad olema nummerdatud, et “auhinna” kaardi saamisel saaksid numbrit kontrollida (kas seda oli).

Näib, mis on 1C-l sellega pistmist? Seega tahetakse nende kaartide ja auhindade arvestus lisada raamatupidamisprogrammi ning samas paluti genereerida juhuslikke kombinatsioone (noh, mitte käsitsi koostada).
Iga kampaania puhul genereeritakse kombinatsioonid üks kord, seejärel tehakse nende põhjal kaardid, st. järgmine kord on sõna erinev jne.

Üldiselt taandub ülesanne järgmisele:
1. Looge juhuslikud arvud, eelistatavalt suure levikuga.
2. Arvuta numbri põhjal välja tähtede kombinatsioon (st leia mingi vastavus võimalike kombinatsioonide ja nende numbrite vahel).
3. Eelmise vastandpunkt – kontrolli numbrite kaupa kombinatsiooni.

Lahendus:
1. sest avb ja NS generaator andis juhuslike arvude väikese jaotuse, pidin kasutama veidi teist algoritmi:

Funktsioon Random()
kui tühiväärtus(randSeed) = 1, siis
randSeed = _getperformancecounter();
endif;

RandSeed=(a*randSeed+c)%m;
tagasta randSeed;
lõppfunktsioon

Siin:
a=1664525; c=1013904223; m = 4294967296;
viimane muutuja on 2 kuni 32. astmeni, ülejäänud kaks on selleks otstarbeks soovitatavad koefitsiendid

Maksimaalne väärtuse piirang 2^32 valiti kombinatsioonide maksimaalse arvu põhjal (kärbitud tähestiku puhul, millest igaüks koosneb 28 tähest ja 7 sõnast, kuna tegelikus ülesandes on neid täpselt 7, on kombinatsioonide koguarv 28 ^7, seega jääb valitud limiit ligikaudu intervalli keskele, mis on täiesti piisav 20-30 tuhande valiku valimiseks)

Vajame ka veel ühte abifunktsiooni - positiivse täisarvu astmeni tõstmist:

Funktsiooni aste (väärtus a, väärtus b, eraldusvõime = 1)
Kui b>0 Siis
Res=Res*a;
b=b-1;
Kraad(a,b,Res);
Return Res;
Muidu
Return Res;
endIf;
EndFunction

Siin: a - astme alus, b - eksponent, Res - tulemus

2. Järjestikuste kombinatsioonide vahelise seose tuvastamine osutus üllatavalt lihtsaks:

Pärast mitme elemendi järjestamist paljastasin sümbolite paigutuse sarnasuse numbrisüsteemiga, ainult mitte kümnendsüsteemiga, vaid antud juhul "kuueteistkümnendsüsteemiga" (saadud "sõna" märkide arvu järgi).
Seega oli kombinatsiooni arvu järgi arvutamiseks vaja selle arv teisendada just sellesse arvusüsteemi.

Meie numbrisüsteemi jaoks on aluseks kuue astmed, st. vasakpoolse esimese numbri saamiseks peate jagama meie kombinatsiooni numbri 6-ga 5. astmeni, seejärel jagamise ülejäänud osa 6-ga 4. astmeni jne.

Seega saame kuuest numbrist koosneva komplekti, mis on sisuliselt meie tähestiku tähtede seerianumbrid.

Saadud kood:

Funktsioon GetCharacters(Pos,TexCharacter=1,SymStr="")
Kui TekSymv jagaja=Degree(Tugevus(täht),k-TekSymv);
TechOst=Pos%jagaja;
SimStr=String(SimStr)+Av(Tähed,Täisarv(Pos/Jagaja+?(TekOst>0,1,0)),1);
GetSymbols(TekOst,TekSymv+1,SymStr);
tagasta SimStr;
Muidu
SimStr=SimStr+Keskmine(Tähed,(?(Pos=0,Pikkus(Tähed),Pos)),1);
tagasta SimStr;
endIf;
EndFunction

Siin:
Pos – kombinatsiooni number (pseudojuhuslik arv)
TechSym – praegust sümbolit töödeldakse
SimStr – saadud tähemärkide jada
Tähed = string, mis sisaldab tähestiku tähti standardses järjekorras ("abv...yuya")
k - märkide arv otsingusõnas (antud juhul = 6)

3. Pöördteisendus on samuti triviaalne:

Funktsioon GetCombination (Word, TechCharacter=0, Pos=0)
NomSymv=Leia(tähed,Am(Word,k-TekSymv,1));
Kui TechCym>0 Siis
Kui TechCym Pos=Pos+(NomCym-1)*Degree(Length(Letters),TechCym);
Muidu
Tagastamispositsioon;
endIf;
Muidu
Pos=?(NomCym=Strangth(Letters),0,NomSymv);
GetCombination (Word, tehniline märk+1, pos);
Tagastamispositsioon;
endIf;
EndFunction

Siin:
Sõna on märkide kombinatsioon, mille numbrit me otsime
TekSymv – praegune töödeldav sümbol (sisuliselt kuueteistkümnendsüsteemi numbri number)
Pos - nõutav kombinatsiooni number


************************

Sega N numbrit:

Tsükli jaoks a=1 kuni N
massiiv[a]=a;
tsükli lõpp;
Tsükli jaoks a=1 kuni N-1
Sl=Case(a,N);// Juhuslik täisarv intervallis [a..N]
K = massiiv[a];
massiiv[a] = massiiv[Sl];
massiiv[Sl]=K;
EndCycle;

//********************************************************************************
************************

Sc = CreateObject("MSScriptControl.ScriptControl");
Sc.language = "VBscript";
sc.executeStatement("randomize");
see on siin = Sc.eval("rnd");

Kuidas teha juhuslikult valitud numbreid vahemikus 1 kuni 100?

Rand=_GetPerformanceCounter()%(100+1);

tundub, et see on parim

//********************************************************************************
************************

8.0-s saate juhuslike numbrite genereerimiseks kasutada sisseehitatud GUID-generaatorit.
Siin on näide lihtsast funktsioonist:

//ainult täisarvude jaoks
Funktsioon GetRandomNumber (min, max)

//Randomize asemel
Kui n = 1 Kuni 100 tsüklit
Unikaalne = uus kordumatu identifikaator;
EndCycle;

//genereerige GUID
Unikaalne = AbbrLP(uus kordumatu identifikaator);

//hoida ainult numbreid
Unikaalne = StrReplace(Unikaalne,"-","");
Unikaalne = StrReplace(Unikaalne,"a","");
Unikaalne = StrReplace(Unikaalne,"b","");
Unikaalne = StrReplace(Unikaalne,"c","");
Unikaalne = StrReplace(Unikaalne,"d","");
Unikaalne = StrReplace(Unikaalne,"e","");
Unikaalne = StrReplace(Unikaalne,"f","");

//nimetajas peab olema sama arv nulle + 1
nimetaja = 10;
Kui n = 2 By (Tugevus(StrAsenda(Unikaalne,Märgid.NPP,""))) Silmus
Nimetaja = Nimetaja * 10;
EndCycle;

Suurtäht = arv (unikaalne) / nimetaja; //siit saame murdosa juhusliku arvu 0-st 1-ni

//teisendab selle antud intervallist juhuslikuks arvuks, ümardades lähima täisarvuni
Intervalli arv = min(Max(Ab(Min + (Max-Min)*Rand),Min),Max);

return NumberFromInterval;

EndFunction

Võetud saidilt [lingi vaatamiseks peate registreeruma]

//********************************************************************************
************************

PS. Selle artikli peale sattusin juhuslike arvude generaatorit otsides. Seega valisin enda jaoks selle variandi
Rand=_GetPerformanceCounter()%(100+1);