将给定的一组数字 N 分成两组,以使它们的总和之差最小?

Posted

技术标签:

【中文标题】将给定的一组数字 N 分成两组,以使它们的总和之差最小?【英文标题】:Divide a given set of numbers N in two groups such that their difference of their sum is minimum? 【发布时间】:2015-04-07 11:09:23 【问题描述】:

您最多可以从集合中排除一个元素以实现目标。 示例:-

N=3

给出的数字是 = 1,2,5

所以,

第 1 组应该是:- [1]

第 2 组应该是:- [2]

我们排除了 5 个,因为我们可以在不属于任一组的情况下实现较小的差异。

N=4

数字 = 1,2,2,5

设置1 = [1,2,2]

设置2 = [5]

什么是最好的算法? 我知道这是一个 NP 完全问题。 而且我认为蛮力会给我正确的解决方案,但如果可用的话,我需要一个算法。

【问题讨论】:

伪多项式时间适合你使用吗? 【参考方案1】:

我知道这是一个 NP 完全问题。

不完全是,partition optimisation problem 甚至被认为是 NP 难的。

而且我认为蛮力会给我正确的解决方案,但我需要一个算法(如果有的话)。

NP-hard 意味着没有已知算法(用于确定解决方案)比蛮力方法执行得更好。

因此,您可能需要approximation,但只有您自己知道哪个适合您的需求。

什么是最好的算法?

定义“最佳”。

【讨论】:

【参考方案2】:

这是著名问题的变体,将整数集划分为两个子集,其和相等或尽可能接近相等。但是,您提出的问题更加困难 - 您还必须检查从原始集合中删除一个元素的所有组合。

由于原始问题是 NP 完全的,所以这个问题也是 NP 完全的(实际上,这是问题的优化版本,甚至是 NP-hard,正如 Bergi 的回答中正确提到的那样)。好消息是,即使在这个更难的版本中,贪婪的方法在大多数情况下都能给你一个满意的答案。策略如下:从原始集合中取出最大的元素并将它们放入第一个和第二个子集中,每个子集中一个。原始集合中的所有其他元素都放入总和较小的子集中,并反复重复该过程,直到您选择了所有元素。

为了获得最佳结果,您需要对原始集合的所有 N 个子集重复此过程,通过删除索引 1,2,...,N 处的元素来获取每个子集。这就是让这个问题变得更加困难的原因。

如果您对更高级的方法感兴趣,请查看Karmarkar-Karp differencing algorithm。

另请参阅:

The easiest hard problem

【讨论】:

以上是关于将给定的一组数字 N 分成两组,以使它们的总和之差最小?的主要内容,如果未能解决你的问题,请参考以下文章

将数字分组 C++

# $CF 638 (Div2)$

MATLAB中,怎样把一组给定的数据随机排列?

zoj 1880 - Tug of War

求java程序:输入n个正整数,分成两组求和,求两列数字组合使这两组的和最接近平均数

找到所需的最小元素数,以使它们的总和等于或超过 S