-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathKnapsack.php
More file actions
68 lines (64 loc) · 3.51 KB
/
Copy pathKnapsack.php
File metadata and controls
68 lines (64 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
namespace App\Chapter9;
class Knapsack
{
/**
* Задача на программирование: рюкзак
* Есть 3 или более предмета, которые можно уложить в рюкзак. Вместимость рюкзака составляет 4 фунта.
* Магнитофон - $3000, вес - 4 фунта. Ноутбук - $2000, вес - 3 фунта. Гитара - $1500, вес - 1 фунт.
* Какие предметы следует положить в рюкзак, чтобы стоимость добычи была максимальной?
*/
public function knapsack(array $weights, array $costs, int $sizePack)
{
//вычисляем шаг - это минимальный вес товара
$step = min(...array_values($weights));
//инициализируем матрицу для поиска максимальной стоимости товара
$cell = [];
$things = array_keys($weights);
foreach ($things as $i => $thing) {
for ($j = $step; $j <= $sizePack; $j += $step) {
// предыдущий максимум
$previousMax = $cell[$i - 1][$j] ?? null;
if ($weights[$thing] > $j) {
if ($previousMax) {
$cell[$i][$j] = $previousMax;
}
} else {
// стоимость оставшегося пространства
$costOfRemainingSpace = $cell[$i - 1][$j - $weights[$thing]] ?? null;
// стоимость текущего элемента
$costMaxCell = $costs[$thing];
// стоимость текущего элемента + стоимость оставшегося пространства =
// максимум стоимости ячейки, при условии того, что уже помещен в ячейку элемент
if ($costOfRemainingSpace) {
$costMaxCell = $costOfRemainingSpace['cost'] + $costs[$thing];
}
// если предыдущий максимум есть
if ($previousMax) {
// если максимум стоимости ячейки больше стоимости предыдущего элемента
// то добавляем вещь
if ($costMaxCell > $previousMax['cost']) {
$maxThings = $costOfRemainingSpace['things'] ?? null;
$maxThings[] = $thing;
$cell[$i][$j] = [
'cost' => $costMaxCell,
'things' => $maxThings,
];
} else {
// иначе добавляем максимум из предыдущей ячейки
$cell[$i][$j] = $previousMax;
}
} else {
$cell[$i][$j] = [
'cost' => $costMaxCell,
'things' => [$thing],
];
}
}
}
}
// стоимость оставшегося пространства
$result = $cell[$i][$j - $step];
return $result;
}
}