python数组分成两个和相等的子集_如何将数组拆分为两个子集,并使数组的子值总和尽可能相等...

4 个答案:

答案 0 :(得分:2)

首先,正如已经确定的那样 - 问题是NP-Hard,减少了分区问题。

Reduction:

给定partition problem的实例,创建每个大小为1的列表。结果将是这个问题。

以上结论:

这个问题是NP-Hard,没有已知的多项式解。

第二,由于问题的严重性,任何指数和伪多项式解决方案都需要很长时间才能工作。

第三,它给我们留下了启发式和近似算法。

我建议采用以下方法:

规范化子列表的比例,因此所有元素都将处于相同的比例(例如,所有元素将被标准化为范围[-1,1]或者所有元素将标准化为标准normal distribution)。

创建一个新列表,其中每个元素将是规范化列表中匹配子列表的总和。

使用为子集和/分区问题开发的一些近似或启发式解决方案。

醇>

结果不是最佳的,但最佳效果在这里确实无法解决。

答案 1 :(得分:2)

根据我在原帖中的讨论中收集的内容,您不是在搜索单个分裂点,而是想要在两个集合中分配所有对,以便两个集合中的每个集合中的总和大致相等。

简而言之,我们的想法是,您可以通过随机将每对配​​置为左侧或右侧设置来开始。

接下来,您可以通过生成新状态

a)从左到右移动随机选择的一对,

b)移动随机选择的一对

从右到左设置,或

c)同时做两件事。

接下来,确定此新状态是好于还是差于当前状态。如果它更好,请使用它。

如果情况更糟,只有当接受概率函数接受它时才接受它,这是一个函数

最初允许使用更糟糕的状态,但随着时间的推移越来越少地支持它们(或者温度降低",在SA术语中)。

经过大量的迭代(比如100.000),你应该有一个非常好的结果。

(可选)多次重新运行此算法,因为它可能会陷入局部最优(尽管接受概率函数试图对此进行反击)。

这种方法的优点是实施起来很简单,你可以自己决定多长时间

你希望它继续寻找更好的解决方案。

答案 2 :(得分:1)

我假设我们只是在阵列中间寻找一个位置,将其分成第一和第二部分。

似乎线性算法可以做到这一点。在JavaScript中有这样的东西。

arrayLength = 2;

tolerance = 10;

// Initialize the two sums.

firstSum = [];

secondSum = [];

for (j = 0; j < arrayLength; j++)

{

firstSum[j] = 0;

secondSum[j] = 0;

for (i = 0; i < arrays.length; i++)

{

secondSum += arrays[i][j];

}

}

// Try splitting at every place in "arrays".

// Try to get the sums as close as possible.

for (i = 0; i < arrays.length; i++)

{

goodEnough = true;

for (j = 0; j < arrayLength; j++)

{

if (Math.abs(firstSum[j] - secondSum[j]) > tolerance)

goodEnough = false;

}

if (goodEnough)

{

alert("split before index " + i);

break;

}

// Update the sums for the new position.

for (j = 0; j < arrayLength; j++)

{

firstSum[j] += arrays[i][j];

secondSum[j] -= arrays[i][j];

}

}

答案 3 :(得分:0)

感谢所有答案,暴力攻击是一个好主意,NP-Hard也与此相关,但事实证明这是一个多背包问题,可以使用this pdf document解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值