loops - Better Logic with PHP - Finding the cheapest blending ratio -


i have small php script find cheapest rawmaterial mix. in example, mix must have iron share > 60% , 200t needed. precision 2% , have 5 different rawmaterials in stock.

here script :

<?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;      ($m1 = 0; $m1 <= 100;                           $m1 += 2) {     ($m2 = 0; $m2 <= (100 - $m1);                   $m2 += 2) {     ($m3 = 0; $m3 <= (100 - $m1 - $m2);             $m3 += 2) {     ($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 max. quantity mix.      // extrapolate each rawmaterial quantity find 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 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 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);      // ksort(), find unique price array keys     $key = $price * 10000;     while(isset($results[$key])) { $key += 1; }      // save 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 $k => $v) {     print($v); } print("</table>");  print('loops: '   . number_format($counter, 0, '', '.') . '<br>'); print('seconds: ' . number_format((microtime(true) - $beginn), 3, ',', '') . ' sec.');  ?> 

the result:

<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.

it works, problem - $mx_quantity_percent. percentage of each rawmaterial. can see, 1 rawmaterial in each mix has here 100%. example first result

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 kg - 19.57 %) total iron share 60.17%
max.quantity 212167kg
price 53.84

m3 99,78% not 100% (100% cheaper , 100% there no remains ...) it's logical problem...

it great, if has idea :)

thank & best regards


Comments