【问题标题】:ILOG CPLEX / OPL dynamic Excel sheet referencingILOG CPLEX / OPL 动态 Excel 工作表引用
【发布时间】:2019-11-27 16:34:20
【问题描述】:

我正在尝试动态引用 .dat 中的 Excel 工作表或表格,以解决我尝试在 CPLEX (OPL) 中解决的车辆路由中的混合整数问题。

设置是:.mod = 模型,.dat = 数据和 MS Excel 电子表格

我有一个二维数组,其中客户需求数据 = Excel 范围(为了编码方便,我还没有将 Excel 数据格式化为表格)

.mod 中的决策变量如下所示:

dvar boolean x[顶点][顶点][场景]

在 .dat 中:

来自 SheetRead 的顶点(数据,“Table!vertices”);

来自 SheetRead 的场景(数据,“不知道如何”); 这可能不需要

没有场景索引一切都很好。 但是随着这个模型中客户需求的变化,我想通过改变数据库引用来包括这个。 现在我想做的是两件事之一:

要么: 更改 Excel 中的电子表格,以便根据情况在 .dat 中得到类似的内容:

场景 = 1:

来自 SheetRead 的顶点(数据,“table-scenario-1!vertices”);

场景 = 2:

来自 SheetRead 的顶点(数据,“table-scenario-2!vertices”);

因此更改电子表格以获取新的基础数据, 要么: 更改同一电子表格中的范围:

场景 = 1:

来自 SheetRead 的顶点(数据,“table!vertices-1”);

场景 = 2:

来自 SheetRead 的顶点(数据,“table!vertices-2”);

无论哪种方式都可以。

了解 Excel 中的 3D 表是如何使用多个电子表格和 2D 表分组创建的,更自然的方法似乎是,让顶点始终在每个 Excel 电子表格中引用相同的范围,同时根据电子表格/页面切换的场景,但我就是不知道怎么做。

感谢您的建议。

【问题讨论】:

  • 是否可以选择只读取 所有 数据,然后在 .mod 文件中选择适当的数据?例如,您可以为所有内容添加额外的场景索引。然后在.mod 文件中,您可以通过修复场景索引来选择要使用的场景。
  • 我如何在 CPLEX 中执行此操作?是否仍然需要将较大的 Excel 范围分组到场景子组中?还是我必须在预处理块中更改 .mod 中使用的数据?
  • 是的,您仍然需要按场景对数据进行分组。问题是SheetConnectionSheetRead 的参数不是动态的。因此,您必须将“活力”移到其他地方。根据我的建议,您将始终阅读相同(硬编码)的 Excel 表格,但会在 .mod 文件中动态过滤。有多种方法可以进行此过滤。一种是使用预处理,另一种是在.mod中有一个参数,指定当前使用的场景。
  • 嗯,好的,到目前为止,我从工作表中读取了所有数据。我现在的问题是,虽然它最终会对场景需求进行排序,但它会在场景中选择一条路线,例如从场景 1 中的仓库 0 到客户 3,然后在场景 2 中从客户 3 到客户 2 等等。您的哪些建议更有可能和更容易产生可行的解决方案。关键是我正在尝试解决 TWAVRP(时间窗口分配车辆路线问题),其中时间窗口是在需求已知之前分配的。然后它解决所有可能的 d 场景并找到最佳方案。
  • 如果您有跨场景的游览,那么您可能会遗漏一些限制。在您的情况下,我希望基本上每个约束定义都以 forall (s in Scenarios) 之类的东西开头,然后您就有了每个场景的约束。如果您可以显示完整的 .mod、.dat 和 Excel 文件,那么我们或许能够提供更多调试帮助。

标签: excel cplex opl ilog


【解决方案1】:

不幸的是,SheetConnection 的参数必须是字符串文字或 Id(请参阅用户手册 here 中的 OPL 语法)。 SheetRead 也是如此。这意味着,您不能有工作表连接的动态源。

正如我们在 cmets 中所讨论的,一种选择是为所有数据添加一个附加索引:场景。然后始终读取所有场景的数据,并在 .mod 文件中选择您要实际使用的数据。

【讨论】:

    【解决方案2】:

    https://www.ibm.com/developerworks/community/forums/html/topic?id=5af4d332-2a97-4250-bc06-76595eef1ab0&ps=25 我分享了一个示例,您可以在其中为 Excel 文件设置动态名称。与您可以拥有动态范围一样,诀窍是使用流量控制。

    sub.mod

    float maxOfx = 2;
    string fileName=...;
    dvar float x;
    
    maximize x;
    subject to {
      x<=maxOfx;
    }
    
    execute
    {
     writeln("filename= ",fileName);
    } 
    

    然后主模型是

    main {
      var source = new IloOplModelSource("sub.mod");
      var cplex = new IloCplex();
      var def = new IloOplModelDefinition(source);
      var opl = new IloOplModel(def,cplex);
    
    
      for(var k=11;k<=20;k++)
      {
      var opl = new IloOplModel(def,cplex);
    
      var data2= new IloOplDataElements();
      data2.fileName="file"+k;
      opl.addDataSource(data2);
      opl.generate();
    
      if (cplex.solve()) {
         writeln("OBJ = " + cplex.getObjValue());
      } else {
         writeln("No solution");
      }
      opl.postProcess();
     opl.end();
    
    
    }  
    
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多