Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java [a] a, b ============== [a] [a, b] [b]_Java_Algorithm_Optimization_Knapsack Problem - Fatal编程技术网

Java [a] a, b ============== [a] [a, b] [b]

Java [a] a, b ============== [a] [a, b] [b],java,algorithm,optimization,knapsack-problem,Java,Algorithm,Optimization,Knapsack Problem,如果输入为a,b,则有3种可能的结果:[a],[b],[a,b] 这就是我们发现规则1的地方:单个元素([a])的可能性是a,b中可能性的子集。或广义: 前面结果中的所有可能性都将包含在当前结果中 让我们看看这是否适用于a,b,c: a, b a, b, c ================== ============================= --------------

如果输入为
a,b
,则有3种可能的结果:
[a],[b],[a,b]

这就是我们发现规则1的地方:单个元素(
[a]
)的可能性是
a,b
中可能性的子集。或广义:

前面结果中的所有可能性都将包含在当前结果中

让我们看看这是否适用于
a,b,c

     a, b                              a, b, c
==================         =============================
  --------------              -------------
 | [a]  [a, b]  |            | [a]  [a, b] |
 | [b]          |            | [b]         |
 |--------------|            |-------------|  [a, b, c]
                               [c]  [a, c]
                                    [b, c] 
            a, b, c
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]
您可以为更大的输入验证这一点,但它始终是正确的。如果你从正确的角度来看,这一切都是有意义的。潜在
n
的所有组合将是:所有
n-1
+的组合


但这里还有一条更有趣的规则

如果您有这样的输入:

     a, b
==============
 [a]  [a, b]
 [b]
您可以创建一个关于如何计算下一个的算法。首先,创建上一个的副本(根据上述规则):

对于第一行,您只需添加“最后一个”下一个字母。由于下一行是
a、b、c
,因此需要添加到第一行的内容是:
c

     a, b                              a, b, c
==================         =============================
  --------------              -------------
 | [a]  [a, b]  |            | [a]  [a, b] |
 | [b]          |            | [b]         |
 |--------------|            |-------------|  [a, b, c]
                               [c]  [a, c]
                                    [b, c] 
    a, b, c
==============
 [a]  [a, b]
 [b]
 [c]
            a, b, c
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]
对于第二行,取上一行(减去添加的
c
),添加“最后一个”下一个字母并插入它。即:

      a, b, c
===================
 [a] <-|    [a, b]
 [b]   |->  [a, c]  <-- "a" came from the previous row, "c" was added as the last one
 [c]   
对于最后一行,我们只需添加所有“下一行”(
a、b、c
):

使用上述相同的逻辑,您可以计算
a、b、c、d的结果:

先拷贝:

            a, b, c, d
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]
添加
d

            a, b, c, d
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]

 [d]
获取上一行并附加:

            a, b, c, d
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]

 [d]        [a, d]
            [b, d]
            [c, d]
同样,取上一行并追加(记住:“除了添加的那一行”):


如果您理解上面所发生的事情,那么这一切都是关于编写代码的。我所做的唯一更改不是添加我已经知道将无法通过对
max
检查的元素。在这里,它看起来很复杂,但实际上它相当简单(除了一些边缘情况):

静态列表分区(列出所有分区,int max){
ArrayList previousResult=新ArrayList();
ArrayList currentResult=新的ArrayList();
int i=0;
对于(;i 1){
对于(int j=0;j x.getKey()x.stream().map(y->(ArrayList)y.clone()).collect(Collectors.toCollection(ArrayList::new)))
.collect(收集器.toCollection(ArrayList::new));
}
私有静态布尔值(列表中,int max){

在.stream().mapToInt(Choice::getCost.sum()中返回如果你知道这是计算机科学中最著名的问题之一的变种,那么它可能会帮助你研究算法。你为什么不从高到低排序?@Jordan Knapsack有两个变量:使用整数权重约束使值最大化。我在这里看不到与权重约束等价的东西。@jrook想象一个例子,在这个例子中er有100美元,物品的价格分别为80美元、50美元和40美元。从高到低排序会导致购买80美元的物品,剩余20美元。但最佳解决方案是同时购买50美元和40美元的物品,剩余10美元未用。因此,从高到低排序并不总是产生最佳解决方案。同样,尝试从低到高排序gh加上$20、60和$90,你会发现它也不是最优的。这是子集和问题的优化形式。行
sortedResult.entrySet().removeIf(key->key.getKey()!=getMapKey);
正在对
Integer
对象执行引用比较,而不是比较它们的值。但无论如何,这是一个奇怪的操作。一个映射中只能出现一个键,因此这会删除除一个键以外的所有键。但是,通过
qualifyItemsCombinationList.get(0)排序后,最小的项已经可用
,无需将列表复制到
LinkedHashMap
。事实上,即使排序也已过时,
Collections.min(qualifyItems组合,Entry.comparingByKey())
已经给出了最小的条目……这是一个有趣的解决方案,但更有趣的是,这给我带来了多少关于在国内举办电脑奥运会的记忆。令人震惊。
      a, b, c
===================
 [a]        [a, b]
 [b] <-|    [a, c]  
 [c]   |->  [b, c] <-- "b" came from the previous row, "c" then added as the last one
            a, b, c
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]
            a, b, c, d
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]
            a, b, c, d
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]

 [d]
            a, b, c, d
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]

 [d]        [a, d]
            [b, d]
            [c, d]
                a, b, c, d
