算法逻辑需要找到最佳解决方案

时间:2015-08-06 09:59:11

标签: php algorithm codeigniter logic solution

方案

  1. 可提供以下物业的车辆清单:

    vehicle1 {乘客:4,行李:2,行李箱:8}

    vehicle2 {乘客:5,行李:3,行李箱:10}

    vehicle3 {乘客:6,行李:3,行李箱:10}

    vehicle4 {乘客:8,行李:4,行李箱:10}

  2. 现在,如果用户要求(13名乘客,6个行李箱,15个行李箱)旅行,那么最有效的车辆结果将是:

    vehicle2 + vehicle4

  3. 问题定义: 我已经能够开发出一个流量/算法(但只有乘客数量),但当乘客/行李箱/行李箱数量超过3辆或更多车辆的需求时,我无法为它开发算法。

    代码:

    function ajax_getVehicles() {
    
        $vehicleType = $_POST['vehicle_type'];
        $passengers = intval($_POST['passengers']);
        $luggage = intval($_POST['luggage']);
        $suitcases = intval($_POST['suitcases']);
    
        $requiredVehicles = array();
    
        // 1. Check if all passengers fit in a single car
        if (!$requiredVehicles) {
            $vehicle = $this->common_model->get_where('fleets', array('vehicle_type' => $vehicleType, 'passengers >=' => $passengers), 'passengers ASC');
            if ($vehicle)
                array_push($requiredVehicles, $vehicle[0]);
        }
    
        // 2. Try sending duplicate vehicles
        $vehicles = $this->common_model->get_where('fleets', array('vehicle_type' => $vehicleType), 'passengers ASC');
        if (!$requiredVehicles) {
            foreach ($vehicles as $v) {
                if ($v['passengers'] * 2 == $passengers) {
                    array_push($requiredVehicles, $v, $v);
                }
            }
        }
    
        // 3. Find best possible solution
        if (!$requiredVehicles) {
            $totalPermutation = gmp_fact(count($vehicles)) / (gmp_fact(count($vehicles) - 2) * gmp_fact(2));
    
            $total_pax_array = array();
            for ($i = 0; $i < $totalPermutation; $i++) {
                for ($count = $i + 1; $count < count($vehicles); $count++) {
                    $total_pax = $vehicles[$i]['passengers'] + $vehicles[$count]['passengers'];
    
                    if ($total_pax >= $passengers) {
    
                        if (count($total_pax_array) < 1) {
                            $requiredVehicles = array($vehicles[$i], $vehicles[$count]);
                        } else if ($total_pax < min($total_pax_array)) {
                            $requiredVehicles = array($vehicles[$i], $vehicles[$count]);
                        }
    
                        array_push($total_pax_array, $total_pax);
                    }
                }
            }
        }
    
        // 4. check if requirement can be acheived by sending duplicate vehicles
        if (!$requiredVehicles) {
    
            foreach ($vehicles as $v) {
                if ($v['passengers'] * 2 > $passengers) {
                    array_push($requiredVehicles, $v, $v);
                } 
            }
        }
    
        if (!$requiredVehicles)
            jsonOutput('ERROR', 'call for 3 vehicles required.');
        else
            jsonOutput('SUCCESS', 'criteria matching vehicles', $requiredVehicles);
    }
    

1 个答案:

答案 0 :(得分:4)

这可以通过遵循递归公式使用Dynamic Programming (DP)来解决:

D(p,l,s,0) =   infinity        if p>0 or l>0 or s>0
               0               otherwise      
D(p,l,s,i) = min { D(p,l,s,i-1), D(p-cars[i].passangers, l-cars[i].luggage, s-cars[i].suitcases) + 1}

这个想法是D(p,l,s,i)代表汽车1,2,3 ...之间的最小汽车数量,i - 可以乘坐p名乘客,{{1} }行李箱和l行李箱。

时间复杂度(如果应用DP技术):s,其中O(n*p*l*s)是可用车辆数量,n所需乘客人数,p - 所需数量行李和l - 需要的手提箱数量。

另一种解决方案是生成汽车的所有子集,针对每个子集检查它是否是可行的解决方案,并从可行解决方案中选择最小尺寸的子集。时间复杂度:s