Home  >  Article  >  Backend Development  >  PHP implements dynamic programming knapsack problem

PHP implements dynamic programming knapsack problem

藏色散人
藏色散人forward
2019-08-13 14:22:173339browse

The reason for the incident

Because our company held an algorithm programming competition, the algorithm questions in the picture below were randomly drawn. After thinking about it for a while, I remembered that there was one in the book (Algorithm Illustration). The algorithm is more consistent with the "knapsack problem" in dynamic programming.

The knapsack problem is an NP-complete problem of combinatorial optimization. The problem can be described as: given a set of items, each item has its own weight and price, within the limited total weight, how do we choose so that the total price of the items is the highest.

How to choose the most appropriate items to place in a given backpack is consistent with our question, so this time we use the "0-1 backpack problem" and use our question this time to substitute it. "Total number of people" is equivalent to "backpack", "item" is equivalent to "work order type", and the weight of the item is the number of people required.

Supplement:

There are three extension problems of the solution to the knapsack problem: unbounded knapsack problem, 0-1 knapsack problem, and quadratic knapsack problem (without detailed extension, just We use)

The algorithm topic is as follows

PHP implements dynamic programming knapsack problem

The problem dealt with by dynamic programming is a multi-stage decision-making problem, generally starting from the initial The state starts and reaches the end state through the selection of decisions in the intermediate stages. These decisions form a decision sequence and determine an activity route to complete the entire process (usually the optimal activity route). The design of dynamic programming has a certain pattern, which generally involves the following steps.

Initial state→│Decision 1│→│Decision 2│→...→│Decisionn│→End state

Dynamic programming problem-solving formula:

f(n,m)=max{f(n-1,m),f(n-1,m-w[n])+P(n,m)}

● Horizontal m (total number of people), vertical n (type of work order made by 4 vehicles)

● f(n-1,m) ==> (Decision 1) The number of technicians corresponding to the previous work order type, and the profit of the work order

● P(n,m) ==> (Decision 2) The number of technicians corresponding to the current work order type, and the work done Single profit

● f(n-1,m-w[n]) ==> By subtracting the number of people required for the current work order, the profit for the corresponding number of people in the previous decision

PHP implements dynamic programming knapsack problem

So the answer to the optimal solution is: the corresponding value among the five technicians in decision n, 1799 yuan

PostMan submitted parameters:

people:5
carDetail[0][technician]:2
carDetail[0][amount]:49
carDetail[0][type]:全车安检
carDetail[1][technician]:2
carDetail[1][amount]:499
carDetail[1][type]:深度诊断
carDetail[2][technician]:3
carDetail[2][amount]:1300
carDetail[2][type]:二手车检测
carDetail[3][technician]:1
carDetail[3][amount]:10
carDetail[3][type]:空调专项检测

Solution one: dynamic programming

 $i)
                {
                    $cacheMap[$j][$i] = $prevGain;
                    $cacheMapName[$j][$i] = $prevName;
                }
                else
                {
                    // 剩余价值
                    if ($i-$requiredPeople >= 0) {
                        $surplusPeople = $i-$requiredPeople;
                        $surplusGain = $cacheMap[$preLine][$surplusPeople];
                        $surplusName = $cacheMapName[$preLine][$surplusPeople];
                    }else {
                        $surplusGain = 0;
                        $surplusName = '';
                    }
                    $nowTotalGain = $gain + $surplusGain;
                    $cacheMap[$j][$i] = max($prevGain, $nowTotalGain);
                    if ($prevGain > $nowTotalGain) {
                        $cacheMapName[$j][$i] = $prevName;
                    }else{
                        $cacheMapName[$j][$i] = $name.'+'.$surplusName;
                    }
                }
            }
        }
        $actual = count($postData['carDetail']);
        return [
            'maxMatch' => $cacheMap[$actual][$totalPeople],
            'maxMatchName' => trim($cacheMapName[$actual][$totalPeople],'+')
        ];
    }
}
$bestMatch = new bestMatch;
if (empty($_POST) || isset($_POST['people']) && $_POST['people'] > 0) {
    die('提交参数有误');
}
$res = $bestMatch->getMethod($_POST);
$t2 = microtime(true);
echo '动态规划: '.'
'; echo '最佳金额: '.$res['maxMatch'].'
'; echo '最佳套餐搭配: '.$res['maxMatchName'].'
'; echo '耗时'.round($t2-$t1,7).'秒'.'
' ; echo '消耗内存: ' . memory_get_usage().'字节'.'
' ;

Solution two: recursion

 0 ){
                $value['name'] = $up['name'].'+'.$array[$i]['type'];
                $value['amount'] = bcadd($up['amount'],$array[$i]['amount']);
                $value['technician'] = bcadd($up['technician'],$array[$i]['technician']);
            }else{
                $value['name'] = $array[$i]['type'];
                $value['amount'] = bcadd($array[$i]['amount'],0);
                $value['technician'] = bcadd($array[$i]['technician'],0);
            }
            $result[]  = $value;
            $this->getSortList($array,$i+1,$value,$result);
        }
        return $result ;
    }
    public function getMethod($postData)
    {
        $people = $postData['people'];
        $carDetail = $postData['carDetail'];
        $allResult = $this->getSortList($carDetail);
        $bestMatch = [];
        foreach ($allResult as $val) {
            if ($val['technician'] <= $people) {
                if ($bestMatch) {
                    if ($val['amount'] > $bestMatch['amount']) {
                        $bestMatch = $val;
                    }
                }else{
                    $bestMatch = $val;
                }
            }
        }
        return $bestMatch;
    }
}
$optimal = new optimal();
if (empty($_POST) || isset($_POST['people']) && $_POST['people'] > 0) {
    die('提交参数有误');
}
$bestMatch = $optimal->getMethod($_POST);
$t2 = microtime(true);
echo '递归查询: '.'
'; echo '最佳金额: '.$bestMatch['amount'].'
'; echo '最佳套餐搭配: '.$bestMatch['name'].'
'; echo '耗时'.round($t2-$t1,7).'秒'.'
' ; echo '消耗内存: ' . memory_get_usage().'字节'.'
' ;

The above is the detailed content of PHP implements dynamic programming knapsack problem. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.im. If there is any infringement, please contact admin@php.cn delete