=================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]     [a, b, d]  <--- [a, b] + [d]
 [d]        [a, d]     [a, c, d]  <--- [a, c] + [d]
            [b, d]     [b, c, d]  <--- [b, c] + [d]
            [c, d] 
                    a, b, c, d
=================================================
 [a]        [a, b]
 [b]        [a, c]     [a, b, c]
 [c]        [b, c]     [a, b, d]  
 [d]        [a, d]     [a, c, d]   [a, b, c, d]
            [b, d]     [b, c, d] 
            [c, d] 
static List<String> partitions(List<Choice> all, int max) {

    ArrayList<ArrayList<ArrayList<Choice>>> previousResult = new ArrayList<>();
    ArrayList<ArrayList<ArrayList<Choice>>> currentResult = new ArrayList<>();

    int i = 0;
    for(;i<all.size();++i) {
        // add the first element
        Choice current = all.get(i);
        if(currentResult.isEmpty()) {
            if(less(List.of(current), max)) {
                // looks complicated, but all it does is adds a single element in the first index
                ArrayList<Choice> inner = new ArrayList<>();
                inner.add(current);
                ArrayList<ArrayList<Choice>> in = new ArrayList<>();
                in.add(inner);
                currentResult.add(in);
                previousResult.add(in);
            }
        } else {
            if(less(List.of(current), max)) {
                ArrayList<Choice> element = new ArrayList<>();
                element.add(current);
                currentResult.get(0).add(element);
            }
            if(currentResult.size() > 1) {
                for(int j=0;j<i-1;++j) {
                    if(j < previousResult.size()) {
                        ArrayList<ArrayList<Choice>> p = previousResult.get(j);
                        for(int d=0;d<=p.size()-1;++d){
                            ArrayList<Choice> copy = new ArrayList<>(p.get(d));
                            copy.add(all.get(i));
                            if(less(copy, max)){
                                currentResult.get(j).add(copy);
                            }
                        }
                    }

                }
            }

            // add tail if possible
            ArrayList<ArrayList<Choice>> tail = new ArrayList<>();
            ArrayList<Choice> t = new ArrayList<>(all.subList(0, i + 1));
            if(less(t, max)) {
                tail.add(t);
                currentResult.add(tail);
            }

            if(currentResult.size() == 1) {
                ArrayList<Choice> l = currentResult.get(0).stream().flatMap(List::stream).collect(Collectors.toCollection(ArrayList::new));
                if(less(l, max)) {
                    tail.add(l);
                    currentResult.add(tail);
                }
            }

            // smart copy here
            previousResult = copy(previousResult, currentResult);
        }

    }

    return
        currentResult.stream()
                     .flatMap(List::stream)
                     .map(list -> {
                            int sum = list.stream().mapToInt(Choice::getCost).sum();
                            List<String> l = list.stream().map(Choice::getKey).collect(Collectors.toList());
                            return new AbstractMap.SimpleEntry<>(sum, l);
                     })
                     .sorted(Map.Entry.<Integer, List<String>>comparingByKey().reversed())
                     .filter(x -> x.getKey() <= max)
                     .map(Map.Entry::getValue)
                     .findFirst()
                     .orElse(List.of());
}

private static ArrayList<ArrayList<ArrayList<Choice>>> copy(ArrayList<ArrayList<ArrayList<Choice>>> previousResult, ArrayList<ArrayList<ArrayList<Choice>>> currentResult) {
    return currentResult.stream()
                 .map(x -> x.stream().map(y -> (ArrayList<Choice>)y.clone()).collect(Collectors.toCollection(ArrayList::new)))
                 .collect(Collectors.toCollection(ArrayList::new));

}

private static boolean less(List<Choice> in, int max) {
    return in.stream().mapToInt(Choice::getCost).sum() <= max;
}