Algorithm 使用什么算法将数字序列分割成n个子集,以最小化每个子集中数字总和的标准偏差

Algorithm 使用什么算法将数字序列分割成n个子集,以最小化每个子集中数字总和的标准偏差,algorithm,sequence,Algorithm,Sequence,我正在寻找一种算法,将一个正数序列分割成n个子序列,这样每个子序列中的数字之和的标准偏差就最小化了 每个子序列中的数字顺序需要与原始序列中的顺序相同 例如: 假设我有一个序列{1,1,1,1,1,1,10,1},我想把它分为两个子序列。 我相信最优解是{1,1,1,1,1,1},{10,1} 第一个子序列的和为6,第二个子序列的和为11 这两个数字的标准偏差约为3.5,我认为这是可能的最低值 假设我有一个序列{4,1,1,1,1,6},我想把它分成3个子序列。 我相信最优解是{4},{1,1,1

我正在寻找一种算法,将一个正数序列分割成n个子序列,这样每个子序列中的数字之和的标准偏差就最小化了

每个子序列中的数字顺序需要与原始序列中的顺序相同

例如:

假设我有一个序列{1,1,1,1,1,1,10,1},我想把它分为两个子序列。
我相信最优解是{1,1,1,1,1,1},{10,1}

第一个子序列的和为6,第二个子序列的和为11
这两个数字的标准偏差约为3.5,我认为这是可能的最低值

假设我有一个序列{4,1,1,1,1,6},我想把它分成3个子序列。
我相信最优解是{4},{1,1,1},{6}
子序列之和为4、4和6。
这3个数字的标准偏差约为1.15,我认为这是可能的最低值

我能想到的最好的算法是找到序列中每个数字的累积和,并在[totalSum/numSubsequences]的每个间隔对序列进行分段

例如,给定序列{4,1,1,1,1,6},每个序列的数的累积和为{4,5,6,7,8,14}。序列中所有数字的总数是14,因此,假设我需要3个子序列,当总数达到14/3=4.66和2*14/3=9.333时,我应该分段序列

但是,在序列中没有实际的位置,累积总数等于4.66-第一个累积总数为4,下一个累积总数为5。那么我应该向上取整还是向下取整?在这种情况下,四舍五入到4会给出最佳解决方案,但情况并非总是如此。我能想到的最好方法是尝试上下舍入的每一种组合,但这会导致O(2^numSubsequences)的复杂性

这似乎是一种可以应用预先存在的算法的东西,但是我的谷歌搜索失败了。我知道,它是NP完全的,但它处理的是无序集,而不是有序序列


任何帮助都将不胜感激。

我想到的一个想法是使用A*搜索算法

更多信息:

http://en.wikipedia.org/wiki/A*_search_algorithm
Artificial Intelligence: A Modern Approach by Stuart Russell and Peter Norvig
读一本关于这方面的好书:

http://en.wikipedia.org/wiki/A*_search_algorithm
Artificial Intelligence: A Modern Approach by Stuart Russell and Peter Norvig
有些东西你可以用在A*:

  • 初始状态:将序列拆分为n个相等(尽可能多)的子序列
  • 下一个状态:为每个子集添加左数或右数(子集i-1的最后一个数(如果i!=0)或子集i+1的第一个数(如果i!=n))(以创建当前状态节点的所有降序节点)
  • 启发式:最佳值是所有值的平均值。它是可容许的,因此可以与*一起使用
我不确定这是否真的能帮你解决你的问题,因为我还没有解决这个问题,但我认为它可能会做得很好。对于这个特定的问题,它也可能不是最复杂的解决方案,但它肯定比任何“尝试所有组合”的方法都要好。它也是健全和完整的(因为允许的启发式)


如果您对此有更多问题,请提问,我将尽力帮助您。

我想您的意思是划分为连续的块,或者换言之,找到n-1个位置,在其中将序列分割为多个部分。(如果您真的想让交错的子序列创建主序列,那么您可能只需要对序列进行排序,解决块问题,然后跟踪各个数字的来源,以提供交错的子序列)


我认为你可以用动态规划来解决这个问题,时间与序列长度的n倍成正比。从左到右填充bestCost[i][j]和lastCut[i][j]的数组,其中i沿着序列运行,j从0运行到n-1。bestCost[i][j]是将序列从0到i分割成j个块的最佳方法的成本。lastCut[i][j]是产生最佳成本[i][j]的切割的最新切割位置。最佳成本[i+1][j]=最小标准偏差(i+1到k)+最佳成本[k-1][j-1]。然后lastCut[i+1][j]=k。最后,您以相同的方式计算出n个切割的最佳答案的成本,然后使用lastCut[][]追溯到其他切割。

假设原始序列的长度为
L
,子序列的数量为
n

你可以得到
sqrt(E[X^2]-E[X]^2)
,其中
E
表示期望值/平均值,
X
表示你的随机变量——在你的例子中,是子序列的和。(一个类似的公式适用于“样本标准偏差”。)请注意,
E[X]
并不取决于您如何分割序列,因为它始终是总和除以
N
。因此,我们只想最小化
E[X^2]
,或者等价地,最小化
X^2
之和(根据平均值的定义,它们的差异系数为
N


在这一点上,我们可以看到这个问题可以用动态规划来解决。设
f(i,j)
,对于
i
0
M
j
1
N
,是序列的第一个
i
元素分裂成
j
子序列的子序列和的最小平方和。然后我们看到,
f(i,j)
可以用
f(i',j')
i'计算,我同意动态规划可能是最好的方法-我要排除的一种技术是非线性优化。你有一个非线性目标函数,不管你是最小化平方根还是仅仅是平方差之和。您还有一个整数变量作为约束集的一部分-赋值