Pagina de start a forumului Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc
Comunitatea PHP Romania
 

random... preferential
Vezi mesajul original
Du-te la pagina 1, 2  Următoare
 
       Pagina de start a forumului Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc -> PHP Avansat
Subiectul anterior :: Subiectul următor  
Autor Mesaj
coditza



Data înscrierii: 23/Ian/2004
Mesaje: 298
Locație: cluj-napoca

Trimis: Joi Iul 22, 2004 1:55 pm    Titlul subiectului: random... preferential  

se da un sir de 10 numere, de la 1 la 10.
Se cere sa se scrie o functie care va returna in 60% din cazuri valoarea 5 si in restu de 40% din cazuri sa returneze una din restul de valori...

Solutia mea e de genul:
construiesc un nou sir, in care am numarul 1 de ceil(27/2) = 14 ori si restul de numere cate o data. Si fac un $key = rand(0,22) si returnez elementul din sirul nou creat de la keyul $key.

Problema e ca treaba asta trebe folosita la un sistem de banners rotators. S-ar putea ca arrayul respectiv sa devina destul de mare. Plus ca solutia nu mi se pare cea mai cea...

Are careva o alta idee?
Sus  
Birkoff



Data înscrierii: 18/Mar/2004
Mesaje: 2266
Locație: Bucuresti

Trimis: Joi Iul 22, 2004 3:55 pm    Titlul subiectului:  

