我是否需要为以下内容形成所有排列和组合?

时间:2015-02-04 12:50:23

标签: c algorithm dynamic-programming brute-force

你有许多已知重量为w1,...,wn的宝石。编写一个程序,将石头重新排列成两堆,这样桩之间的重量差异很小。

2 个答案:

答案 0 :(得分:1)

虽然这是一维的knastpsack问题,但这是另一种数学方法。



Algorithm: 1D Optimization
Input: weights (sequenc of weights)
Output: left and right, two sequences with difference between sum of elements minimized
***************************************************************************************

1) Sort weights in descending order
2) initialize leftsum = 0, rightsum = 0
3) initialize leftseq = [], rightseq = []
4) for each weight in weights repeat
	4.1) if leftsum = 0 then
		4.1.1) leftsum = weight
		4.1.2) leftseq.add(weight)
	4.2) else if rightsum = 0 then
		4.2.1) rightsum = weight
		4.2.2) rightseq.add(weight)
	4.3) else
		4.3.1) error_left = absolute(leftsum - weight)
		       error_right = absolute(rightsum - weight)
		4.3.2) if error_left >= error_right then
			4.3.2.1) rightsum = rightsum + weight
			4.3.2.2) rightseq.add(weight)
		4.3.3) else
			4.3.3.1) leftsum = leftsum + weight
			4.3.3.2) leftseq.add(weight)
 

// And here is a sample implementation of the above hypothesis in python

numbers = [1, 23, 100, 857, 890, 78, 54, 789, 34, 47, 900];
#numbers = [1, 23, 16, 5, 2]
print numbers
numbers.sort(reverse=True)
print numbers

leftSum = 0;
rightSum = 0;

leftSeq = [];
rightSeq = [];

for num in numbers:
	if leftSum == 0:
		leftSum = num;
		leftSeq.append(num);
	elif rightSum == 0:
		rightSum = num;
		rightSeq.append(num);
	else:
		errorLeft = abs(leftSum - num);
		errorRight = abs(rightSum - num);
		if errorLeft >= errorRight:
			rightSum += num;
			rightSeq.append(num);
		else:
			leftSum += num;
			leftSeq.append(num);

print leftSum;
print rightSum;
print leftSeq;
print rightSeq;
		




它应该工作。您的序列现在位于leftseq和rightseq。

答案 1 :(得分:0)

没有。您无需创建所有2 ^ n个组合。有两种方法可以避免它。

  1. 即使您要创建多个组合并进行比较,也可以使用初步过滤。虽然你只做了一部分组合,设置了一些m(m
  2. 也许你可以找到一些现有的算法,它可以创建所需的合成而不需要任何组合。你可以自己发明它或找到一个已存在的。
  3. 即使您要找到算法,请记住,您必须学习如何使用初步过滤创建自己的排序算法。因为现实生活中有许多任务需要这种技能。