Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Для профи > нужен алгоритм


Автор: olegti 1.9.2009, 17:38
Директор поставил задачку,написать алгоритм, но ничего не проходит в голову!

1.Имеем объекты со следующей ценой (цена может быть любая)
    A    33.010101
            B    25.765201
            C    13.888888
            D    05.000000
            E    00.010000
            F    17.989898
            И т.д.
2.Необходимо выбрать Random
            a.    По одному объекту
            b.    По два объекта
            c.    По три объекта
3.Частота выпадания объекта должна быть пропорциональна цене
4.Два одинаковых объекта выпадать не должны

В общих чертах - существует панел где размещенны баннеры (3 шт), у каждого баннера своя цена. Смысл в том, чтобы после обновления страницы баннеры появлялись с разной частотой, т.е. если баннер стоит 50$ - то он будет появляться чаще, чем баннер за 30$, а если он стоит 5$ - то появляться он будет на много реже!

Автор: pizzz 1.9.2009, 17:50
Цена изменяеться?

Добавлено через 32 секунды
Баннеров много?

Автор: olegti 1.9.2009, 17:57
Цитата(pizzz @ 1.9.2009,  17:50)
Цена изменяеться?

Добавлено @ 17:50
Баннеров много?

да, цена меняется!

а по поводу баннеров, в самой понели их 3 штуки, а появляться будут больше, но по очереди, после каждого обновления страницы!

Автор: pizzz 1.9.2009, 18:12
Сумбурно... Но извините уже рабочий день закончен.

Получаем сумму цены всех банера из базы.
делим ее например на 0.1 (можно на 1) это будет СРЕДНЕЕ

теперь создаем пустой массив

Теперь заполняем этот массив. Ключи числа. Значения ид домена. Количество элементов в массиве для 1 банера = денег за банер /  на СРЕДНЕЕ

(То есть получаеться например 2 банера, один 30, второй 70. в итоге получаем такой массив: 
$a[0] = 'баннер 1';
$a[1] = 'баннер 1';
...
$a[29] = 'баннер 1';
$a[30] = 'баннер 1';
$a[31] = 'баннер 2';
$a[32] = 'баннер 2';
...
$a[99] = 'баннер 2';
$a[100] = 'баннер 2';
)

теперь получаем случайное число от 0 до количество элементов массива. Подставляем в ключ массива и получаем ид баннера.

Добавлено через 1 минуту и 54 секунды
Ошибся

Добавлено через 6 минут
Идея понятна? Чет вобше не думаеться...

Автор: solenko 1.9.2009, 18:19
Код

<?php
function doSelection() {
$banners = array(
    10,
    11,
    20,
    100,
);

$max = max($banners);

$weight = array();
foreach ($banners as $price) {
    $weight[] = $price/$max;
}

asort($weight);
$r = rand(0,100)/100;
$selected = 0;
while ($r > $weight[$selected]) {
  ++$selected;
}

echo 'Selected price is ',$weight[$selected]*$max,PHP_EOL;
}

for ($i=0;$i<20;$i++) {
    doSelection();
}


В простейшем виде что-то вроде этого. Частотой управлять можно изменяя расчет веса (например, возьмете квадраты и разница увеличится)

Автор: pizzz 1.9.2009, 18:51
solenko,  решил провести тест. И вот что он показал:

Array
(
    [60] => 66331
    [70] => 10895
    [80] => 10911
    [90] => 11863
)

Array
(
    [60] => 66339
    [70] => 10893
    [90] => 11879
    [80] => 10889
)

Array
(
    [60] => 66330
    [80] => 10905
    [70] => 10889
    [90] => 11876
)

Array
(
    [90] => 11885
    [80] => 10887
    [70] => 10878
    [60] => 66350
)

Array
(
    [60] => 66347
    [80] => 10886
    [90] => 11889
    [70] => 10878
)

Сам код:

Код

<?php
function doSelection() {
$banners = array(
    60,
    70,
    80,
    90,
);

$max = max($banners);

$weight = array();
foreach ($banners as $price) {
    $weight[] = $price/$max;
}

asort($weight);
$r = rand(0,100)/100;
$selected = 0;
while ($r > $weight[$selected]) {
  ++$selected;
}

return $weight[$selected]*$max;
}
$a = array();
for ($i=0;$i<100000;$i++) {
    $t = doSelection();
    if(isset($a[$t])) $a[$t]++; else $a[$t] = 1;
}
echo "<pre>";
print_r($a);


Что то нето...

Добавлено через 1 минуту и 7 секунд
Сейчас напишу свой вариант, и проведу так же тесты smile

Автор: pizzz 1.9.2009, 19:12
А вот мои результаты smile

Array
(
    [80] => 26685
    [60] => 19981
    [70] => 23343
    [90] => 29991
)

Array
(
    [90] => 30008
    [80] => 26677
    [70] => 23304
    [60] => 20011
)

Array
(
    [90] => 30008
    [80] => 26688
    [70] => 23302
    [60] => 20002
)

Array
(
    [40] => 8662
    [80] => 17318
    [90] => 19473
    [70] => 15156
    [50] => 10823
    [60] => 12970
    [15] => 3239
    [12] => 2614
    [30] => 6499
    [14] => 3030
    [1] => 216
)

сам код 
Код

<?php
function doSelection() {
    $banners = array(60, 70, 80, 90);

    $a = array();
    foreach ($banners AS $k => $v) {
        $i = 0;
        while($v>$i) {
            $a[]=$k;
            $i++; 
        }           
    }               
    return $banners[$a[rand (0, count($a)-1)]];    
}
$a = array(); 
for ($i=0;$i<100000;$i++) {
    $t = doSelection();
    if(isset($a[$t])) $a[$t]++; else $a[$t] = 1;
}
echo "<pre>";
print_r($a);


Автор: Akina 1.9.2009, 19:13
Стоимость баннеров конвертируем в смежные диапазоны, например

Исходный массив стоимостей: баннер1=20, баннер2=50, баннер3=5
Массив диапазонов: баннер1=0..20, баннер2=21..70, баннер3=71..75

Теперь осталось взять rand(0, 75) и посмотреть, какой баннер выводить.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)