o idee
incearca sa faci un script care sa scrie un nr in bd sau intr-un fisier text...
adica vizitez pagina odata se introduce nr 1 a doua oara nr 2 si tot asa...
in functie de anumite nr se afiseaza un anumit banner ( sa zicem ca din 5 in 5 afisari ale pagini se va afisa un anumit baner si in rest celelalte intr-o ordine prestabilita...
scriptul tau trebuie doar sa citeasca nr respectiv din bd si in functie de el (sau de valoarea lui) sa afiseze banerul corespunzator...

sper sa te ajute ideea
Sus  
coditza



Data înscrierii: 23/Ian/2004
Mesaje: 298
Locație: cluj-napoca

Trimis: Joi Iul 22, 2004 4:08 pm    Titlul subiectului:  

adik un fel de history la ce numere am scos deja or smth? e o idee, dar nu e mai buna decat cea folosita deja... asta ar insemna 3 queryuri la baza de date... 1 sa vad ce history am deja... unu sa fac update la history ala + unu sa scot baneru din baza de date. la solutia mea is numai 2 queryuri... scot toate idurile cu valorile lor de prioritate + query care scoate datele propriuzise

no, sa redefinesc "corect" problema: am o tabela cu tzajpe banere in care este pastrata si prioritatea. No, tre sa scot banneru Z de Z.priority ori (sau in Z.priority cazuri) etc

dupa un brainstorming cu coworkeri am ajuns la concluzia ca fara un counter extern nu poti sa scoti de exact 60% (cu rotunjirile de vigoare).
No, totusi, daca mai avetzi solutii, nu conteaza cand veniti cu ele, is bine primite. A devenit chestia asa un fel de "manie" personala
Sus  
Troto



Data înscrierii: 29/Iun/2004
Mesaje: 249
Locație: Brasov

Trimis: Joi Iul 22, 2004 6:03 pm    Titlul subiectului:  

Ce spui de asta

Nu stiu cum se comporta la matrici foarte mari. Testeaza si tu

<?php // Dupa parerea mea este imposibil ca in 60% din cazuri sa iti afiseze un anumit banner. // Tot ce poti face e sa aproximezi dand o marja de eroare. // Oricum, am sa incerc ceva si mai discutam pe baza scriptului // Indiferent ca numele, poza sau mai stiu eu ce a bannerului le ai intr-o baza de date sau un fisier // trebuie sa verificam cate bannere sunt in total. // Aici voi folosi o matrice. Matricea o poti genera dintr-o baza de date sau un fisier sau unde le ai // $bannerul pe care il vom afisa $banner_id_de_afisat = null; // Matrice cu bannere $matrice_cu_bannere = array(                             array(                                     'id'      => 0,                                     'afisari' => 0,                                     'nume'    => 'Banner 1',                                     'poza'    => 'images/banner/1.jpg'                                  ),                             array(                                     'id'      => 1,                                     'afisari' => 0,                                     'nume'    => 'Banner 2',                                     'poza'    => 'images/banner/2.jpg'                                  ),                             array(                                     'id'      => 2,                                     'afisari' => 0,                                     'nume'    => 'Banner 3',                                     'poza'    => 'images/banner/3.jpg'                                  ),                             array(                                     'id'      => 3,                                     'afisari' => 0,                                     'nume'    => 'Banner 4',                                     'poza'    => 'images/banner/4.jpg'                                  ),                            ); // id-ul bannerului principal $id_banner_principal = 0; // acum setam procentul pt bannerul 1 (sa spunem pe care vrem sa il afisam in x % din cazuri) $procent_necesar = 0.6; // setam si o marja de eroare in caz ca vrem asa ceva, altfel o punem 0 $marja_eroare = 0.1; // cate bannere avem $nr_bannere = count($matrice_cu_bannere); if ($matrice_cu_bannere[$id_banner_principal]['afisari'] == 0) {     $banner_id_de_afisat = $id_banner_principal; // daca bannerul principal nu a fost afisat deloc il afisam direct fara a mai calcula } else {     // facem suma afisarilor tuturor bannerelor cu exceptia celui mai important     $suma_afisari_celalte_bannere = 0;     for ($i=0; $i<$nr_bannere; $i++) {         if ($i != $id_banner_principal) { // sa nu adunam bannerul important             $suma_afisari_celalte_bannere += $matrice_cu_bannere[$i]['afisari'];         }     }     // totalul afisarilor realizate pana in prezent     $total_afisari = $suma_afisari_celalte_bannere + $matrice_cu_bannere[$id_banner_principal]['afisari'];     // procentul realizat pana in rpezent de bannerulprincipal     $procent_curent_realizat = ($matrice_cu_bannere[$id_banner_principal]['afisari'] / $total_afisari);     if ($procent_curent_realizat <= $procent_necesar - $marja_eroare) {         // afisam bannerul principal         $banner_id_de_afisat = $id_banner_principal;     } else {         // in caz ca nu afisam bannerul principal calculam sa vedem ce alt banner afisam         // stergem bannerul principal din matrice         unset($matrice_cu_bannere[$id_banner_principal]);         // setam bannerul cu cele mai putine afisari un banner aleator         srand((float) microtime() * 10000000);         $index_random = array_rand($matrice_cu_bannere);         $min_b_id     = $matrice_cu_bannere[$index_random]['id'];         $min_b_afis   = $matrice_cu_bannere[$index_random]['afisari'];         reset($matrice_cu_bannere);         foreach($matrice_cu_bannere as $banner) {             // daca intalnim un banner care nu a fost afisat il afisam pe acela             if ($banner['afisari'] == 0) {                 $banner_id_de_afisat = $banner['id'];                 break;             } else {                 // salvam valoarea minima intr-o variabila temporala                 $tmp_min = min;                 // calculam minimul dintre valoarea minima precedenta si a cea a bannerului curent                 $min = min($min_b_afis, $banner['afisari']);                 // daca valoarea minima se schimba inseamna ca am gasit o valoare ma mica si o salvam pe aia                 if ($tmp_min != min) {                     $min_b_afis = $min;                     echo $min_b_id   = $banner['id'];                 }             }         }         // bannerulpe care il afisam e minimul gasit         $banner_de_afisat = $min_b_id;     } } print_r($matrice_cu_bannere[$banner_id_de_afisat]); ?>

Dupa ce afli ID-ul bannerului trebuie doar sa reactualizezi baza de data sau fisierul, sau unde tii tu toate datele, dar asta nu am mai facut :D
Sus  
coditza



Data înscrierii: 23/Ian/2004
Mesaje: 298
Locație: cluj-napoca

Trimis: Joi Iul 22, 2004 9:14 pm    Titlul subiectului:  

is cam obosit acum, dar algoritmul pare ok. Nu am vazut asa la o prima citire nici o scapare. Il citesc maine iara, sa vedem ce chestii ar putea apare si/sau ce imbunatatiri se pot aduce
Sus  
Troto



Data înscrierii: 29/Iun/2004
Mesaje: 249
Locație: Brasov

Trimis: Joi Iul 22, 2004 11:30 pm    Titlul subiectului:  

E facut in graba in jma de ora.

cred eu ca sunt ceva scapari, dar in mare isi face treaba.

Oricum , trebuie adaptat dupa necesitatile tale. Oricum macar un inceput sper sa fie. de aici mai discutam pana il facem asa cumiti trebuie

Somn usor :P
Sus  
coditza



Data înscrierii: 23/Ian/2004
Mesaje: 298
Locație: cluj-napoca

Trimis: Vin Iul 23, 2004 2:42 pm    Titlul subiectului:  

Troto a scris: Somn usor :P
right... poate la noapte
Sus  
smallAdmin



Data înscrierii: 21/Mai/2004
Mesaje: 117
Locație: Bucuresti

Trimis: Vin Iul 23, 2004 2:54 pm    Titlul subiectului: Re: random... preferential  

Generalizat : vreau aleg un numar random din n. Fiecare numar are o pondere de aparitie.
Solutie : construiesc un vector cu n elemente, fiecare element avand ponderea fata de toate celelalte...
Aleg un numar aleator intre 0 si suma tuturor elementelor din vector.
Pentru exemplul de mai jos ($pond), numarul generat de rand daca e mai mic decat 5, insemna ca numarul cautat e 1, daca e intr 5 si 10 numarul cautat e 2 si tot asa...
<?php // vectorul de ponderi... // fiecare element din vector inseamna cata pondere are in facutul de random $pond=array(0,5,5,5,5,55,5,5,5,5,5); $total=array_sum($pond); $n=count($pond); $rand=rand(0,$total-1); $add=0; // caut cheia din vector care se potriveste cel mai bine for($i=0;$i<$n;$i++){     $add+=$pond[$i];     if($add>$rand){ // am gasit numarul, asa ca ies         $randul_cautat=$i;         $i=$n;     } } echo 'Randomul cautat : '.$randul_cautat.', pondere : '.number_format($pond[$randul_cautat]/$total*100,2).'%'; ?>
In exemplul de mai sus, fiecare pondere e fix procentul de care am nevoie.
Sus  
Troto



Data înscrierii: 29/Iun/2004
Mesaje: 249
Locație: Brasov

Trimis: Vin Iul 23, 2004 3:08 pm    Titlul subiectului:  

Solutia asta nu e chiar asa de buna pentru ca de fiecare data iti returneaza acelsi rand cautat
Sus  
smallAdmin



Data înscrierii: 21/Mai/2004
Mesaje: 117
Locație: Bucuresti

Trimis: Vin Iul 23, 2004 3:09 pm    Titlul subiectului:  

varianta 2 ( folosind si o tabela MySQL )
an style="color: #000000"><?php // tabela bannere cu campurile : id(primary key), views, pondere // ponderea e exprimata in procente $res=mysql_query("select sum(views) from bannere"); list($total_views)=mysql_fetch_array($res,MYSQL_NUM); $res=mysql_query("select *,pondere-(views/$total_views)*100 as diferenta from bannere order by diferenta desc limit 1"); $banner=mysql_fetch_array($res); mysql_query("update bannere set views=views+1 where id=$banner[id]"); 
Ideea e ca incerci mereu sa iei un banner a carui pondere de afisare in momentul actual e cea mai departata de pondeea cu care trebuie sa fie afisat acel banner.
La fel ca in exemplul de mai sus, poti folosi oricate bannere, in schimb e mai dificil sa adaugi un banner pentru ca trebuie sa schimbi si celelalte ponderi astfel incat sa ai suma tuturor ponderilor 100.
E netestat, da' sper ca intelegi ce am vrut sa zic ;)
Sus  
Troto



Data înscrierii: 29/Iun/2004
Mesaje: 249
Locație: Brasov

Trimis: Vin Iul 23, 2004 4:14 pm    Titlul subiectului:  

smallAdmin a scris:
La fel ca in exemplul de mai sus, poti folosi oricate bannere, in schimb e mai dificil sa adaugi un banner pentru ca trebuie sa schimbi si celelalte ponderi astfel incat sa ai suma tuturor ponderilor 100.


tocmai de asta cred ca solutia mea este mai buna deoarece nu trebuie sa schimbi ponderile la fiecare adaugare a unui banner... daca ai f mute bannere o sa fie extrem de dificil
Sus  
smallAdmin



Data înscrierii: 21/Mai/2004
Mesaje: 117
Locație: Bucuresti

Trimis: Vin Iul 23, 2004 7:10 pm    Titlul subiectului:  

Troto a scris: Solutia asta nu e chiar asa de buna pentru ca de fiecare data iti returneaza acelsi rand cautat
Incearca mai multe refreshuri... statistic e corect. Dupa vreo 10 incercari ar trebui sa ai de 5-7 ori numarul 5...
Troto a scris: tocmai de asta cred ca solutia mea este mai buna deoarece nu trebuie sa schimbi ponderile la fiecare adaugare a unui banner... daca ai f mute bannere o sa fie extrem de dificil
Bine ma, e mai buna... :D da' tre' sa recunosti ca a mea e ingenioasa si merge pe cazul general ;)
Sus  
Troto



