2011-01-07 3 views
2

Можно создать дубликат:
Generating random results by weight in PHP?Случайные взвешенный выбор события

я сделал базу данных, в которой я хранить имя и ссылку на RSS feeds.i сделали RSS читатель, и все в порядке до сих пор. Я хочу сделать скроллер новостей, который покажет статьи в фидах. Но я хочу дать кормам некоторые значения веса, чтобы каждый фид выбирался в соответствии с его значением для меня и автоматически когда фид выбран из тех, что указаны в базе данных, его статьи o nly будет показан в скроллере. Все идеи о том, как я могу это сделать ??? Спасибо заранее.

p.s. моя проблема в том, как я могу сделать aytomatically случайный взвешенный выбор каналов из базы данных , а не как показать статьи в фидах (я сделал эту часть).

ответ

6

Два способа сделать это, что я могу думать с верхней части моей головы:

Вариант 1: Наполните новый массив с ключевыми значениями из набора данных, где вес определяет, как часто элемент повторяется. Затем пропорция в этом массиве соответствует взвешенному распределению. Просто возьмите с собой $arr[array_rand($arr)]. Хотя это просто и легко понять, это будет взрываться в вашем лице, если есть много предметов или если значения веса действительно высоки.

$weighted = array(); 
foreach($items as $item) { 
    array_merge($weighted, array_fill(0, $item['weight'], $item['value']); 
} 
$result = $weighted[array_rand($weighted)]; 

Вариант 2. Сумма весов. Выберите случайное число между 0 и суммой весов. Перебирайте элементы в наборе данных, сравните их с выбранным случайным числом. Как только вы нажмете тот, который равен или больше, чем случайный индекс, выберите этот элемент.

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; 
} 

После нашего разговора в комментариях ниже, вот Pastebin с кодом в нем:

http://pastebin.com/bLbhThhj

+0

+1 Второй вариант, вероятно, будет быстрее и, возможно, будет проще реализовать. – ughoavgfhw

+0

Нет, в базе данных не будет много записей. 10 каналов в лучшем случае ... У db есть только 3 поля. Ид, имя фида, URL-адрес фида. Честно говоря, я не понимаю первое решение, которое вы Мне это очень понравилось. Я попробую второй в качестве первого подхода. Я не профессионал в php, и мне это кажется легче. Спасибо! – olaf36

+0

Привет, user566487 - что делает первый пример: если у вас есть такой массив, как этот '$ feeds = array (array ('value' => 'Feed 1', 'weight' => 2), array ('value' => 'Feed 2', 'weight' => 1), array ('value' => 'Feed 3', 'weight' => 5)) ', он создает дополнительный массив, например:' array ('Feed 1', ' «Подача 1», «Подача 2», «Подача 3», «Подача 3», «Подача 3», «Подача 3», «Подача 3»); «Каждый элемент вставлен так часто, как показывает его вес. Затем вы можете просто вытащить случайный вариант, используя array_rand(), и он будет случайным в соответствии с указанными вами весами. Но если вы считаете, что второе проще, используйте его как можно лучше :) – kander

0

Вы можете найти быстрый алгоритм реализован и описан - weighted random (в JavaScript, но может быть переписываюсь на PHP за несколько минут, я думаю). Это намного быстрее, чем цикл через массив.

+0

Вы не должны просто указывать ссылку на другой сайт в качестве ответа, так как сайт может устареть в будущем. Вместо этого нажмите ссылку «изменить» в этом ответе и включите в нее основные части решения с этой страницы. См .: http://meta.stackexchange.com/q/8259 –

Смежные вопросы