由于我不太熟悉各种优化/树算法,我正在寻求帮助。
问题描述:
假设,给出了一个大的排序节点序列,每个节点表示一个整数值L.每个节点的L总是变大,没有节点具有相同的L. 现在的目标是找到最佳节点组合,其中后续节点的L值之间的差异最接近于L的给定整数值M(L)。
示例:
所以,在开始时我会得到L = 50和M = 100.下一个节点的L = 70,140,159,240,310。
首先,159的值似乎最接近L + M = 150,因此它被选为正确的值。 但是,在下一步中,仍然给出M = 100,我们注意到L + M = 259,这远离240。 如果我们现在返回并选择L = 140的节点,然后选择240,则M值和L差异之间的总体匹配更强。该算法应该能够找回最佳路径,即使在此过程中出现了错误。
其他一些信息:
1)起始节点不一定是最佳组合/路径的一部分,但如果需要,可以先开发一种算法,选择最佳的起始候选者。
2)节点的最佳组合遵循排序的序列而不是"跳回" - >所以1,3,5,7是可能的,但不是1,3,5,2,7
3)最后,所选节点的L值之间的差异应该在均方意义上最接近M值
非常感谢每一位帮助!
答案 0 :(得分:1)
如果我理解你的问题,你可以使用Dijktras算法:
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
http://www.mathworks.com/matlabcentral/fileexchange/20025-dijkstra-s-minimum-cost-path-algorithm
为此你必须知道每个节点的邻居并创建一个邻接矩阵。通过我在上面发布的Dijktras算法的实现,您可以指定边权重。您可以通过它所访问的节点的L + M来指定边缘权重。因此,对于每个节点组合,您都有L的新节点+ M.这样,算法应该找到节点之间的最佳路径。 要获得所有边缘组合,您可以使用Matlabs图形函数:
http://se.mathworks.com/help/matlab/ref/graph.html
如果我正确理解您的问题,您需要一个无向图。 您可以使用该命令访问所有边 G.Edges创建图表后。
我知道这不是完美的答案,但我希望它有所帮助!
P.S。请注意,Djikstras算法只能处理正边缘权重。
答案 1 :(得分:0)
假设我们给出了一个数字M和一个n个数字的列表,L [1],...,L [n],我们想要找到后一个数的至少q的子序列,它最小化和相对于M的平方误差(SSE),其中关于M的k个位置x [1],...,x [k]的列表的SSE由
给出SSE(M, x[1], ..., x[k]) = sum((L[x[i]]-L[x[i-1]]-M)^2) over all 2 <= i <= k,
将0或1个位置的SSE定义为0。
(我在这里引入参数q和子序列长度的相关约束,因为没有它,总是存在长度正好为2的子序列,它实现了最小可能的SSE - 我猜测那个这么短的序列对你没有帮助。)
使用dynamic programming可以在 O(qn ^ 2)时间和O(qn)空间中解决此问题。
将f(i,j)定义为在以下约束条件下可实现的最小平方误差总和:
还将g(i,j)定义为全部0 <= k <= i的f(k,j)的最小值。因此g(n,q)将是在整个原始问题上可实现的最小平方误差之和。对于g(i,j)的有效(O(1))计算,请注意
g(i>0, j>0) = min(g(i-1, j), f(i, j))
g(0, 0) = 0
g(0, j>0) = infinity
要计算f(i,j),请注意,如果i&gt;然后,必须通过将第i个位置附加到某个解Y来形成任何解,该解Y选择至少j-1个位置并且其最右边的所选位置在i的左边 - 即,其最右边的选择位置是k,对于某些k <1。一世。对于(i,j)子问题,该解的总SSE将是Y的SSE加上固定项(L [x [i]] - L [x [k]] - M)^ 2 - - 为了最小化这个总SSE,它足以最小化Y的SSE。但我们可以计算出最小值:它是g(k,j-1)。
因为这适用于任何0&lt; = k&lt; i,只需尝试k的所有这些值,并采用给出最低总SSE的值:
f(i>=j, j>=2) = min of (g(k, j-1) + (L[x[i]]-L[x[k]]-M)^2) over all 0 <= k < i
f(i>=j, j<2) = 0 # If we only need 0 or 1 position, SSE is 0
f(i, j>i) = infinity # Can't choose > i positions if the rightmost chosen position is i
通过上述重现和基本情况,我们可以计算g(n,q),即整个问题的最小可能误差平方和。通过memoising values of f(i, j) and g(i, j),计算所有需要的f(i,j)值的时间是O(qn ^ 2),因为最多有(n + 1)*(q + 1)个可能的不同输入组合参数(i,j)和计算f(i,j)的特定值需要最多(n + 1)次循环迭代选择k的值,每次迭代在递归之外花费O(1)时间子调用。存储f(i,j)的解决方案值最多需要(n + 1)*(q + 1)或O(qn),空间,并且同样需要g(i,j)。如上所述,当已经计算了所有需要的f(x,y)值时,可以在O(1)时间内计算g(i,j),因此可以在相同的时间复杂度下计算g(n,q)。
要实际重建与此最小SSE对应的解,您可以以相反的顺序追溯f(i,j)的计算值,每次查找在重复时达到最小值的k值(通常可以存在许多这样的k)值,将i设置为该k值,并继续直到i = 0。这是一种标准的动态编程技术。
答案 2 :(得分:0)
我现在用我当前的实现回答我自己的帖子,以便构建我的帖子并加载图片。不幸的是,代码没有做它应该做的事情。想象一下L,M和q如下图所示。使用calcf和calcg函数,我计算了F和G矩阵,其中F(i + 1,j + 1)是从g(i)计算和存储的f(i,j)和G(i + 1,j + 1) ,J)。最优组合的SSE应为G(N + 1,q + 1),但结果是错误的。如果有人发现了这个错误,那将非常感激。