20. maj 2003 - 22:29Der er
46 kommentarer og 1 løsning
random, men ikke den samme 2 gange i streg
Jeg har lavet denne function som skulle trække en ramdom citat ud af en database hver gang funktion bliver brugt, men jeg kan ikke få den til at virke ordenlig :(
function randomcitat() { $foresp = mysql_query("SELECT * FROM mamster_citat WHERE id != '$_SESSION[lastcitat]' ORDER BY rand() LIMIT 0,1") or die(mysql_error()); while($row = mysql_fetch_array($foresp)) { $id = $row["id"]; $citat = $row["citat"];
echo"$citat";
$lastcitat = $id;
session_register("lastcitat"); } }
Jeg har sat en session således at man kan kontrollere at det samme citat ikke bliver vist 2 gange i streg!
I dette særtema ser vi på, hvordan cloud og AI bliver fundamentet for virksomhedernes digitale forretning, og hvordan de nye muligheder for automatisering og forretningsværdi kan udnyttes uden at miste overblik, sikkerhed og menneskelig kontrol.
Jeg har en gammel idé på dette område (jeg kan ikke huske om du har set den - du har da vist spurgt om det før):
Tæl hvor mange gange hvert citat er vist, vælg det citat (et af de citater) der har været vist færrest gange, og tæl antallet op. Det er ikke random for den enkelte, men er der blot lidt besøg på siden, så virker det fint.
Ellers er det vist noget med en ændret rand() funktion i MySql i de nyere versioner.
Og så ved oprettelse af nye skal du sætte count lig med den mindste af de eksisterende. Som du kan forstå er det mere en idé - jeg har aldrig haft brug for at prøve.
Problemet med den beskrevne algoritme er blot at: Hvis citaterne har været vist sån' cirka 100 gange hver, og du så lægger et ny citat i databasen, så vil dette blive vist hver eneste gang de næste 100 gange.
nielle: elskermad.dk ønsker at trække et tilfældigt citat ud af db'en og har problemer med at den kan vise post 1 20 gange i træk, hvilket jo næppe er særligt tilfældigt! Årsagen til dette er, ifølge MySQL.com, at RAND() funktionen skal seedes i nyere versioner af MySQL, hvorfor den her fodres med med NOW() som seed, hvilket giver "mere tilfældige" citater og problemet er løst.
tipsen-> Problemet er *ikke* løst, hvis ikke man husker hvad det forrige citat var og så prøver igen hvis man tilfældigvis trækker det samme (uanset at man måtte bruge en "mere tilfældig" random funktion).
Forresten skal min pseudokode lige justeres sådan at man husker det nye citat:
Max_ID = Resultat af "SELECT count(*) FROM Citater" Nyt_ID = Gammelt_ID
do while Nyt_ID=Gammelt_ID Nyt_ID = random(Max_ID) loop
nielle: Hvorfra stammer dit påståede problem - det fremgår ikke af spørgsmålet så vidt jeg kan se!?
Det jeg mener at kunne se er at elskermad.dk ikke er tilfreds med at MySQL "tilfældigt" udvælger citat 1 adskillige gange i træk, hvilket skyldes den måde RAND() funktionen fungerer på efter v. 3.23.54 af MySQL. Dette problem er løst i den SQL-query jeg har skrevet ovenfor i en kommentar.
tipsen-> Overskriften på spørtgsmålet var da vist "random, men ikke den samme 2 gange i streg". Derfor!
Det kommer selvfølgeligt an på hvor religøs man er med om det samme citat *ikke* må komme to gange i træk. Selv ville jeg synes at det var lidt kikset (men selvfølgeligt mindre kikset end hvis det kom 20 gange i træk!); Faktisk ville jeg kalde det for sløset programering.
brug af rand() har det gammelkendte problem, at det er langsomt, og tager tid proportionalt med længden af tabellen. Det gør min "metode" også, med mindre man husker at gøre tællefeltet indexeret. Det er så ikke lige afprøvet, men skulle gøre det muligt at få konstant tid opdatering og aflæsning.
nielle: Jeg havde ikke læst overskriften - så ok! Jeg mener så det er begrænset, hvor meget tid man skal bruge på at løse sådan et problem - og også hvor lang server-tid funktionaliteten må bruge hver gang en side requestes - det er i mine øjne irrelevant om et citat vises to gange i træk - sålænge det stadig er tilfældigt!
Erik: Det med lineær kompleksitet havde jeg ikke overvejet, men det er selvfølgelig rigtigt...
...og hvis der oveni er det krav at der ikke må komme samme citat to gange i træk, så husk det første citat i en sessionvariabel, træk ikke et men to citater ud (med lavest tæller), og hvis det første er det samme som i den sessionvariabel, så tager man den anden.
Jeg må se at få det testet en dag ... !!
Nellie: du udnytter i dit script, at der ikke er huller i ID-erne, og det kan der sagtens være når man begynder at slette citater. Derfor dur det ikke.
En ny funktion der i stedet benytter php's rand-funktion:
function randomcitat() { $res = mysql_query("SELECT COUNT(*) FROM mamster_citat WHERE id <> '$_SESSION[lastcitat]'") or die(mysql_error()); $antal = mysql_result($res,0); mysql_free_result($res); if ($antal > 0) { $rndnum = mt_rand(0, $antal-1); $res = mysql_query("SELECT id, citat FROM mamster_citat WHERE id != '$_SESSION[lastcitat]' LIMIT $rndnum, 1") or die(mysql_error()); list($id, $citat) = mysql_fetch_row($res); } }
Der er så mulighed for at få 2 identiske citater i træk, men hvis man slår med terninger, kan man jo også få 2 seksere i træk!
Erik: Kan du umiddelbart se nogle problemer med denne metode? (Nu er tiden konstant - jeg ved så bare ikke om den er for langsom...)
Så snart du har en where på har mysql svært ved at finde din limit xxx,1 fordi den skal "alt" igennem. Drop where betingelsen og skriv limit xxx,2 og lav testet derefter. JEg er ikke helt på det rene med hvilke optimeringer der kan eller ikke kan udføres, men på denne måde burde mysql være en lille smule hurtigere.
uh ha, kan se at I er lidt uenige om hvordan det skal laves, og jeg er ikke nok inde i mysql til at kunne gennemskue hvilken måde jeg skal vælge for at få den hurtigste metode (hvis et citat kommer 2 gange i streg en enkel gang imellem sker der ikke noget ved det!)
Erik: Det var vist også en hjerneblødning fra min side - det var meningen at det skulle være en "ren" løsning - dvs. uden det pjat med at huske sidste citat! Dvs. følgende var hvad jeg mente:
function RandomQuote() { $res = mysql_query('SELECT COUNT(*) FROM mamster_citat') or die(mysql_error()); $antal = mysql_result($res,0); mysql_free_result($res); if ($antal > 0) { $rndnum = mt_rand(0, $antal-1); $res = mysql_query('SELECT citat FROM mamster_citat LIMIT $rndnum, 1') or die(mysql_error()); return mysql_result($res, 0); } else { return 'Intet citat fundet!'; } }
I could prove God statistically. George Gallup The last good thing written in C++ was the Pachebel Canon. Jerry Olson Problems cannot be solved at the same level of awareness that created them. Albert Einstein (1879-1955) Multimedia? As far as I'm concerned, it's reading with the radio on! Rory Bremner
Det er kun første gang det tager *rigtig* lang tid >10 sek. hvilket er *for* lang tid for mig...
Det tog 16sek at hente ca. 100k og det er vist ikke min forbindelse der er flaskehalsen - min pointe er bare, at det er for længe og for meget data - specielt baggrunden tilter...
Har lige testet med baggrunden og pga. dens udseende kan du gemme den i meget lav kvalitet uden at se kvalitetstab - det er fra 61kb -> 10kb!
det kan du nu igen, det er pga den kører lokalt på min egen computer, og den har været slukket nogle timer!!
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.