views:

77

answers:

5

Hi

Is there is any way to avoid duplication in random number generation .

I want to create a random number for a special purpose. But it's should be a unique value. I don't know how to avoid duplicate random number

ie, First i got the random number like 1892990070. i have created a folder named that random number(1892990070). My purpose is I will never get that number in future. I it so i have duplicate random number in my folder.

+3  A: 

A random series of number can always have repeated numbers. You have to keep a record of which numbers are already used so you can regenerate the number if it's already used. Like this:

$used = array(); //Initialize the record array. This should only be done once.

//Do like this to draw a number:
do {
  $random = rand(0, 2000);
}while(in_array($random, $used));
$used[] = $random; //Save $random into to $used array

My example above will of course only work across a single page load. If it should be static across page loads you'll have to use either sessions (for a single user) or some sort of database (if it should be unique to all users), but the logic is the same.

Emil Vikström
Asymptotically, this makes random number generation an O(n) operation for each call. If you'll only be generating a small amount that's fine, but if you're going to be reaching anywhere near the limits of your domain, it is much better to shuffle the domain instead (assuming your domain is small enough to fit in memory).
Adrian Petrescu
Adrian, yes, good you pointed that out. For a large number of used numbers you can also save it like "$used[$random] = true" and use "isset($used[$random])" in the while loop. This will be a faster operation than searching through the entire array. It's not always a good idea to shuffle the domain either, at least not if it's a really large domain (e.g. 0-INT_MAX).
Emil Vikström
A: 

This will generate a string with one occurence of each digit:

$randomcharacters = '0123456789';
$length = 5;
$newcharacters = str_shuffle($randomcharacters);
$randomstring = substr($newcharacters, 0, $length);
Lekensteyn
Char 0 through 12 on a 10 char string? (Also, `$newcharacters` is never used.)
jensgram
I've added the alphabet to this, and removed when I saw 'numbers only'.
Lekensteyn
A: 

For what purpose are you generating the random number? If you are doing something that generates random "picks" of a finite set, like shuffling a deck of cards using a random-number function, then it's easiest to put the set into an array:

$set = array('one', 'two', 'three');

$random_set = array();

while (count($set)) {
    # generate a random index into $set
    $picked_idx = random(0, count($set) - 1);
    # copy the value out
    $random_set []= $set[$picked_idx];
    # remove the value from the original set
    array_splice($set, $picked_idx, 1);
}

If you are generating unique keys for things, you may need to hash them:

# hold onto the random values we've picked
$already_picked = array();

do {
    $new_pick = rand();
# loop until we know we don't have a value that's been picked before
} while (array_key_exists($new_pick, $already_picked));

$already_picked[$new_pick] = 1;
amphetamachine
+1  A: 

You can write a wrapper for mt_rand which remembers all the random number generated before.

function my_rand() {
        static $seen = array();
        do{                                                                                                                                                                                                    
                $rand = mt_rand();
        }while(isset($seen[$rand]));
        $seen[$rand] = 1;
        return $rand;
}
codaddict
A: 

The ideas to remember previously generated numbers and create new ones is a useful general solution when duplicates are a problem.

But are you sure an eventual duplicate is really a problem? Consider rolling dice. Sometimes they repeat the same value, even in two sequential throws. No one considers that a problem.

If you have a controlled need for a choosing random number—say like shuffling a deck of cards—there are several approaches. (I see there are several recently posted answer to that.)

Another approach is to use the numbers 0, 1, 2, ..., n and modify them in some way, like a Gray Code encoding or exclusive ORing by a constant bit pattern.

wallyk