День добрый, уважаемые форумчане! Столкнулся с такой задачей: Например, у нас есть 4 предмета(может быть сколько угодно) и их цена 1 - 5p 2 - 10p 3 - 5p 4 - 10p Задача стоит такая, выбрать отсюда предметы таким образом, чтобы они удовлетворяли условию: сумма выбранных предметов = 30%(+-5% (например) от общей суммы предметов. В данном случае возможны такие комбинации: 1,3 и 2. ( В приоритете комбинация с меньшим кол-ов предметов) Т.е нужно получить максимально близкую к N% от общей суммы комбинацию предметов. Кто нибудь сталкивался с подобными алгоритмами? Есть примеры решения/алгоритмов?
1. Считаешь общее кол-во предметов - 40, хранишь в переменной. Условно в переменной "А" 2. Выбираешь значение, допустим 2, т.е. 10. 3. Вычисляешь процент от 40, т.е. сколькими процентами является 10 от 40, получаешь 25, хранишь в переменной, условно в "B". Вычисление процентов на php: http://www.php.su/forum/topic.php?forum=71&topic=6520 4. Пишешь проверку: Если переменная "B" меньше 36 и больше 24, тогда Что-то
Да, спасибо большое) поглядел алгоритмы, задача походит на задачу о ранце(в моем случае вес=цене), а если точнее то это скорей задача о суммах подмножеств Вот только с ее реализацией на php все как-то не очень, попробовал прогнать через алгоритм задачи о ранце и задачи о суммах подмн., до 20 предметов считает быстро, 40 - уже медленно (7-10 сек), на 50 зависает В моем случае будет в районе 100 предметов, боюсь не дождусь результата Даже не знаю, что теперь делать (а точнее, в чем проблема скорости? алгоритма или php?)
Забыл совсем, вот, одна из реализаций задачи о рюкзаке (w - вес, v - цена, uid - это уже моя доп.инфа) Для 20 считает ещё более-менее, дальше - хуже Код (PHP): <?php define('COMMISSION', '10'); // (%) от общей суммы предметов // генерируем тестовые наборы for ($i = 0; $i < 20; $i++) { $num = rand(5, 50)/2; $data[] = ['w' => $num, 'v' => $num, 'uid' => rand(65479, 65499)]; $solution[] = -1; } // сортировка по убыванию usort($data, "customSort"); function customSort($a, $b) { return $a['w'] < $b['w']; } $totalSum = array_sum(array_column($data, 'v')); /* * n: number of items * content: the maximum content of the knapsack */ function knapsack($n, $content) { global $data; global $solution; if ($n == 0 || $content == 0) { return 0; } else { for ($i = $n - 1; $i >= 0; $i--) { if ($data[$i]['w'] > $content) { $solution[$i] = 0; return knapsack($n - 1, $content); } else { if (($data[$i]['v'] + knapsack($n - 1, $content - $data[$i]['w'])) > knapsack($n - 1, $content)) { $solution[$i] = 1; return $data[$i]['v'] + knapsack($n - 1, $content - $data[$i]['w']); } else { $solution[$i] = 0; return knapsack($n - 1, $content); } } } } } $comis = COMMISSION * $totalSum / 100; printf('You need to take things to the amount %s<br>', $comis); $maxvalue = knapsack(20, $comis); $sum = 0; for ($i = 0; $i < 20; $i++) { if (1 == $solution[$i]) { printf("Item %d is selected.", $i); printf("{value : %d,weight : %d, uid: %d}", $data[$i]['v'], $data[$i]['w'], $data[$i]['uid']); echo "<br>"; $sum += $data[$i]['v']; } } printf("Sum: %s, TotalSum: %s This %s percent<br>", $sum, $totalSum, $sum / $totalSum * 100); printf("Maximum value is: %d", $maxvalue); ?> PHP, JavaScript, SQL и другой код пишите внутри тегов Код ( (Unknown Language)): [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]