PHP ağırlık olarak rastgele sonuçlar oluşturuluyor?

7 Cevap php

Ben PHP rastgele bir sayı üretmek için nasıl biliyorum ama 1-10 arasında rastgele bir sayı istiyoruz diyelim ama daha 3,4,5 'nin ardından 8,9,10' s istiyorum. Bu nasıl mümkün olur? Ben denedim ne gönderebilir ama dürüst olmak gerekirse, ben bile nerede başlar bilmiyorum.

7 Cevap

Dayanarak @ Allain adlı answer / link, PHP bu hızlı işlevini çalıştı. Olmayan tamsayı ağırlık kullanmak istiyorsanız bunu değiştirmek zorunda olacak.

  /**
   * getRandomWeightedElement()
   * Utility function for getting random values with weighting.
   * Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50)
   * An array like this means that "A" has a 5% chance of being selected, "B" 45%, and "C" 50%.
   * The return value is the array key, A, B, or C in this case.  Note that the values assigned
   * do not have to be percentages.  The values are simply relative to each other.  If one value
   * weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66%
   * chance of being selected.  Also note that weights should be integers.
   * 
   * @param array $weightedValues
   */
  function getRandomWeightedElement(array $weightedValues) {
    $rand = mt_rand(1, (int) array_sum($weightedValues));

    foreach ($weightedValues as $key => $value) {
      $rand -= $value;
      if ($rand <= 0) {
        return $key;
      }
    }
  }

Ölçeğin bir ucuna doğru sürekli eğri etkili bir rasgele sayı için:

  • 0 arasında sürekli bir rasgele sayı seç .. 1
  • Önyargı bunu için, bir güç γ yükseltmek. 1 ağırlıksız olduğunu, alt tersi daha yüksek sayıların daha verir ve
  • İstediğiniz aralığı ve tamsayı tura Ölçek

örn. PHP (denenmemiş):

function weightedrand($min, $max, $gamma) {
    $offset= $max-$min+1;
    return floor($min+pow(lcg_value(), $gamma)*$offset);
}
echo(weightedrand(1, 10, 1.5));

Bir pretty good tutorial for you var.

Temelde:

  1. Tüm sayıların ağırlıkları toplamı.
  2. Az daha rastgele bir sayı seç
  3. sonuç negatif olana kadar sırayla ağırlıkları çıkarmak ve eğer bu sayı döndürür.

Bunun için saf kesmek gibi bir liste veya bir dizi oluşturmak olacaktır

1, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10

Ve sonra o rastgele seçin.

Bu eğitimde çoklu kesme ve yapıştırma çözümleri ile, PHP, bunun üzerinden yürüyor:

http://w-shadow.com/blog/2008/12/10/fast-weighted-random-choice-in-php/

Plain and fair. Just copy/paste and test it.

/**
 * Return weighted probability
 * @param (array) prob=>item 
 * @return key
 */
function weightedRand($stream) {
    $pos = mt_rand(1,array_sum(array_keys($stream)));           
    $em = 0;
    foreach ($stream as $k => $v) {
        $em += $k;
        if ($em >= $pos)
            return $v;
    }

}

$item['30'] = 'I have more chances than everybody :]';
$item['10'] = 'I have good chances';
$item['1'] = 'I\'m difficult to appear...';

for ($i = 1; $i <= 10; $i++) {
    echo weightedRand($item).'<br />';
}

Edit: sonunda eksik dirseğini eklendi.

Ben IainMH çözümünü kullanılan beri, ben de benim PHP kodu paylaşabilir:

<pre><?php

// Set total number of iterations
$total = 1716;

// Set array of random number
$arr = array(1, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5);
$arr2 = array(0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 5);

// Print out random numbers
for ($i=0; $i<$total; $i++){

    // Pick random array index
    $rand = array_rand($arr);
    $rand2 = array_rand($arr2);

    // Print array values
    print $arr[$rand] . "\t" . $arr2[$rand2] . "\r\n";

}

?></pre>