2011-05-06 2 views
1

나는 가중치에 따라 많은 숫자 중에서 숫자를 선택해야하는 어플리케이션이 있습니다. 내가 선택할 때마다 결과를 flash.I에 전송했습니다. 파이썬에서 알고리즘을 발견했습니다. PHP로 구현하고 그 결과를 테스트했습니다. 내가 파이썬에서 그 알 고를 실행했다면 좋은 결과를 주지만 php에서는 좋지 않습니다. 전의. (1 => 30,2 => 40,3 => 30) 여러 번 실행 한 후에 가중치 배열에서 발생 숫자의 가능성은 항상 더 높지만 파이썬에서는 균일합니다. PHP 코드를 첨부했습니다.난수 시드하기 생성자 PHP에서

define("MAX",100000); 
$reelfrequencies=array(30,40,30); 
echo weightedselect($reelfrequencies); 
/*function weightedselect($frequency) 
{ 
    $arr=cumWghtArray($frequency);//array(35,96,100); 
    print_r($arr); 
    $len=sizeof($frequency); 
    $count=array(); 
    echo $r=mt_rand(0,$arr[$len-1]); 
    $index=binarysearch($arr,$r,0,$len-1); 
    return $index; 
}*/ 
function cumWghtArray($arr) 
{ 
    $cumArr=array(); 
    $cum=0; 
    $size=sizeof($arr); 
    for($i=0;$i<$size;$i++) 
    { 
    $cum+=$arr[$i]; 
    array_push($cumArr,$cum); 
    } 
    return $cumArr; 
} 

function weightedselect($frequency) 
{ 
    $arr=cumWghtArray($frequency);//array(35,96,100); 
    $len=sizeof($frequency); 
    $count=array(); 
    $count[0]=$count[1]=$count[2]=0; 
    for($i=0;$i<MAX;$i++) 
    { 
    $r=mt_rand(0,$arr[$len-1]); 
    $index=binarysearch($arr,$r,0,$len-1); 
    $count[$index]++; 
    } 
    for($i=0;$i<3;$i++) 
    { 
    $count[$i]/=MAX; 
    echo $i." ".$count[$i]."\n"; 
    } 
} 
function binarySearch($ar,$value,$first,$last) 
{ 
    if($last<$first) 
    return -1; 
    $mid=intVal(($first+$last)/2); 
    $a=$ar[$mid]; 
    if($a===$value) 
    return $mid; 
    if($a>$value&&(($mid-1>=0&&$ar[$mid-1]<$value)||$mid==0)) 
    return $mid; 
    else if($a>$value) 
    $last=$mid-1; 
    else if($a<$value) 
    $first=$mid+1; 
    return binarySearch($ar,$value,$first,$last); 
} 

다음은 Python 코드입니다. 이 포럼에서이 코드를 가져 왔습니다.

def cdf(weights): 
    total=sum(weights) 
    result=[] 
    cumsum=0 
    for w in weights: 
     cumsum+=w 
     result.append(cumsum/total) 
    return result 

def choice(population,weights): 
    assert len(population) == len(weights) 
    cdf_vals=cdf(weights) 
    x=random.random() 
    idx=bisect.bisect(cdf_vals,x) 
    return population[idx] 

weights=[0.30,0.40,0.30] 
population="ABC" 
counts={"A":0.0,"B":0.0,"C":0.0} 
max=10000 
for i in range(max): 
    c=choice(population,weights) 
    counts[c]=counts[c]+1 
print(counts) 
for k, v in counts.iteritems(): 
    counts[k]=v/max 
print(counts) 

문제점은 균일하지 않은에는, mt_rand() 함수이다 가져 오기 랜덤 이등분 수입 모음. python random.rand()는 매우 균일합니다. 어느 랜덤 함수가 매번 실행될 때마다 적절한 시드 값을 사용하여 PHP에서 구현해야합니다. 나는 Withcmann (python random.random에 의해 사용됨)을 사용하려고 생각 했었지만 어떻게 시드를 제공 할 것인가.

답변

2

mt_rand은 둘 다 여기에서 사용자 작업에 대해 충분히 임의적이어야합니다. mt_rand을 시드해야한다면 mt_srand을 사용할 수 있지만 PHP 4.2 이후에는 필요하지 않습니다.

코드에 문제가있는 것으로 의심됩니다. 코드에 문제가있는 것으로 의심됩니다. 귀하의 코드가 무작위로 선택된 가중치가있는 확률을 선택하는 것으로 생각됩니다.

도움이 될만한 사람 : Generating random results by weight in PHP?

+1

답장을 보내 주셔서 감사합니다. 링크가 좋다. Withmann을 사용하고 mt_rand()를 사용하여 문제를 해결했습니다. 이제 확률이 같은 숫자를 선택합니다. – cooldude

+0

도움이 된 것을 기쁘게 생각합니다! –