» »

[php] unique random

[php] unique random

sebavet ::

Še eno cvetko imam na lagerju. A je možno v tabelo polnit naključne 8 mestne številke preko celega leta več let (cca 100 dnevno), ne da bi ob kreiranju nove številke preverjal v tabeli ali taista že obstaja. Random številka v tabeli še ne sme obstajati.
Vem, da bi lahko napisal funkcijo, ki bi novo številko primerjala z že obstoječimi v tabeli in če že obstaja iskala drugega. Vendar bi to preverjanje rad obšel.

prtenjam ::

Pozdravljen,

Odgovor na tvoje vprašanje je že po definiciji naključnosti negativen! Če izbereš povsem naključno število na nekem območju to pomeni, da lahko izbereš katerokoli število na tem območju - torej tudi tistega, ki ga že imaš vpisanega v tabeli.

Vsaka rešitev bo torej v neki točki morala brati tabelo in preveriti katera števila tam so in katera ne.
Matjaž Prtenjak
https://mnet.si

Yacked2 ::

Najprej zgeneriraš in šele nato preveriš ali je notri takole:

števila = generiraj(); funkcija vrne 8 mesto število

while(in_array(število))
število = generiraj()
Korak naprej ni vedno ustrezen...sploh če si na robu prepada!

sebavet ::

@prtenjam: ja, glede nakjučnosti imaš prav.
Kaj pa funkcija, ki bi zgenerirala cca. 1000000 različnih osem mestnih števil znotraj 99999999, je pa pomembno, da so števila večja od 10.000.000. Sin in cos odpadeta, ker se potem, ko je argument večji od 360 začnejo ponavljati.

Zgodovina sprememb…

  • spremenil: sebavet ()

black ice ::

Vseeno boš še vedno moral preverjati, če že imaš element v arrayu.

galu ::

Ena teoretična rešitev:

- narediš pool vseh možnih kombinacij (dolžine cca 9*10^7 elt)
- izbereš eno random število med 0 in dolžino poola (recimo mu X) in potegneš število iz poola na indeksu X, kateremu rečemo Y. Pool se tako zmanjša za 1.
- dodaš Y v svoje polje naključnih, neponavljajočih števil

Problemi so predvsem v 1. iztočnici: kreacija bi trajala zajetno količino časa, velikost takega polja pa bi zasedala več kot četrt GB pomnilnika :D

Se pa izogneš čekiranju, ali je random število že bilo kdaj izbrano, ja. :))
Tako to gre.

Zgodovina sprememb…

  • spremenil: galu ()

dasf ::

Lahko narediš naključno permutacijo celotnega obsega, za 1-100 milijon 32-bit števil bi potreboval cca 380 MB spomina.
Fisher-Yates shuffle @ Wikipedia

Da se pa tudi implementirati generatorje neponavljajočih naključnih števil, npr. z kvadratnimi ostanki.
Quadratic residue @ Wikipedia

Fuks ::

Kaj pa če bi seedal random? Če random seedaš z neko fiksno cifro, to pomeni da vsakič dobiš enako zaporedje psevdonaključnih števil. Ponavadi so algoritmi kar dobri in se številke začnejo zelo pozno ponavljati.

Glede na wiki je v PHP uporabljen PRNG, ki ima periodo 2^19937 - 1. To pomeni, da bi lahko vsak dan zavrgel random številke prejšnjih dni in nadaljeval od tam kjer si prejšnji dan začel. Oz nevem ali ima php tudi možnost da dobiš random na točno določenem mestu.
Mersenne Twister @ Wikipedia

Še vedno ti ostane tudi implementacija svojega bolj custom psevdonaključnega generatorja. Psevdokoda je tudi na wiki ;)

sebavet ::

Morda ima kdo izkušnje koliko časa bi trajala funkcija, ki bi najprej prebrala 10000 števil iz tabele v array nato pa preverjala ali je določeno število v array. Na koncu pa vrnilo rezultat. Čist hipotetično? Saj bi lahko sprogramiral in izmeril, a vseeno vprašam.

Ziga Dolhar ::

Kaj pa, če bi funkcija kr lepo v tabelo pogledala, ali želeni ID že obstaja?

Mimogrede - al mora bit nujno "osemmestni integer", al bi si ti v bistvu rad naprogramiral GUID?
https://dolhar.si/

technolog ::

Če boš naredil naivno, se pravi da poizkušaš številke, dokler ne zadaneš še neporabljene, se bo zgodilo, da bo ta funkcija trajala vedno dlje in dlje časa.

Boljš rešit tako, da preveriš, koliko števil si že generiral do sedaj (N), potem pa generirati število na (1, 10^8 - N) in ga ustrezno postaviti.

Za kaj rabiš to naključnost?

Zgodovina sprememb…

c3p0 ::

Če nisi res omejen z dolžino 8 mest, lahko spredaj dodaš npr. še trenutni timestamp, tako nikoli ne bo podvajanja.

prtenjam ::

Življenje me je izučilo, da so preproste rešitve skoraj vedno tudi dovolj dobre. Dandanes je iskanje po ključu v tabeli zalo zelo hitro in če imaš tabelo že generiranih števil je trivialno vsekati novo število preveriti ali obstaja in če obstaja si izmisliti novo. V kolikor je bazen naključnih števil dovolj velik je možnost podvajanja ni velika in stvar deluje.

Kadar pa si omejen in bi čez čas bilo vedo manj in manj še neizbranih števil ter bi iskanje trajalo vedno dlje, pa naredil sledeče:
1. Napolni bazo z vsemi število - praviš, da si omejen zato števil pač ni neskončno veliko.
2. Naključno izberi število med 1 in velikostjo tabele (COUNT(*))
3. Preberi število na tem mestu
4. Izloči število iz tabele

Glede na konkretno situacijo pa lahko postopke kombiniraš - dokler imaš veliko prostih števil delaš po prvem načinu, ko ti števil zmanjkuje pa po drugem. Ali pa vseskozi delaš po prvem načinu in ko zadeneš že izbrano število si ne izmisliš novega temveč vzameš kar naslednjega večjega, ki še ni izbrano...

V glavnem opcij je veliko in so relativno nezahtevne - a kot rečeno v vsakem primeru boš nekako moral ugotoviti ali se je neko število že pojavilo ali ne - toda to je z današnjimi DB bliskovito hitro...
Matjaž Prtenjak
https://mnet.si

technolog ::

3 giga tabela samo za to?

Ravno tako je operacija COUNT v O(n), tako da je treba poskenirat celotno tabelo vsakič. To lahko rešiš tako, da nekje posebej hraniš še števec.

Je pa definitvno branje števila na N-tem mestu O(N). Grozno počasno bo tole.

Yacked2 ::

Zakaj pa to sploh rabiš, verjetno obstaja boljši pristop
Korak naprej ni vedno ustrezen...sploh če si na robu prepada!


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Python - pomoč (strani: 1 2 3 )

Oddelek: Programiranje
10317142 (7890) black ice
»

največkrat pojavljeni element v tabeli

Oddelek: Programiranje
181845 (1220) pac1
»

Java-random-polje

Oddelek: Programiranje
6876 (755) LeQuack
»

Nasvet - izpis najvisjega stevila

Oddelek: Programiranje
92765 (2468) Keki
»

[C] generator naključnih števil

Oddelek: Programiranje
363302 (2820) Thomas

Več podobnih tem