I am wondering if the shuffle() array function is the correct way to randomize array results.
Basically, I have some ad codes in an array, and I use this to display 1 random ad each time, but there is an ad that seems to appear much much more than anything! I mean out of 20 times it appeared about 18 times. I'd thought by randomizing the results I'd get around equal views for each ad but thats not the case.
It makes me question here. Is shuffle the correct way to do this.. or do I need something totally different?
Here is my code to grab the random ad code at a time.
if (count($eligible_ads) > 1) {
shuffle($eligible_ads);
echo stripslashes($eligible_ads[0]['code']);
}
You could also simply pick a random key using array_rand, instead of shuffling the whole thing. It won't get any more random than that*. You can't say something's not random with test data based on only 20 runs. It should even out if you run it a few thousand more times.
In other words:
* As far as PRNGs go at least.
Random means Random. It wouldn't be random if it gave equal views to each ad. shuffle() randomizes the order of the elements in the array, associative or otherwise. If your goal is to give equal views to each "ad" in the array, then no, shuffle() is not what your after. You could probably write a function that uses boolean logic to give equal views though.
If you don't mind the hit of running a database query or two, throw the ads into a table, and create a column that will store how many times that ad was displayed. SELECT the row with the MIN(views) ordered by RAND() and increase the view count of the row that was selected. This will ensure every ad is viewed the same number of times, but shown in a random order.
Related
Ok, so I am a bit lost here..
I am pulling profile IDs from an sql database into an array.
i would like to then take that array and randomly pick only 25 numbers each time the array loads, then shuffle up the numbers so there is less likely a chance they will show up in the same order.
You can do this in MySQL directly:
SELECT id FROM profiles ORDER BY RAND() LIMIT 25
RAND() sorts randomly. This should be guarantee enough that "there is less likely a chance they will show up in the same order". If you have more stringent demands on randomness, like uniqueness over draws you might need a more complex solution.
shuffle($numbers);
then
array_pop ($numbers)
I have just started working on sphinx with php. Was just wondering is if i set limit to 20 records per call.
$cl->SetLimits ( 0, 20);
the index recreate is say set to 5 minutes with a --rotate option.
So if in my application i have to call the next 20 search results i call the command
$cl->SetLimits ( 20, 20);
Suppose the index is recreated in between the two setlimit calls. And say a new document is inserted with say the highest weight. (and i am sorting results by relevance.)
Wouldnt the search result shift by one position down so the earlier 20th record will now be the 21st record and so i again get the same result at the 21st position that i got in the 20th position & so my application will display a duplicate search result. Is this true..any body else got this problem.
Or how should I overcome this?
Thanks!
Edit (Note: The next setlimit command is called based on a user event say 'See more Results')
Yes, that can happen.
But usually happens so rarely that nobody notices.
About the only way to avoid it would be to store some sort of index with the query. So as well as a page number, you include a last id. Then when on the second page etc, use that id to exclude any new results created since the search started.
On the first page query, you lookup the biggest id in the index, need to run a second query for that.
(this at least copes with new additions to the index, but its harder to cope with changes to documents, but can be done in a similar way)
setLimit sets the offset on the result server side, http://php.net/manual/en/sphinxclient.setlimits.php.
So to answer your question, no, it will query the with max_matches and save a result set, from there you work with the result set and not the indexed data.
One question though, why are you indexing it every 5 minutes? It would be better just to re-index every time your data changes.
Ok so lets say I have an array that can be 0 - X large x being in the tens of thousands, I know insane notion but none the less just for the sake of how vast the array can be. What I need to do is device a function that can take a couple parameters. One would be how many numbers am I looking to sum to make the number I want to check, the next would be the number I want to check for. The next would be the array itself.
At first I figured something like array_sum() would give me a little help but thats only for totaling the entire sum of the array. What I need to do is say I either want 1 - 10 different values again for sake of example to see if this will total what I am seeking. Now its possible I could think of something up on my own if I can only figure out how to check that 1-10 concept. Its most likely only going to be 2 at any given time but I want it dynamic for potential future needs. So anyone know of an algorithm concept I can come build up to check a given array like this? I know its possible, I just can't fully wrap my head around it at 3am in the morning.
EDIT
$test_case = array(0,1,2,3,4,5,6,7,8,9,10,11,12,13);
function find_sum($totalby = 2, $expected = 0, $updown = "subtract")
{
//something here to take the total by and then check to see if expected is found
}
now what I mean to try and figure out is if any 2 numbers equal 0 when subtracted (although $updown could be "add" also for later expansion of this function. Anyway in this case scenario I should have specified if anything equals zero. Example I want to find if a 2 numbers equal zero together. Grant it Not exactly sure if my array above will find a zero result with just subtracting any 2 of the given numbers, but it expresses what type of array I am working with to holdfully achieve my goal.
Sounds like all you need is to use array_slice before using array_sum.
Something like:
function subarr_sum($array,$offset,$length) {
$newarray = array_slice($array,$offset,$length);
return array_sum($newarray);
}
In php - how do I display 5 results from possible 50 randomly but ensure all results are displayed equal amount.
For example table has 50 entries.
I wish to show 5 of these randomly with every page load but also need to ensure all results are displayed rotationally an equal number of times.
I've spent hours googling for this but can't work it out - would very much like your help please.
please scroll down for "biased randomness" if you dont want to read.
In mysql you can just use SeleCT * From table order by rand() limit 5.
What you want just does not work. Its logically contradicting.
You have to understand that complete randomness by definition means equal distribution after an infinite period of time.
The longer the interval of selection the more evenly the distribution.
If you MUST have even distribution of selection for example every 24h interval, you cannot use a random algorithm. It is by definition contradicting.
It really depends no what your goal is.
You could for example take some element by random and then lower the possibity for the same element to be re-chosen at the next run. This way you can do a heuristic that gives you a more evenly distribution after a shorter amount of time. But its not random. Well certain parts are.
You could also randomly select from your database, mark the elements as selected, and now select only from those not yet selected. When no element is left, reset all.
Very trivial but might do your job.
You can also do something like that with timestamps to make the distribution a bit more elegant.
This could probably look like ORDER BY RAND()*((timestamps-min(timestamps))/(max(timetamps)-min(timestamps))) DESC or something like that. Basically you could normalize the timestamp of selection of an entry using the time interval window so it gets something between 0 and 1 and then multiply it by rand.. then you have 50% fresh stuff less likely selected and 50% randomness... i am not sure about the formular above, just typed it down. probably wrong but the principle works.
I think what you want is generally referred to as "biased randomness". there are a lot of papers on that and some articles on SO. for example here:
Biased random in SQL?
Copy the 50 results to some temporary place (file, database, whatever you use). Then everytime you need random values, select 5 random values from the 50 and delete them from your temporary data set.
Once your temporary data set is empty, create a new one copying the original again.
I want PHP to randomly create a multi-dimensional array by picking a vast amount of items out of predefined lists for n times, but never with 2 times the same.
Let me put that to human words in a real-life example: i want to write a list of vegetables and meat and i want php to make a menu for me, with every day something else then yesterday.
I tried and all i got was the scrambling but there were always doubles :s
Try the shuffle function http://us2.php.net/manual/en/function.shuffle.php
Use either array_rand() or shuffle().
Random != unique
You need to either:
a) create a list containing every possible combination and then randomly select and remove one
or
b) store your results so your random selection can be compared to previous selections.