用于在最小化成本的同时从集合中选择n个向量的算法

时间:2012-10-18 11:22:26

标签: algorithm machine-learning artificial-intelligence

假设我们有:

  • 设置n维向量的U(向量v =< x1,x2 ...,xn>)
  • 约束n维向量c =< x1 ... xn>
  • 权重的n维向量w =< x1 ... xn>
  • 整数S

我需要算法,该算法将从U中选择S向量到集合R中,同时最小化函数成本(R)

cost(R) = sum(abs(c-sumVectors(R))*w)

(sumVectors是一个对所有向量求和的函数:sumVectors({< 1,2 >; < 3 ,4>}) = < 4,6 >,而sum(< 1, 2, 3 >)返回标量6)

解决方案不一定是最佳的。我只需要在预设时间内得到最好的猜测。

知道从哪里开始? (最好是比遗传算法更快/更智能的东西)

3 个答案:

答案 0 :(得分:4)

这是一个优化问题。由于您不需要最佳解决方案,您可以尝试使用stochastic optimization方法,例如Hill Climbing,其中您从随机解决方案(R的随机子集)开始,并查看相邻的解决方案(添加或删除当前解决方案的一个组件)用于那些与成本函数各自更好的解决方案。

要获得更好的解决方案,您还可以在登山搜索中添加Simulated Annealing。这个想法是,在某些情况下,有必要转向更糟糕的解决方案,然后再找到更好的解决方案。模拟退火效果更好,因为它允许在过程开始时移动到更差的解决方案。随着过程的继续,该算法不太可能允许更糟糕的解决方案。

我粘贴一些示例爬山python代码来解决你的问题: https://gist.github.com/921f398d61ad351ac3d6

在我的示例代码中, R 始终包含 U 的索引列表,并使用euclidean distance来比较邻居之间的相似性。当然,您可以使用其他距离函数来满足您自己的需求。另请注意,在代码中,我正在寻找邻居。如果您在 U 中有大量向量,则可能需要缓存预先计算的邻居,甚至考虑局部敏感散列以避免 O(n^2) 比较。模拟退火可以添加到上面的代码中。

一次随机运行的结果如下所示。

我在 U S = 10中仅使用了20个向量,因此我可以将结果与最佳解决方案进行比较。 登山过程在第4步停止,因为没有更好的选择,只需要替换一个k最近的邻居。

我还运行详尽的搜索,迭代所有可能的组合。你可以看到,与详尽的方法相比,爬山的结果非常好。只需要4个步骤就可以获得相对较小的成本(尽管是局部最小值),这使得穷举搜索超过82K步骤来击败它。

initial R [1, 3, 4, 5, 6, 11, 13, 14, 15, 17]
hill-climbing cost at step      1: 91784
hill-climbing cost at step      2: 89574
hill-climbing cost at step      3: 88664
hill-climbing cost at step      4: 88503
exhaustive search cost at step      1: 94165
exhaustive search cost at step      2: 93888
exhaustive search cost at step      4: 93656
exhaustive search cost at step      5: 93274
exhaustive search cost at step     10: 92318
exhaustive search cost at step     44: 92089
exhaustive search cost at step     50: 91707
exhaustive search cost at step     84: 91561
exhaustive search cost at step     99: 91329
exhaustive search cost at step    105: 90947
exhaustive search cost at step    235: 90718
exhaustive search cost at step    255: 90357
exhaustive search cost at step   8657: 90271
exhaustive search cost at step   8691: 90129
exhaustive search cost at step   8694: 90048
exhaustive search cost at step  19637: 90021
exhaustive search cost at step  19733: 89854
exhaustive search cost at step  19782: 89622
exhaustive search cost at step  19802: 89261
exhaustive search cost at step  20097: 89032
exhaustive search cost at step  20131: 88890
exhaustive search cost at step  20134: 88809
exhaustive search cost at step  32122: 88804
exhaustive search cost at step  32125: 88723
exhaustive search cost at step  32156: 88581
exhaustive search cost at step  69336: 88506
exhaustive search cost at step  82628: 88420

答案 1 :(得分:3)

您将需要检查所有可能的成本R和最小化的成本。如果您逐步选择向量,可以在每次添加时降低成本,则可能无法以最低成本找到该集合。如果向量的集合U非常大并且计算太慢,则可能被迫使用逐步方法。

答案 2 :(得分:1)

你的问题基本上是一个组合优化问题。这些很难解决,但我可以提出一些建议。它们基于你无法探索所有组合的想法,所以你不得不在贪婪的最佳解决方案附近探索。

有一种称为beam-search的非常通用的方法,它是一种启发式方法,它基本上修改了最佳优先搜索以使用有限的内存(波束宽度)。它依赖于以下概念:对于任何给定的部分解决方案,您可以计算与向集合中添加一些新成员相关联的分数,以及当前集合的分数(因为您有一个目标函数很好)。我们的想法是你从空集开始,并不断为堆栈中的每个状态选择n个最佳下一个状态,然后当所有状态都展开时,你将丢弃堆栈上除n个最佳状态之外的所有状态并重复。这将为您提供可能的解决方案,您可以选择最高得分。

然而,这可能不起作用,因为你的目标函数的细节会使这个选择向量立即接近约束,然后(在一些步骤之后,取决于你的成本向量和分量向量的相对比例)看起来对于小向量来减少差异。如果是这样,您可以使用此方法的解决方案初始化随机游走/模拟退火策略(允许您随机添加或从集合中移除)以寻找接近您通过波束搜索获得的解决方案的更好解决方案。 / p>