Data înscrierii: 29/Iun/2004
Mesaje: 249
Locație: Brasov

Trimis: Vin Iul 23, 2004 8:14 pm    Titlul subiectului:  

In primul rand variabila $total este intotdeauna 100 dupa cum ai spus tu..corect?

apoi inainte de a apela rand() (in care puiteai f bine sa pui rand(0,99)) trebuie sa ai ceva de genul

an style="color: #000000"><?php function make_seed() {    list($usec, $sec) = explode(' ', microtime());    return (float) $sec + ((float) $usec * 100000); } srand(make_seed()); 

Asta in cazul in care ai php 4.2 (eu am 4.3.8 dar se pare ca totusi un mic program care il folosesc pt testare esueaza la treburi de genul asta. .. asa ca acum l-am testat in server direct)

Ideea e buna, dar totusi nu prea ai control sigur asupra valorilor. Adica statistic vorbind e bine.. dar asta nu inseamna ca e si corect. Sti cum e .. daca am o palma in foc si alta in frigider .. statistic mie mi-e bine.. lucru care nu e tocmai asa :)
Sus  
coditza



Data înscrierii: 23/Ian/2004
Mesaje: 298
Locație: cluj-napoca

Trimis: Lun Iul 26, 2004 5:44 pm    Titlul subiectului:  

deci 2 idei care merita discutate. pana maine sper sa le citesc si eu... pana una alta, hi sa discutam unpika despre criptarea parolelor in baza de date pe urmatorul topic :D
Sus  
coditza



Data înscrierii: 23/Ian/2004
Mesaje: 298
Locație: cluj-napoca

Trimis: Mie Iul 28, 2004 5:37 pm    Titlul subiectului:  

no, sefu mi-o dat cel mai bun algorit de pana acum :D
pur si simplu, cand userul intra prima oara pe pagina, ii generezi un "path" cum ii areti banerele... si tot elimi cate un baner din pathul ala. cand s-o golit, il regenerezi... simplu... doar un sir in $_SESSION ;)
Sus  
PHPRomania Bot
Bot Member


Data înscrierii: 27/Dec/2007
Mesaje: 1
Locaţie: Server Google
Trimis: Mie Dec 26, 2007 7:01 pm   Titlul subiectului: Ad  

Sus  
 
       Pagina de start a forumului Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc -> PHP Avansat Du-te la pagina 1, 2  Următoare
Pagina 1 din 2


Powered by phpBB 2.0.22 © 2001, 2002 phpBB Group
Varianta în limba română: Romanian phpBB online community