Dwa sposoby na zrobienie tego, które mogę wymyślić z czubka głowy:
Opcja 1:Wypełnij nową tablicę wartościami kluczy ze zbioru danych, gdzie waga określa, jak często element jest powtarzany. Proporcja w tej tablicy odpowiada następnie rozkładowi ważonemu. Po prostu chwyć za pomocą $arr[array_rand($arr)]
. Chociaż jest to proste i łatwe do zrozumienia, to eksploduje ci w twarz, jeśli jest DUŻO przedmiotów lub jeśli wartości wagi są naprawdę wysokie.
$weighted = array();
foreach($items as $item) {
array_merge($weighted, array_fill(0, $item['weight'], $item['value']);
}
$result = $weighted[array_rand($weighted)];
Opcja 2. Zsumuj wagi. Wybierz losową liczbę od 0 do sumy wag. Zapętlaj elementy w zbiorze danych, porównaj z wybraną liczbą losową. Jak tylko trafisz na taki, który jest równy lub większy od losowego indeksu, wybierz ten element.
function findRandomWeighted(array $input) {
$weight = 0;
// I'm assuming you can get the weight from MySQL as well, so this loop really should not be required. In that case $weight becomes a parameter.
foreach($items as $item) {
$weight += $item['weight'];
}
$index = rand(1, $weight);
foreach($items as $item) {
$index -= $item['weight'];
if($index <= 0) { return $item['value'] }
}
return null;
}
Po naszej rozmowie w komentarzach poniżej, oto Pastebin z zawartym w nim kodem: