从一组包含数组的项中获取最佳组合

时间:2016-05-07 05:34:35

标签: java algorithm combinations knapsack-problem

我有一组像bellow这样的元素:

  1. A [8] = [1 1 1 1 1 1 1 1]米
  2. B [5] = [5 5 5 5 5]米
  3. C [7] = [0.5 0.5 0.5 0.5 0.5 0.5 0.5]米
  4. 我想从上面的容器中获得最好的项目组合。

    例如,获得7米大小

    • 选项1:从A我们可以拿7项(1 + 1 + 1 + 1 + 1 + 1 + 1)
    • 选项2:从B我们可以拿1个项目,从A我们可以拿2个(5 +(1 + 1))
    • 选项3:从B我们可以拿1个项目,从C我们可以拿4个(5 +(。5 * 4))
    • 选项4:从B我们可以拿1个项目,从B取1和从C我们可以取2(5 + 1 +(。5 * 2))

    让我知道如何解决这个问题。我曾尝试过背包但努力争取最好的组合。

    提前致谢

2 个答案:

答案 0 :(得分:2)

我已经为您编写了这个简单的方法,包括用于提供示例的Resource类。

private static class Resource {
      private double value;
      private int available;

          public Resource(double value, int available) {
             this.value = value;
             this.available = available;
          }

          public void setValue(double value) {
             this.value = value;
          }

          public double getValue() {
             return this.value;
          }

          public void setAvailable(int available) {
             this.available = available;
          }

          public int getAvailable() {
             return this.available;
          }
       }

在屏幕上打印数字的方法

public static void findNumbers(Resource[] availableResources, double targetNumber) {
      // Keeps Track of which resource is currently in use.
      int resourceInCheck = 0;
      // Remainder of the wanted number
      double remainder = targetNumber;

      System.out.print("Values: ");
      while(remainder > 0) {
         if(remainder >= availableResources[resourceInCheck].getValue() && availableResources[resourceInCheck].getAvailable() > 0) {

            System.out.print(availableResources[resourceInCheck].getValue() + ", ");

            remainder -= availableResources[resourceInCheck].getValue();

            availableResources[resourceInCheck].setAvailable( (availableResources[resourceInCheck].getAvailable() - 1) );
         }
         else {
            resourceInCheck++;
         }
      }
   }

主要方法

public static void main(String[] args){

      Resource firstResource = new Resource(5, 5);
      Resource secondResource = new Resource(1, 8);
      Resource thirdResource = new Resource(0.5, 7);

      Resource[] availableResources = {firstResource, secondResource, thirdResource};

      findNumbers(availableResources, 17.5);
   }

输出

Values: 5.0, 5.0, 5.0, 1.0, 1.0, 0.5,

同样,这是一个可能的解决方案,以适应这个问题的特点,显然还有其他方法来解决它。

注意: targetNumber应为<=,而不是所有可用资源的总和。

注2:资源数组需要从较大的值排序到较小的值。

答案 1 :(得分:0)

或许最简单,也是最清楚的,只需生成所有可能的组合并计算&amp;与期望的总数进行比较?

这样的事情:

:For A :In 0 1 2 3 4 5 6 7 8
    :For B :In 0 1 2 3 4 5
        :For C :In 0 1 2 3 4 5 6 7
            :If (7 == (A * 1) + (B * 5) + (C * 0.5))
                [append to list of results]
           :End
       :End
    :End
:End

然后你可以从(总计= 7米)中选择这些结果:

┌───┬───┬─────┐
│1 m│5 m│0.5 m│
├───┼───┼─────┤
│0  │1  │4    │
├───┼───┼─────┤
│1  │1  │2    │
├───┼───┼─────┤
│2  │1  │0    │
├───┼───┼─────┤
│4  │0  │6    │
├───┼───┼─────┤
│5  │0  │4    │
├───┼───┼─────┤
│6  │0  │2    │
├───┼───┼─────┤
│7  │0  │0    │
└───┴───┴─────┘

对于17.5米的情况:

┌───┬───┬─────┐
│1 m│5 m│0.5 m│
├───┼───┼─────┤
│0  │3  │5    │
├───┼───┼─────┤
│1  │3  │3    │
├───┼───┼─────┤
│2  │3  │1    │
├───┼───┼─────┤
│4  │2  │7    │
├───┼───┼─────┤
│5  │2  │5    │
├───┼───┼─────┤
│6  │2  │3    │
├───┼───┼─────┤
│7  │2  │1    │
└───┴───┴─────┘

顺便说一句,你可以解决所有可能的独特总长度(那里没有大的惊喜: - )):

┌─┬───┬─┬───┬─┬───┬─┬───┬─┬───┬─┬───┬─┬───┬─┬───┬─┬───┬─┬───┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┬──┬────┐
│0│0.5│1│1.5│2│2.5│3│3.5│4│4.5│5│5.5│6│6.5│7│7.5│8│8.5│9│9.5│10│10.5│11│11.5│12│12.5│13│13.5│14│14.5│15│15.5│16│16.5│17│17.5│18│18.5│19│19.5│20│20.5│21│21.5│22│22.5│23│23.5│24│24.5│25│25.5│26│26.5│27│27.5│28│28.5│29│29.5│30│30.5│31│31.5│32│32.5│33│33.5│34│34.5│35│35.5│36│36.5│
└─┴───┴─┴───┴─┴───┴─┴───┴─┴───┴─┴───┴─┴───┴─┴───┴─┴───┴─┴───┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┴──┴────┘