Knapsack problem 解决大量类似背包实例的最佳实践

Knapsack problem 解决大量类似背包实例的最佳实践,knapsack-problem,constraint-programming,minizinc,Knapsack Problem,Constraint Programming,Minizinc,我正在做一个项目,在这个项目中,我需要解决数千个从小到大的类似背包问题的“简单”实例。我的所有实例都具有相同的结构、相同的约束,但项目数量(因此变量)不同。可以为所有实例修复域 我已经成功地将Minizing集成到一个工作流中 从数据库中提取相关数据 生成.mzn模型(包括初始变量分配) 调用CBC解算器的Minizing驱动程序 解析并解释解决方案 现在,在大型实例的平坦化阶段,我遇到了一个性能瓶颈(cf verbose flatting stats)。展平最多需要30秒,而求解最优值所需时间

我正在做一个项目,在这个项目中,我需要解决数千个从小到大的类似背包问题的“简单”实例。我的所有实例都具有相同的结构、相同的约束,但项目数量(因此变量)不同。可以为所有实例修复域

我已经成功地将Minizing集成到一个工作流中

  • 从数据库中提取相关数据
  • 生成.mzn模型(包括初始变量分配)
  • 调用CBC解算器的Minizing驱动程序
  • 解析并解释解决方案 现在,在大型实例的平坦化阶段,我遇到了一个性能瓶颈(cf verbose flatting stats)。展平最多需要30秒,而求解最优值所需时间不到1秒

    我尝试过禁用“优化展平”但无济于事,我还尝试过拆分工具链(mzn2fzn,然后是mzn cbc);最后尝试分离模型和数据定义,但没有观察到任何显著的改进

    如果有帮助,我已经确定了导致问题的约束集:

    ...
    array[1..num_items] of int: item_label= [1,12,81,12, [10 000 more ints between 1..82], 53 ];
    
    int: num_label = 82;
    array[1..num_label] of var 0..num_items: cluster_distribution;
    constraint forall(i in 1..num_label)(cluster_distribution[i]==sum(j in 1..num_items)(item_indicator[j] /\ item_label[j]==i));
    var 1..num_label: nz_label;
    constraint non_zero_label = sum(i in 1..num_label) (cluster_distribution[i]>0);
    ....
    
    基本上,5000个项目中的每一个都有一个标签(在大约100个可能的标签中),我尝试(在其他目标中)最大化不同标签的数量(非零标签变量)。我试过各种配方,但这个似乎是最有效的

    有谁能为我提供一些关于如何加速这一扁平化阶段的指导吗?您将如何处理解决数千个“类似”实例的任务

    直接生成MPS文件,然后本机调用CBC是否有益?我希望Minizing在编译MPS文件时非常高效,但也许我可以利用实例的重复结构来提高速度?然而,我担心这或多或少会归结为重新编写了一个写得不好的半生不熟的Minizing伪定制版本,这感觉不太对

    谢谢

    我的系统信息:OSX和Ubuntu,mnz 2.1.7

    Compiling instance-2905-gd.mzn
    MiniZinc to FlatZinc converter, version 2.1.7
    Copyright (C) 2014-2018   Monash University, NICTA, Data61
    Parsing file(s) 'instance-2905-gd.mzn' ...
    processing file '../share/minizinc/std/stdlib.mzn'
    processing file '../share/minizinc/std/builtins.mzn'
    processing file '../share/minizinc/std/redefinitions-2.1.1.mzn'
    processing file '../share/minizinc/std/redefinitions-2.1.mzn'
    processing file '../share/minizinc/linear/redefinitions-2.0.2.mzn'
    processing file '../share/minizinc/linear/redefinitions-2.0.mzn'
    processing file '../share/minizinc/linear/redefinitions.mzn'
    processing file '../share/minizinc/std/nosets.mzn'
    processing file '../share/minizinc/linear/redefs_lin_halfreifs.mzn'
    processing file '../share/minizinc/linear/redefs_lin_reifs.mzn'
    processing file '../share/minizinc/linear/domain_encodings.mzn'
    processing file '../share/minizinc/linear/redefs_bool_reifs.mzn'
    processing file '../share/minizinc/linear/options.mzn'
    processing file '../share/minizinc/std/flatzinc_builtins.mzn'
    processing file 'instance-2905-gd.mzn'
     done parsing (70 ms)
    Typechecking ... done (13 ms)
    Flattening ... done (16504 ms), max stack depth 14
    MIP domains ...82 POSTs [ 82,0,0,0,0,0,0,0,0,0, ], LINEQ [ 0,0,0,0,0,0,0,0,82, ], 82 / 82 vars, 82 cliques, 2 / 2 / 2 NSubIntv m/a/m, 0 / 127.085 / 20322 SubIntvSize m/a/m, 0 clq eq_encoded  ...  done (28 ms)
    Optimizing ... done (8 ms)
    Converting to old FlatZinc ... done (37 ms)
    Generated FlatZinc statistics:
    Variables: 21258 int, 20928 float
    Constraints: 416 int, 20929 float
        This is a minimization problem.
    Printing FlatZinc to '/var/folders/99/0zvzbfcj3h16g04d07w38wrw0000gn/T/MiniZinc IDE (bundled)-RzF4wk/instance-2905-gd.fzn' ... done (316 ms)
    Printing .ozn to '/var/folders/99/0zvzbfcj3h16g04d07w38wrw0000gn/T/MiniZinc IDE (bundled)-RzF4wk/instance-2905-gd.ozn' ... done (111 ms)
    Maximum memory 318 Mbytes.
      Flattening done, 17.09 s
    

    如果您正在解决同一问题类的多个实例化,并且需要花费大量的展平时间,那么您可以采取两种通用方法:优化Minizin以最小化展平时间,或者可以在直接解算器API中实现模型

    如果要保持解算器之间的通用性,第一个选项是最好的。为了优化展平时间,您希望消除的主要内容是“临时”变量:创建然后丢弃的变量。将模型展平的大部分时间用于解决不必要的变量。这是为了在求解时最小化搜索空间。临时变量可以在理解、循环、let表达式和具体化中生成。针对您的特定车型,对约束中的For循环进行了优化:

    constraint forall(i in 1..num_label)(cluster_distribution[i]==sum(j in 1..num_items where item_label[j]==i)(item_indicator[j]));
    

    如果您想将模型集成到软件产品中,另一个选项可能是最好的,因为您可以提供与解算器的直接交互。您将不得不手动“展平”您的模型/数据,但您可以仅针对您的目的以更有限的方式进行。因为它不是通用的,所以它可以非常快。通过查看为不同实例生成的FlatZn,可以找到模型提示。

    我希望每次执行MiniZn都会增加更大的开销。由于问题很简单,您不能直接调用CBCAPI吗?这将比通过MPS文件更快。感谢Dekker(还有Gleb),这无疑减少了展平阶段所需的时间。