繁体   English   中英

如何找到有效子集和最佳有效子集?

[英]How to find the valid subsets and the best valid subset?

我正在尝试解决二维 0-1 全背包问题,使用蛮力方法生成所有可能的子集并选择最有价值的子集。 但是,我未能找到有效子集以及从这些有效子集中找到最佳选择。

我创建了一个 Item 类,其中包含值、大小和重量变量,以及 getter 和 setter。

我还想出了如何生成所有子集。

子集的总重量和尺寸必须等于背包的重量和尺寸,否则包装将不起作用。

但是对于我的生活,我无法弄清楚如何选择获胜的子集。 我知道,首先,必须找到所有有效的子集(总尺寸和重量等于背包的尺寸和重量),然后在这些子集中最有价值的是所选择的包装。

要查看子集是否有效,我假设必须有一个 if 语句,例如

if (subsetSize == knapsackSize && subsetWeight == knapsackWeight)
      subset is valid

但我想不出最好的方法来做到这一点。

我也无法弄清楚是否应该将子集值存储到某个列表中以比较它们,或者是否有我没有看到的更好的方法。

例如,这是我未能找到子集的值、大小和重量的失败之一。

for(int i = 0; i <setOfSubsets.size(); i ++) {
                for (int j = 0; j < setOfSubsets.get(i).size(); j ++) {



                    subsetSizeList.add(setOfSubsets.get(i).get(j).getSize());
                    subsetWeightList.add(setOfSubsets.get(i).get(j).getWeight());
                    subsetValueList.add(setOfSubsets.get(i).get(j).getValue());


下面是代码的其余部分。

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class FullKnapsack2D {


    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        ArrayList<Item> itemList = new ArrayList<Item>();
        List<ArrayList<Item>> setOfSubsets = new ArrayList<ArrayList<Item>>();

        System.out.println("Enter the knapsack weight and size capacity (separate by space): ");
        int knapsackWeight = s.nextInt();
        int knapsackSize = s.nextInt();

        System.out.println("How many items?");
        int numberOfItems = s.nextInt();

        for (int i = 0; i < numberOfItems; i ++) {
            System.out.println("Enter the value, size, and weight for item " + (i + 1));
            Item newItem = new Item(s.nextInt(), s.nextInt(), s.nextInt());
            itemList.add(newItem);
        }

        System.out.println("Running...");

        long startTime = System.currentTimeMillis();

        for(int i = 0; i < itemList.size(); i ++) {

            List<ArrayList<Item>> setCopy = new ArrayList<ArrayList<Item>>();

            // Make a setCopy of all existing subsets
            for(ArrayList<Item> subset : setOfSubsets) {
                setCopy.add(new ArrayList<Item>(subset));
            }

            //Add the new element to each of the existing subsets
            for(ArrayList<Item> subset : setCopy) {
                subset.add(itemList.get(i));
            }

            //Add the new element as a standalone set
            ArrayList<Item> standalone = new ArrayList<Item>();
            standalone.add(itemList.get(i));
            setCopy.add(standalone);

            setOfSubsets.addAll(setCopy);
        }

            //Print out all subsets
            for(ArrayList<Item> subset : setOfSubsets) {
                System.out.println(subset);
            }


        //if the sum total of a subset's value is higher than every other subset's value &&
        // the sum total of a subset's weight and size is equal to the knapsack's
        // weight and size, then 

        //System.out.println("Found an optimal packing:");

        //for(Item item : subset){
        // System.out.println(item.toString());
        //}
            ```




似乎是一个简单的逻辑问题。 既然你已经获得了所有可能的组合,那么你需要做的是:

对于每个子集,

  1. 计算所有物品的总尺寸、重量和价值。
  2. 如果总尺寸等于背包尺寸且总重量等于背包重量,则检查当前总值是否最大
  3. 如果是,则将其存储为迄今为止的最佳子集
ArrayList<Item> bestSubset = null;
int bestValue = 0;
for(ArrayList<Item> subset : setOfSubsets){
    int totalSize = 0;
    int totalWeight = 0;
    int totalValue = 0;
    for(Item i : subset){
        totalSize += i.getSize();
        totalWeight += i.getWeight();
        totalValue += i.getValue();
    }
    if(totalSize == knapsackSize && totalWeight == knapsackWeight && totalValue > bestValue){
        bestSubset = subset;
        bestValue = totalValue;
    }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM