使用PHP改善逻辑 - 找到最便宜的混合比率

时间:2016-03-26 16:43:54

标签: php loops

我有一个小的PHP脚本来找到最便宜的原料混合物。 在此示例中,混合必须具有Iron Share>需要60%和200t。 精度为2%,我们有五种不同的原材料库存。

这是脚本:

<?php

$beginn = microtime(true);
$counter = 0;
$needed_quantity = 200000;
$m =  array();

    // Iron Share in %
    $stock[0]['iron'] = 17.5;
    $stock[1]['iron'] = 60;
    $stock[2]['iron'] = 60;
    $stock[3]['iron'] = 68.6;
    $stock[4]['iron'] = 59.745;

    // rawmaterial quantity
    $stock[0]['quantity'] = 69148;
    $stock[1]['quantity'] = 25460;
    $stock[2]['quantity'] = 34020;
    $stock[3]['quantity'] = 69873;
    $stock[4]['quantity'] = 737299;

    // price per ton
    $stock[0]['price'] = 13.21;
    $stock[1]['price'] = 27.46;
    $stock[2]['price'] = 35.66;
    $stock[3]['price'] = 89.21;
    $stock[4]['price'] = 60.69;

    for ($m1 = 0; $m1 <= 100;                           $m1 += 2) {
    for ($m2 = 0; $m2 <= (100 - $m1);                   $m2 += 2) {
    for ($m3 = 0; $m3 <= (100 - $m1 - $m2);             $m3 += 2) {
    for ($m4 = 0; $m4 <= (100 - $m1 - $m2 - $m3);       $m4 += 2) {
                  $m5  = (100 - $m1 - $m2 - $m3 - $m4);


    $counter++;

    $iron = ($m1 * $stock[0]['iron']) +
            ($m2 * $stock[1]['iron']) +
            ($m3 * $stock[2]['iron']) +
            ($m4 * $stock[3]['iron']) +
            ($m5 * $stock[4]['iron']);
    $iron /= 100;

    // Check Iron Share first
    if ($iron < 60) {
        continue;
    }

    $price = ($m1 * $stock[0]['price']) +
             ($m2 * $stock[1]['price']) +
             ($m3 * $stock[2]['price']) +
             ($m4 * $stock[3]['price']) +
             ($m5 * $stock[4]['price']);
    $price /= 100;

    // Calculation the max. quantity for this mix. 
    // Extrapolate each rawmaterial quantity to find the smallest possible quantity 
    $quantity = 100000000000;
    if ($m1) { $temp = $stock[0]['quantity'] * (100 / $m1); if ($temp < $quantity) { $quantity = $temp; } }
    if ($m2) { $temp = $stock[1]['quantity'] * (100 / $m2); if ($temp < $quantity) { $quantity = $temp; } }
    if ($m3) { $temp = $stock[2]['quantity'] * (100 / $m3); if ($temp < $quantity) { $quantity = $temp; } }
    if ($m4) { $temp = $stock[3]['quantity'] * (100 / $m4); if ($temp < $quantity) { $quantity = $temp; } }
    if ($m5) { $temp = $stock[4]['quantity'] * (100 / $m5); if ($temp < $quantity) { $quantity = $temp; } }

    // Check Quantity
    if ($needed_quantity) {
        if ($quantity < $needed_quantity) {
            continue;
        }
    }

    // Calculate the used quantity 
    $m1_quantity = round($quantity * ($m1 / 100));
    $m2_quantity = round($quantity * ($m2 / 100));
    $m3_quantity = round($quantity * ($m3 / 100));
    $m4_quantity = round($quantity * ($m4 / 100));
    $m5_quantity = round($quantity * ($m5 / 100));

    // Caculate how many percent of stock we need 
    $m1_quantity_percent = round(($quantity * ($m1 / 100)) / $stock[0]['quantity'] * 100,2);
    $m2_quantity_percent = round(($quantity * ($m2 / 100)) / $stock[1]['quantity'] * 100,2);
    $m3_quantity_percent = round(($quantity * ($m3 / 100)) / $stock[2]['quantity'] * 100,2);
    $m4_quantity_percent = round(($quantity * ($m4 / 100)) / $stock[3]['quantity'] * 100,2);
    $m5_quantity_percent = round(($quantity * ($m5 / 100)) / $stock[4]['quantity'] * 100,2);

    // For ksort(), find unique price array keys
    $key = $price * 10000;
    while(isset($results[$key])) { $key += 1; }

    // Save the result
    $result[$key] = "<tr><td>$counter</td>
            <td>$m1 ($m1_quantity kg - $m1_quantity_percent %)</td>
            <td>$m2 ($m2_quantity kg - $m2_quantity_percent %)</td>
            <td>$m3 ($m3_quantity kg - $m3_quantity_percent %)</td>
            <td>$m4 ($m4_quantity kg - $m4_quantity_percent %)</td>
            <td>$m5 ($m5_quantity kg - $m5_quantity_percent %)</td>
            <td><b>" . round($iron,2) . "%</b></td>
            <td><b>" . round($quantity) . "kg</b></td>
            <td><b>" . round($price,2) . "</b></td></tr>";

}
}
}
}

