![]() |
random koji favorizuje
pozdrav ekipo
nije da sam bas toliko los sa matematikom koliko mi se spava :) elem problem: potreban mi je specijalan random koji ce raditi na sledecem principu: spec_rand($from,$to,$factor); elem to bi radilo otprilike ovako spec_random(10,100,3); to bi znacilo da je 3x veca mogucnost da funkcija vrati veci broj tj blizi 100 a ako bi faktor bio -3 znaci veca verovatnoca da ce biti manji broj, tj blizi 10 any ideas? p.s. ne, nisam googlao :D p.s.2 kratko objasnjenje, imacu neku tabelu sa nekim proizvodima, gde ce svaki imati neki faktor recimo od 1-100, a na glavnoj stranici ce se prikazivati recimo 20 proizvoda stim sto ce biti favorizovani ovi sa vecim faktorom.. a ako u spec_rand funkciju unesem 0 kao faktor onda da radi kao obican random, tj da ne favorizuje... hmm sad razmisljam 1 i -1 faktor bi bili takodje kao obican random.... |
Citat:
Срећом па се то лако ради ако имаш на лагеру генератор униформне расподеле, можеш да направиш ма који други. Међутим овако како си ти дефинисао неће да може, или бар не може директно. Бољи начин је да одредиш функцију расподеле која ти врши посао, а онда да пробаш некако ту функцију да пресликаш у твој параметар. Почиње се од функције расподеле за униформну случајну променљиву на интервалу 0 до 1. За друге интервале можеш да скалираш, али овај је најједноставнији. Означи са U ту случајну променљиву. Њена функција расподеле је: F_U(x) = P( U < x) = { 0, x <0 ; x, x E [0, 1]; 1, x > 1 Претпостави сад да знаш која ти функција расподеле G(x) треба. Она ти зависи од примене, тако да је дефинисање G(x) твој посао. Претпостављам из твог описа да се ради о линеарној функцији густине расподеле, према томе о квадратној функцији расподеле, на опсегу који те занима. То је зато што је функција расподеле интеграл функције густине расподеле, а како је густина вероватно линеарна, то је расподела квадратна. Али о овом касније. Све што треба јесте да генеришеш случајну променљиву Y = G^-1(U), где је G^-1 инверзна функција од G, а U случајна променљива са униформном расподелом. Тако добијена променљива има управо расподелу G(x). Доказ следи: F_Y(x) = P ( Y < x) = P( G^-1(U) < x) = P [U < G(x)]= G(x). Дакле добили смо да је тачно: F_Y(x) = G(x) а то је оно што нам треба. Због појављивања инверза функције расподеле G, она мора да буде монотона. Уколико није, у овом случају то може да се реши накнадним пермутовањем елемената, а у општем случају можда треба да се потражи други генератор. ф |
Само да допуним горњу причицу једним примером, да не буде да лупам у празну шерпу.
Пробаћу да набодем шта ти је потребно, мада то није тако добро дефинисано. Претпостављам да је густина расподеле g(x) на интервалу (f,t) (from->to) таква да је g(t) = n * g(f), што је отприлике оно што си рекао горе. Једино је фактор мало другачији јер је инверз мултипликативан а не адитиван као у твом случају. Тојест, обрнути случај од n = 3 добио би се са n' = 1/3, а не са n = -3. Али то ваљда није неки проблем. Претпоставићу да је интерполација између крајњих тачака линеарна. Овај део ниси навео у поставци, тако да провери да ли ти одговара. Тада је: g(x) = { 0, x < f; ax + b, x E [f, t]; 0, x > t Треба нам да одредимо a и b у функцији од n да бисмо добили g(x). Онда ћемо да инвертујемо g(x) и то је оно што нам треба. Линеарном интерполацијом се добија да је: a = (n-1) / (t-f) * q b = (t - nf) / (t-f) * q што су вредности које добијете ако протурите праву ax+b кроз тачке: (f, q) и (t, nq). Овде нам је n параметар кога задаје корисник, а q мора да се одреди из интегралног услова за расподелу. Пошто g(x) мора да задовољи интегрални услов за расподелу да је \int_{-\infty}^{+\infty} = 1, интеграљењем функције g(x) по целом домену добије се: q = 2/[(n+1)(t-f)] (паде ми напамет мало касније па да допуним: вредност за q добио сам формално интеграљењем, али може да се добије и на бржи начин тако што се уочи да је средња вредност функције тачно на средини интервала. Штос је сличан ономе ког је Гаус искористио да срачуна брзо збир свих бројева од 1 до 100) Сада треба да пређемо на функцију расподеле G(x). По дефиницији, G(x) = \int_{\infty}^x g(x) dx а интеграљењем део по део у овом случају добија се: G(x) = { 0, x< f; a/2(x^2-f^2) + b(x-f), x \in [f, t]; 1, x > t Налажењем инверза G^{-1}(x) добија се, за интервал [0,1] ово: G^{-1}(y) = H(y) = 1/a * ( -b + \sqrt{ b^2 + 2a(a/2 f^2 + bf)}) где су нам све величине или познате од пре, или зависе од параметра n. H(y) је у ствари функција и од параметра n, па ћу да забележим: H(y; n). И сад је лако. Ако имаш функцију rand() која генерише реални број од 0 до 1 са униформном расподелом, радиш следеће: u = rand(); y = H(u; n) И број y је извучен тачно из расподеле коју си хтео. ф |
u prevodu za one koji nisu sa ETF-a ili PMF-a, poenta je da podelis interval na konacan broj delova (tj. cele brojeve u ovom slucaju) i da onda napravis funkciju koja ce da oslika to "favorizovanje". Posto imas na raspolaganju funkciju koja daje (pseudo) uniformnu raspodelu, odnosno svi brojevi na intervalu imaju iste sanse, ono sto treba da se uradi je da se prosiri interval na kome je odredjeni rezultat. Ako 1 ima 5 puta vece sanse od 5 onda, da bi dobio tvoju verovatnocu na intervalu (1,5) treba da ti je interval za rezultat "1" od 0-4, za rezultat "2" od 5-8, "3" je od 9-11, "4" od 12-13 i "5" je 14. Onda izvuces rand (0,14) i vidis u koji interval ti upada dobijeni rezultat. "1" ti ima verovatnocu 5/15, "2" je 4/15, "3" je 3/15, "4" je 2/15 i "5" je 1/15, odnosno dobio si trazeno..
|
Mozda mozes da iskoristis (PHP manual):
Citat:
|
i ja sam razmisljao nesto kao ivanhoe, na kraju sam nacrtao grafik i vidm da je to manje-vise neka logaritamska funkcija...
sad ja znam da je ovo daleko od idealnog, al radi posao (pod pretpostavkom da je range 1 <-> x i da je n >= 2 ) Kôd:
-spec_rand(1,30,100) vraca skoro uvek 22 i vece.. bas se retko zadesi manji od 20 naravno glavni je nedostatak sto se neki brojevi zbog zaokruzivanja ne pojavljuju redje, vec nikad :( |
dve stvari
1) gornji kod treba da bude:: Kôd:
function spec_rand($from,$to,$n){ 2) uh, zakomplikovah ga bez potrebe, ovo resava stvar (tako mi se bar cini) Kôd:
|
Očigledno se nisi potrudio da pročitaš šta su ti ljudi napisali nego teraš svoje... ;)
Da probam da približim ovo što Ivanhoe kaže (filmil je i za mene previše stručan ;)), prenoseći ideju u svet baza. Dakle, na raspolaganju ti je npr. najobičnija unfiormna random funkcija rand(n), koja vraća ceo broj između 0 i n. Imaš tabelu T sa nekim ID-jem i nekim slogovima. Svaki slog ima polje težina, koja je neki integer. Hoćeš da polje sa 5 puta većom težinom od drugog bude 5 puta verovatnije izvučeno iz random bubnja. Uradiš sledeće: n := select sum(težina) from T x := rand(n) Upit koji ti vraća traženi slog je: Kôd:
select top 1 t1.id, sum(t2.težina) from tabela t1 |
Hvala!
|
Citat:
Пробај са квадратним кореном, не мораш нужно да наместиш све параметре као што сам показао, него направи неколико проба са разним параметрима, па узми шта ти се највише свиђа. ф |
holly ****, izgleda da radi :)
(doduse za 1/n favorizuej vece a za n manje brojeve, nisam uradio onaj deo gde inverzujes) Kôd:
Kôd:
0 0 za 1 se svaki mapira na sebe Da probam jos jednom da objasnim zasto mi je ovo bitno (osim sto sam istripovao da je bitno :) ) zato sto hocu da jednom kad popunim tu tabelu proizvodima, i odredim tezine, posle samo menjam taj jedan parametar, tako da ako je 1 onda radi obican random (testirao sam sa ovom F-jom, radi) a ako hocu da favorizujem neke proizvode, samo malo podignem n, bez potrebe da cackam po bazi. a takodje se moze iskoristiti kod za prokazivanje oglasa i baner-a (valjda) Elem ovo sasvim radi posao, sad samo da vidim kako da ga mapiram na bazu. :D |
Zanimljiva ideja, samo pazi da ne smoris one koji ce azurirati takav sajt. U praksi je uglavnom dovoljno oznaciti neki proizvod kao "promovisani" i takve proizvode gurati u prvi plan. Znaci, bas mi je zanimljivo to kako si zamislio, samo ne znam koliko ce to biti lako odrzavati sa par hiljada proizvoda npr.
|
opusteno, moj projekat :D
edit: naravno, filmil ima pice+klopu kad dodje ovde.. :) |
Jednom davno sam radi onesto slicno i primenio sam nesto drugaciju logiku. Naime, moj radnom gneerator je morao da ispuni uslov da obezbedi da se svaki elemnet prikaze dovoljan broj puta. Zbog toga nisam ostavljao da sve prosto zavisi od matematike nego sam uradio sledece:
Uveo sam pojam kruga, definisan kao broj prikazivanja dok svi elementi nisu prikazani bar jednom. Standardno se element prikazuje jednom u jednom krugu. Za svaki elemnt se definise koliko puta cesce se pojavljuje od standardnog. Ako je 1 onda se element pojavljuje standradno ucestano, ako je 2, dva puta, 5 pet puta, a moze da se koriste i decimalni brojevi za profinjenije odnose. Imam jedan brojac koji broji "krugove" Jedan krug se zavrsava kada su svi elementi prikazani bar jednom. Za svaki element se pamti i koliko je puta prikazan. Imajuci ove podatke, relativno je jednostavno izvlaciti elemente koji su za prikazivanje. |
heh, ja sam ladno sinoc sanjao random funkciju
cilj random funkcije je da bude takva da sa njom moze da se dobije recimo random n lica razlicite starosne dobi ali tako da odgovara trenutnom preseku populacije i resenje je tu negde bilo al kao i svaki san najbolje se zaboravi ;) verovatno je poruka - moze to i na javi ) |
LOL, vrlo zanimljiv san :)
|
Citat:
A onda lepo nazad na random :1042: |
Vreme je GMT +2. Trenutno vreme je 03:07. |
Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.