在數據庫中,我有一個不同包的價目表,每個包至少包含以下產品之一:照片,平面圖,EPC。示例(ID |標題|價格):算法:最便宜的產品包組合
12 Photo 10.00
13 EPC 20.00
14 Floor Plan 20.00
15 4 Photos 40.00
16 4 Photos + EPC 55.00
17 4 Photos + Floor Plan 55.00
18 4 Photos + Floor Plan + EPC 75.00
etc...
現在我無法理解我如何總能確定最便宜的套餐組合。例如,如果我想要5張照片和一張平面圖,那麼項目17 + 12的組合將比組合5x12和14(70.00)更便宜(65.00)。 我已經將價目表轉換爲下列數組,並將其傳遞給我的算法嘗試,但它失敗了......任何人都可以將我推向正確的方向嗎?
Array
(
[12] => Array
(
[price] => 10.00
[items] => Array
(
[0] => 1 // photo
[1] => 0 // floor plan
[2] => 0 // epc
)
)
[13] => Array
(
[price] => 20.00
[items] => Array
(
[0] => 0 // photo
[1] => 0 // floor plan
[2] => 1 // epc
)
)
[14] => Array
(
[price] => 20.00
[items] => Array
(
[0] => 0 // photo
[1] => 1 // floor plan
[2] => 0 // epc
)
)
[15] => Array
(
[price] => 40.00
[items] => Array
(
[0] => 4 // photo
[1] => 0 // floor plan
[2] => 0 // epc
)
)
[16] => Array
(
[price] => 60.00
[items] => Array
(
[0] => 4 // photo
[1] => 0 // floor plan
[2] => 1 // epc
)
)
etc...
)
取景器:
class CombinationFinder {
private $products = array();
public function __construct($products) {
$this->products = $products;
// sort by overall amount of items
uasort($this->products, function ($a, $b) {
$sum_a = array_sum($a['items']);
$sum_b = array_sum($b['items']);
if ($sum_a == $sum_b) {
return 0;
}
return $sum_a < $sum_b ? -1 : 1;
});
}
private function intersect($combo, $purchased) {
return array_map(function ($a, $b) {
$result = $b-$a;
return $result < 0 ? 0 : $result;
}, $combo, $purchased);
}
private function possibility($purchased, $limit) {
$price = 0;
$combination = array();
foreach($this->products as $pid => $combo) {
// if adding this combo exceeds limit, try next combo
if($price + $combo['price'] >= $limit) {
continue;
}
// see if combo helps
$test = $this->intersect($combo['items'], $purchased);
if(array_sum($test) === array_sum($purchased)) {
continue;
}
// add combo and deduct combo items
$combination[] = $pid;
$price += $combo['price'];
$purchased = $test;
// if purchased items are covered, break
if(array_sum($purchased) === 0) {
return array('price' => $price, 'combination' => $combination);
}
}
return false;
}
public function getCheapest($photos, $floorplans, $epc) {
$purchased = array((int)$photos, (int)$floorplans, (int)$epc);
$limit = 9999;
while($test = $this->possibility($purchased, $limit)) {
$limit = $test['price'];
$possibility = $test;
}
sort($possibility['combination'], SORT_NUMERIC);
echo 'Cheapest Combination: '.implode(', ', $possibility['combination']);exit;
}
}
動態規劃的典型案例,歸結爲試驗和消除。 – 2014-11-25 04:09:15
謝謝,一直在閱讀。聽起來這可能是我需要的理論。我只是需要以某種方式應用它。 – Jonny 2014-11-25 11:30:41