【问题标题】:Would I need to form all permutations and combinations for the following?我是否需要为以下内容形成所有排列和组合?
【发布时间】:2015-04-04 00:04:44
【问题描述】:

你有许多已知重量为 w1, ..., wn 的石头。

编写一个程序,将石头重新排列成两堆,使两堆之间的重量差异最小。

【问题讨论】:

标签: c algorithm dynamic-programming brute-force


【解决方案1】:

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

  1. 即使您要创建许多组合并比较它们,您也可以使用初步过滤。虽然您只完成了组合的一部分,设置了一些 m (m
  2. 也许您可以找到一些现有的算法,无需任何组合即可创建所需的组合。你可以自己发明它,也可以找到一个已经存在的。

即使您会找到一种算法,请记住,您必须学习如何创建自己的算法来进行初步过滤的排序。因为在现实生活中有许多任务需要您掌握这项技能。

【讨论】:

    【解决方案2】:

    虽然这是一个一维背包问题,但这里有另一种数学方法。

    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 中。

    【讨论】:

      猜你喜欢
      • 2016-06-07
      • 1970-01-01
      • 2019-12-17
      • 2019-06-24
      • 2015-05-12
      • 2021-08-29
      • 1970-01-01
      • 2010-11-16
      • 2023-03-12
      相关资源
      最近更新 更多