<?php
/*********************************
RandomLib Version 1.4
Programmed by : Chao Xu(Mgccl)
E-mail : mgcclx@gmail.com
Website : http://mgccl.com
Info : Please email me if there is any feature you want
or there is any bugs. I will fix them as soon as possible.
Change :
1.4
Small bug fix in bcrand() and speed improvement
1.3
Add the rand() method, it choses which random method to be used
on generate random numbers.
1.2
Add truerand(), get a random number from http://www.random.org
1.1
Add some BC functions and the power of generate
very large random numbers
ToDo :Speed improvements for large inputs
*********************************/
class random{
var $data = array();
var $rand_op = 'rand';
function rand($min = 0, $max = 1, $amount = 1){
if($this->rand_op=='rand'){
if($amount == 1){
return rand($min, $max);
}else{
$i = 0;
while($i< $amount){
$rand[] =rand($min, $max);
++$i;
}
return $rand;
}
}elseif($this->rand_op=='mt_rand'){
if($amount == 1){
return mt_rand($min, $max);
}else{
$i = 0;
while($i< $amount){
$rand[] =mt_rand($min, $max);
++$i;
}
return $rand;
}
}elseif($this->rand_op=='truerand'){
return $this->truerand($min, $max, $amount);
}
}
function add($string,$weight=1){
$this->data[] = array('s' => $string, 'w' => $weight);
}
function optimize(){
foreach($this->data as $var){
if($new[$var['s']]){
$new[$var['s']] += $var['w'];
}else{
$new[$var['s']] = $var['w'];
}
}
unset($this->data);
foreach($new as $key=>$var){
$this->data[] = array('s' => $key, 'w' => $var);
}
}
function select($amount=1){
if($amount == 1){
$rand = array_rand($this->data);
$result = $this->data[$rand]['s'];
}else{
$i = 0;
while($i<$amount){
$result[] = $this->data[array_rand($this->data)]['s'];
++$i;
}
}
return $result;
}
function select_unique($amount=1){
if($amount == 1){
$rand = array_rand($this->data);
$result = $this->data[$rand]['s'];
}else{
$rand = array_rand($this->data, $amount);
foreach($rand as $var){
$result[] = $this->data[$var]['s'];
}
}
return $result;
}
function select_weighted($amount=1){
$count = count($this->data);
$i = 0;
$max = -1;
while($i < $count){
$max += $this->data[$i]['w'];
++$i;
}
if(1 == $amount){
$rand = $this->rand(0, $max);
$w = 0; $n = 0;
while($w <= $rand){
$w += $this->data[$n]['w'];
++$n;
}
$key = $this->data[$n-1]['s'];
}else{
$i = 0;
while($i<$amount){
$random[] = $this->rand(0, $max);
++$i;
}
sort($random);
$i = 0;
$n = 0;
$w = 0;
while($i<$amount){
while($w<=$random[$i]){
$w += $this->data[$n]['w'];
++$n;
}
$key[] = $this->data[$n-1]['s'];
++$i;
}
}
return $key;
}
function bc_select_weighted($amount=1){
$count = count($this->data);
$i = 0;
$max = -1;
while($i < $count){
$max = bcadd($this->data[$i]['w'],$max);
++$i;
}
if(1 == $amount){
$rand = $this->bcrand(0, $max);
$w = 0; $n = 0;
while(bccomp($w,$rand) == 0||bccomp($w,$rand)== -1){
$w = bcadd($this->data[$n]['w'],$w);
++$n;
}
$key = $this->data[$n-1]['s'];
}else{
$i = 0;
while($i<$amount){
$random[] = $this->bcrand(0, $max);
++$i;
}
natsort($random);
$i = 0;
$n = 0;
$w = 0;
while($i<$amount){
while(bccomp($w,$random[$i]) == 0||bccomp($w,$random[$i])== -1){
$w = bcadd($this->data[$n]['w'],$w);
++$n;
}
$key[] = $this->data[$n-1]['s'];
++$i;
}
}
return $key;
}
function select_weighted_unique($amount=1){
if($amount == 1){
return $this->select_weighted(1);
}
$count = count($this->data);
$i = 0;
if($amount >= $count){
while($i < $count){
$return[] = $this->data[$i]['s'];
++$i;
}
return $return;
}else{
$max = -1;
while($i < $count){
$max += $this->data[$i]['w'];
++$i;
}
$i = 0;
while($i < $amount){
$max -= $sub;
$w = 0;
$n = 0;
$num = $this->rand(0,$max);
while($w <= $num){
$w += $this->data[$n]['w'];
++$n;
}
$sub = $this->data[$n-1]['w'];
$key[] = $this->data[$n-1]['s'];
array_splice($this->data, $n-1, 1);
++$i;
}
return $key;
}
}
function bc_select_weighted_unique($amount=1){
if($amount == 1){
return $this->bc_select_weighted(1);
}
$count = count($this->data);
$i = 0;
if($amount >= $count){
while($i < $count){
$return[] = $this->data[$i]['s'];
++$i;
}
return $return;
}else{
$max = -1;
while($i < $count){
$max = bcadd($this->data[$i]['w'],$max);
++$i;
}
$i = 0;
while($i < $amount){
$max = bcsub($max,$sub);
$w = 0;
$n = 0;
$num = $this->bcrand(0,$max);
//BCCOMP!!!!!!
while(bccomp($w,$num) == 0 || bccomp($w,$num) == -1){
$w = bcadd($this->data[$n]['w'],$w);
++$n;
}
$sub = $this->data[$n-1]['w'];
$key[] = $this->data[$n-1]['s'];
array_splice($this->data, $n-1, 1);
++$i;
}
return $key;
}
}
function bcrand($min, $max) {
bcscale(0);
if(bccomp($max,$min)!=1) return 0;
$t = bcsub($max,$min);
$l = strlen($t);
for($n=0,$r='';$n<$l;$n+=9){
$e = (string) $this->rand(0,999999999);
$r .= str_pad($e , 9, '0', STR_PAD_LEFT);
}
$r = substr($r,0,$l);
while(bccomp($r,$t)==1) $r = substr($r,1,$l).$this->rand(0,9);
return bcadd($r,$min);
}
function truerand($min, $max, $amount=1){
if($amount == 1){
$fp = fopen("http://www.random.org/cgi-bin/randnum?num=".$amount."&min="."$min"."&max="."$max"."&col=1", "r");
$num = fread($fp, 4096*$amount);
fclose($fp);
return $num;
}else{
if($amount > 10000){
return false;
}
$fp = fopen("http://www.random.org/cgi-bin/randnum?num=".$amount."&min="."$min"."&max="."$max"."&col=1", "r");
$num = fread($fp, 4096*$amount);
fclose($fp);
$num = explode("\n", $num);
unset($num[count($num)-1]);
return $num;
}
}
}
?>
|