ksort($result);
print("<table border=1 cellpadding=2>
<tr><td>Nr.</td>
    <td>m1</td>
    <td>m2</td>
    <td>m3</td>
    <td>m4</td>
    <td>m5</td>
    <td><b>Total Iron Share</b></td><td><b>Max.Quantity</b></td><td><b>Price\t</b></td></tr>");
foreach($result as $k => $v) {
    print($v);
}
print("</table>");

print('Loops: '   . number_format($counter, 0, '', '.') . '<br>');
print('Seconds: ' . number_format((microtime(true) - $beginn), 3, ',', '') . ' sec.');

?>

结果:

<table border=1 cellpadding=2>
<tr><td>Nr.</td>
<td>m1</td>
<td>m2</td>
<td>m3</td>
<td>m4</td>
<td>m5</td>
<td><b>Total Iron Share</b></td><td><b>Max.Quantity</b></td><td><b>Price	</b></td></tr><tr><td>7546</td>
<td>0 (0 kg - 0 %)</td>
<td>12 (25460 kg - 100 %)</td>
<td>16 (33947 kg - 99.78 %)</td>
<td>4 (8487 kg - 12.15 %)</td>
<td>68 (144273 kg - 19.57 %)</td>
<td><b>60.17%</b></td>
<td><b>212167kg</b></td>
<td><b>53.84</b></td></tr><tr><td>7508</td>
<td>0 (0 kg - 0 %)</td>
<td>12 (25460 kg - 100 %)</td>
<td>14 (29703 kg - 87.31 %)</td>
<td>4 (8487 kg - 12.15 %)</td>
<td>70 (148517 kg - 20.14 %)</td>
<td><b>60.17%</b></td>
<td><b>212167kg</b></td>
<td><b>54.34</b></td></tr><tr><td>7547</td>
<td>0 (0 kg - 0 %)</td>
<td>12 (25460 kg - 100 %)</td>
<td>16 (33947 kg - 99.78 %)</td>
<td>6 (12730 kg - 18.22 %)</td>
<td>66 (140030 kg - 18.99 %)</td>
<td><b>60.35%</b></td>
<td><b>212167kg</b></td>
<td><b>54.41</b></td></tr><tr><td>6473</td>
<td>0 (0 kg - 0 %)</td>
<td>10 (21263 kg - 83.51 %)</td>
<td>16 (34020 kg - 100 %)</td>
<td>4 (8505 kg - 12.17 %)</td>
<td>70 (148838 kg - 20.19 %)</td>
<td><b>60.17%</b></td>
<td><b>212625kg</b></td>
<td><b>54.5</b></td></tr><tr><td>7469</td>
<td>0 (0 kg - 0 %)</td>
<td>12 (25460 kg - 100 %)</td>
<td>12 (25460 kg - 74.84 %)</td>
<td>4 (8487 kg - 12.15 %)</td>
<td>72 (152760 kg - 20.72 %)</td>
<td><b>60.16%</b></td>
<td><b>212167kg</b></td>
<td><b>54.84</b></td></tr><tr><td>7509</td>
<td>0 (0 kg - 0 %)</td>
<td>12 (25460 kg - 100 %)</td>
<td>14 (29703 kg - 87.31 %)</td>
<td>6 (12730 kg - 18.22 %)</td>
<td>68 (144273 kg - 19.57 %)</td>
<td><b>60.34%</b></td>
<td><b>212167kg</b></td>
<td><b>54.91</b></td></tr><tr><td>7548</td>
<td>0 (0 kg - 0 %)</td>
<td>12 (25460 kg - 100 %)</td>
<td>16 (33947 kg - 99.78 %)</td>
<td>8 (16973 kg - 24.29 %)</td>
<td>64 (135787 kg - 18.42 %)</td>
<td><b>60.52%</b></td>
<td><b>212167kg</b></td>
<td><b>54.98</b></td></tr><tr><td>6434</td>
<td>0 (0 kg - 0 %)</td>
<td>10 (24300 kg - 95.44 %)</td>
<td>14 (34020 kg - 100 %)</td>
<td>4 (9720 kg - 13.91 %)</td>
<td>72 (174960 kg - 23.73 %)</td>
<td><b>60.16%</b></td>
<td><b>243000kg</b></td>
<td><b>55</b></td></tr><tr><td>6474</td>
<td>0 (0 kg - 0 %)</td>
<td>10 (21263 kg - 83.51 %)</td>
<td>16 (34020 kg - 100 %)</td>
<td>6 (12758 kg - 18.26 %)</td>
<td>68 (144585 kg - 19.61 %)</td>
<td><b>60.34%</b></td>
<td><b>212625kg</b></td>
<td><b>55.07</b></td></tr></table>Loops: 316.251<br>Seconds: 0,830 sec.

它有效,但问题是 - $ mX_quantity_percent。所以每个原材料的百分比。如您所见,每种混合物中只有一种原材料在这里100%。 例如,第一个结果

NR。 7546
m1 0(0 kg - 0%)
m2 12(25460 kg - 100%)
m3 16(33947 kg - 99.78%)
m4 4(8487 kg - 12.15%)
m5 68(144273千克 - 19.57%) 铁总份额60.17%
最大数量212167千克 价格53.84

m3是99,78%而不是100%(100%会更便宜,100%没有遗骸......) 这是一个合乎逻辑的问题......

如果有人有想法,那就太好了。)

谢谢你&amp;最诚挚的问候

0 个答案:

没有答案