基本上我有一个项目列表,其中包含大小和值的参数,需要以最佳方式与许多其他项目相匹配,以达到可能的最高值,但保持在maxSize下。
要解释此问题,请参阅以下说明。
第1项: 大小1,值1;
第2项: 大小2,值4:
最大尺寸:11; 最佳解决方案:1xItem1,5xItem2。
但在这种情况下,限制更高,物品更多。我的问题是找到最好的组合。到目前为止,我已经创建了一个算法来实现这一点,但由于复杂性太差,它只适用于少数项目。
我基本上尝试了所有可能的组合,这会在更多数量的项目上创建大量计算。我将保存的路径保存为字符串(Item2-> Item2-> Item1-> Item2 ...),直到总大小高于限制。如果该值高于其他找到的值,则会保存该字符串。
我想要做的是保存已经完成的所有计算,这是一个例子。
A - > A - > A - > A - >甲
A - > B - > A - > A - >甲
在最后一种情况下,没有必要重新计算A - > A - > A,我想要做的就是将它保存起来。
最好的方法是什么?
目前,我的递归看起来像这样
recursion(Item item, int size, int value, String s){
s += cust.getName() + "-";
if(value is bigger)
bestMix = s
for(Item item : itemList){
if(!(we break the limit){
recursion(item, size + item.getSize(), value + item.getValue(), s);
}
}
}
我想要做的是在进行递归时获取已计算的值。
为了降低时间复杂度,最简单,最智能的方法是什么?
答案 0 :(得分:2)
您正在寻找的是memoization,这是dynamic programming种常见的算法技术,可让您通过将解决方案重用于子问题来提高速度。这种技术的一个必要条件是,正在解决的问题有optimal substructure,这是你的问题所在。
这是通常实现memoization的一种方法:在递归例程中添加一个额外的参数,其中包含已知子问题的解决方案的映射。每个子问题的参数都被编码为在已知解决方案的地图中查找的关键字。
memoized递归解决方案的第一件事是构建一个密钥并在已知解决方案的映射中运行查找。如果答案在那里,它会立即返回,而不会再进一步递减。如果答案不存在,则以常规方式计算,然后在从递归调用返回之前放入解决方案的映射中。
答案 1 :(得分:0)
项目1具有每个大小的利润(双倍值/大小(1/1。项目2具有更大的每个大小利润4/2。因此,您应该对itemList(带有Comparator)进行排序第2项。然后第一个遇到的解决方案可以是最大的解决方案。
另一个改进是每个项目都有int factor
,开始尝试最高因素。
一般来说,递归有完成事情的参数和待办事项(候选人)。
每次调用都会有一个部分结果。访问其余部分的缓存可能是可行的,但对于已经存在的数据结构(如某些树结构)更为重要。
答案 2 :(得分:0)
正如dasblinkenlight所说,记忆是要走的路,但我决定做点别的事。
我意识到我的问题是“未绑定的背包问题”的意思 更多信息: http://www.cs.rit.edu/~zjb/courses/800/lec7.pdf http://en.wikipedia.org/wiki/Knapsack_problem
我用动态编程解决了这个问题。 http://en.wikipedia.org/wiki/Dynamic_programming
这使我的时间复杂度更好。