<?php
$weight = 5678;
$trucks = [1200, 600, 300];
$result = optimize($weight, $trucks);
var_dump($result);
$weight = 900;
$trucks = [600, 350, 100];
$result = optimize($weight, $trucks);
var_dump($result);
$weight = 1300;
$trucks = [1200, 600, 300];
$result = optimize($weight, $trucks);
var_dump($result);
function optimize(int $weight = 0, array $trucks = [], $sensitivity = 10): array
{
$weightStore = $weight; // cache weight
// sort truck-type array (highest to lowest weight capacity).
rsort($trucks);
/* initialize truckCount at 0 for all types */
foreach ($trucks as $type) {
$truckCount[$type] = 0;
}
foreach ($trucks as $type) {
$capacity = $type; // truck capacity
$exact = ($weight / $type);
$round = (int) (floor($exact)); // whole trucks
if ($exact >= 1) {
$truckCount[$type] = $round; // whole trucks
// adjust weight
$weight = $weight - ($round * $type);
}
}
// do we still have remaining weight
if ($weight > 0) {
rsort($trucks);
foreach ($trucks as $type) {
$ratio[$type] = $weight / $type;
$max = max($ratio);
}
$type = array_search($max, $ratio);
$truckCount[$type]++;
$weight -= $type; // final weight adjustment
}
/*
* use the ratio of truck capacities to identify
* edge cases in results array:
* e.g.: algorithm selected two trucks of 300 cap
* where 1 of 600 cap would be more efficient.
*/
$ratioCap = [];
foreach ($trucks as $key => $type) {
if (isset($trucks[$key + 1])) {
$ratioCap[$trucks[$key + 1]] = ($trucks[$key] / $trucks[$key + 1]);
}
}
/* edge cases - force fewer trucks */
$sensitivity = ($sensitivity <= 0) ? 10 : $sensitivity; // set default if neg. or 0
foreach ($trucks as $cycle) {
foreach ($truckCount as $type => $number) {
foreach ($ratioCap as $key => $value) {
if ($type == $key && $number >= (floor($value) / $sensitivity) && $number != 1) {
$truckCount[$type] = 0; // group of smaller type trucks = 0
$truckCount[$type * $value] += 1; // the group of smaller trucks is moved into one larger truck
}
}
}
}
/* truck capacity vs. weight transported */
$capacityUse = 0;
foreach($truckCount as $type => $number) {
$capacityUse += $type * $number;
} $weight = $weightStore - $capacityUse;
return ['trucks' => $truckCount, 'remaining weight' => $weight];
}
- Output for 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.33, 8.2.0 - 8.2.29, 8.3.0 - 8.3.26, 8.4.1 - 8.4.13
- array(2) {
["trucks"]=>
array(3) {
[1200]=>
int(4)
[600]=>
int(1)
[300]=>
int(1)
}
["remaining weight"]=>
int(-22)
}
array(2) {
["trucks"]=>
array(3) {
[600]=>
int(1)
[350]=>
int(1)
[100]=>
int(0)
}
["remaining weight"]=>
int(-50)
}
array(2) {
["trucks"]=>
array(3) {
[1200]=>
int(1)
[600]=>
int(0)
[300]=>
int(1)
}
["remaining weight"]=>
int(-200)
}
preferences:
106.11 ms | 409 KiB | 5 Q