对于某些子集的选择,如果您不介意进行一些(可能很昂贵的)预计算,那么有一些方法可以加快计算速度,但不是全部。例如,假设您的子集是 {1,2}, {2,3}, {3,4}, {4,5}, ..., {n-1,n}, {n,1}; 那么幼稚的方法对每个子集使用一个算术运算,显然你不能做得比这更好。另一方面,如果您的子集是 {1}, {1,2}, {1,2,3}, {1,2,3,4}, ..., {1,2,..., n} 那么你可以使用 n-1 算术运算,而天真的方法要糟糕得多。
这是进行预计算的一种方法。它并不总能找到最佳结果。对于每对子集,将转换成本定义为 min(对称差异的大小,Y - 1 的大小)。(X 和 Y 的对称差是 X 或 Y 中的一组事物,但不是两者。)因此,转换成本是计算 Y 元素之和所需的算术运算次数,给定X的。将空集添加到子集列表中,并使用 Edmonds 算法 (http://en.wikipedia.org/wiki/Edmonds%27_algorithm) 或更快但更复杂的变体之一计算最小成本有向生成树那个主题。现在确保当您的生成树有一条边 X -> Y 时,您在 Y 之前计算 X。(这是一种“拓扑排序”,可以有效地完成。
当您有 {1,2}, {3,4}, {1,2,3,4}, {5,6}, {7,8}, {5,6 ,7,8}。在使用上述过程确定您的操作顺序之后,您可以进行优化传递,您可以找到更便宜的方法来评估每个集合的总和,给定已经计算的总和,这在实践中可能会给出相当不错的结果。
我怀疑,但没有试图证明,为给定的一组子集找到一个最佳过程是 NP-hard 或更糟的。(它当然是可计算的;您可能进行的计算集是有限的。但是,从表面上看,它可能非常昂贵;您可能正在跟踪大约 2^n 部分和,添加任何一个他们在每个步骤中与其他任何步骤,并且最多有大约 n^2 步骤,对于 (2^2n)^(n^2) = 2^(2n^3) 操作的超幼稚成本来尝试每种可能性。 )