【发布时间】:2015-05-22 09:05:43
【问题描述】:
我想用木板填充一个特定的长度。为此,我需要找到木板组合的最佳可能性,使用尽可能少的木板,最后一块木板的剩余量最少。 为此,我首先创建一棵具有所有可能性的树。之后我将数组展平一点,所以我在一个数组中拥有所有选项(删除树方面)。最后,我遍历数组以获得具有最低深度和最低剩余的结果。 前两个步骤我使用递归函数完成。
问题: 长度为 5000 毫米,木板为 5000 毫米、4000 毫米和 3000 毫米,有 7 种可能性。 当我尝试 20000 毫米的长度和 2450 毫米、2750 毫米、3000 毫米、3150 毫米、3600 毫米、3900 毫米、4000 毫米、4600 毫米、4900 毫米和 5000 毫米的木板时,有几十亿种可能性。 使用我当前的代码,我超过了 php 的 30 秒限制。我尝试在谷歌上寻找一个好的算法来解决这个问题,但我找不到可能的解决方案。
有没有人知道解决这个问题的算法或解决方案?我试图将计算保持在最低限度,以尽可能快地保持速度。
创建树
public function createPossibilities($lengths, $length, $depth = 1) {
$lengths = [2450, 2750, 3000, 3150, 3600, 3900, 4000, 4600, 4900, 5000]; // example array of all possible lengths
$res = []; // array with all possible results
foreach ($lengths as $l) {
$rest = $length - $l; // calculates the rest length
if ($rest > 0) // check if length is complete
$children = ['depth' => $depth, 'length' => $l, 'children' => $this->createPossibilities($lengths, $rest, ($depth +1))]; // if length is not complete, do function recursively
else
$children = ['depth' => $depth, 'length' => $l, 'leftover' => abs($rest)]; // if length is complete, add the leftover to the array
$res[] = $children;
}
return $res;
}
扁平树
public function flattenArray($array, &$possibilities, $str = '') {
foreach ($array as $element) {
$temp = $str;
$temp .= $element['length'] . ', '; // add length to string
if (array_key_exists('children', $element)) { // check if element has children
$this->flattenArray($element['children'], $possibilities, $temp); // do function recursively for the child
} else {
$temp = explode(', ', $temp); // explode the string into an array
array_pop($temp); // remove last empty element
$temp['depth'] = count($temp); // add the depth to the array
$temp['leftover'] = $element['leftover']; // add the leftover to the array
$possibilities[] = $temp; // add the possibility to the array
}
}
}
获得最佳可能性
public function getBestPossibility($options, &$liggersPerBreedte) {
$minDepth = -1;
$minLeftover = -1;
foreach ($options as $option) {
if ($option['depth'] < $minDepth || $minDepth == -1) { // check if possibility has fewest lengths
$minDepth = $option['depth']; // put min depth to this option
unset($option['depth']); // remove depth from option
$minLeftover = $option['leftover']; // put min leftover to this option
unset($optie['leftover']); // remove leftover from option
$bestPosibility = $option; // best possibility is array with lengths
} else if ($option['depth'] == $minDepth && $option['leftover'] < $minLeftover) { // check if depth is the same as min, but leftover is less
unset($option['depth']); // remove depth from option
$minLeftover = $optie['leftover']; // put min leftover to this option
unset($optie['leftover']); // remove leftover from option
$bestPosibility = $option; // best possibility is array with lengths
}
}
}
示例
$tree = createPossibilities([5000, 4000, 3000], 8000);
$possibilities = [];
$flatten = flattenArray($tree, $possibilities);
$best = getBestPossibilities($possibilities); // result: [5000, 3000]
【问题讨论】:
标签: php arrays algorithm recursion