【问题标题】:How to count number of items matching a criteria in a tuple in OPL如何计算 OPL 元组中匹配条件的项目数
【发布时间】:2020-12-22 07:39:18
【问题描述】:

问题背景: 我有一个大的 OPL 问题,下面只是其中的一部分。

forall(b in PitBlocks,t in TimePeriods )
  //
 {
   sum(p in Pbd: p.source == b,r in TimePeriods : r <= t ) Xbdt[b][p.dest][r] == sum(p in Pbd: p.source == b,r in TimePeriods : r <= t)ypt[p.id][r];
 } 

在上面的代码中,数据来自一个excel文件:

PitBlocks = {P1,P2,P3....P27}

时间周期 = {1,2,3}

Pbd 是一个元组,其数据如下:

此表有 1972 行。以上是其中的一部分。这个excel表正在读入集合Pbd

tuple Path {
string id;
string source;
string dest;
{string} pitblockSet;
{string} roadPoints; 
{string} dumpblockSet;
{string} others;
float dist;
};

现在使用上面的代码:

forall(b in PitBlocks,t in TimePeriods ) // { sum(p in Pbd: p.source == b,r in TimePeriods : r

在 LP 格式中,我得到以下信息:

 c8677:   4 Xbdt#0#0#0 + 4 Xbdt#0#1#0 + 3 Xbdt#0#2#0 + 3 Xbdt#0#3#0
          + 3 Xbdt#0#4#0 + 3 Xbdt#0#5#0 + 4 Xbdt#0#6#0 + 4 Xbdt#0#7#0
          + 3 Xbdt#0#8#0 + 4 Xbdt#0#9#0 + 4 Xbdt#0#10#0 + 4 Xbdt#0#11#0
          + 4 Xbdt#0#12#0 + 4 Xbdt#0#13#0 + 4 Xbdt#0#14#0 + 4 Xbdt#0#15#0
          + 4 Xbdt#0#16#0 + 4 Xbdt#0#17#0 + 5 Xbdt#0#18#0 + 5 Xbdt#0#19#0
          + 4 Xbdt#0#20#0 + 5 Xbdt#0#21#0 + 5 Xbdt#0#22#0 + 4 Xbdt#0#23#0
          + 5 Xbdt#0#24#0 + 5 Xbdt#0#25#0 + 4 Xbdt#0#26#0 + 4 Xbdt#0#27#0
          - ypt#0#0 - ypt#1#0 - ypt#2#0 - ypt#3#0 - ypt#80#0 - ypt#81#0
          - ypt#82#0 - ypt#83#0 - ypt#160#0 - ypt#161#0 - ypt#162#0 - ypt#163#0
          - ypt#223#0 - ypt#224#0 - ypt#225#0 - ypt#226#0 - ypt#280#0
          - ypt#281#0 - ypt#282#0 - ypt#283#0 - ypt#358#0 - ypt#359#0
          - ypt#360#0 - ypt#361#0 - ypt#421#0 - ypt#422#0 - ypt#423#0
          - ypt#424#0 - ypt#478#0 - ypt#479#0 - ypt#480#0 - ypt#481#0
          - ypt#552#0 - ypt#553#0 - ypt#554#0 - ypt#555#0 - ypt#609#0
          - ypt#610#0 - ypt#611#0 - ypt#612#0 - ypt#666#0 - ypt#667#0
          - ypt#668#0 - ypt#669#0 - ypt#670#0 - ypt#732#0 - ypt#733#0
          - ypt#734#0 - ypt#735#0 - ypt#804#0 - ypt#805#0 - ypt#806#0
          - ypt#807#0 - ypt#808#0 - ypt#864#0 - ypt#865#0 - ypt#866#0
          - ypt#867#0 - ypt#918#0 - ypt#919#0 - ypt#920#0 - ypt#921#0
          - ypt#922#0 - ypt#994#0 - ypt#995#0 - ypt#996#0 - ypt#997#0
          - ypt#998#0 - ypt#1063#0 - ypt#1064#0 - ypt#1065#0 - ypt#1066#0
          - ypt#1117#0 - ypt#1118#0 - ypt#1119#0 - ypt#1120#0 - ypt#1121#0
          - ypt#1195#0 - ypt#1196#0 - ypt#1197#0 - ypt#1198#0 - ypt#1199#0
          - ypt#1255#0 - ypt#1256#0 - ypt#1257#0 - ypt#1258#0 - ypt#1309#0
          - ypt#1310#0 - ypt#1311#0 - ypt#1366#0 - ypt#1367#0 - ypt#1368#0
          - ypt#1369#0 - ypt#1418#0 - ypt#1419#0 - ypt#1420#0 - ypt#1490#0
          - ypt#1491#0 - ypt#1492#0 - ypt#1556#0 - ypt#1557#0 - ypt#1558#0
          - ypt#1613#0 - ypt#1614#0 - ypt#1615#0 - ypt#1616#0 - ypt#1687#0
          - ypt#1688#0 - ypt#1689#0 - ypt#1690#0 - ypt#1750#0 - ypt#1751#0
          - ypt#1752#0  = 0

Xbdt变量前面的前缀4、4、3等是因为Source = P1,Dest = D1在上面的excel数据中出现了4次。

问题: 我不希望以 LP 格式创建前缀,因此我希望将等式的左侧除以以下内容。但我不确定这里的哪个功能会有所帮助,例如卡片、计数等...无法获得合适的功能:

尝试失败:

我知道下面是错误的,但想找到 Xbdt[b][p.dest][r] 的出现次数并除以它

forall(b in PitBlocks,t in TimePeriods )
  //
 {
   sum(p in Pbd: p.source == b,r in TimePeriods : r <= t ) Xbdt[b][p.dest][r]/ count(p in Pbd: p.source == b && p.dest ) == sum(p in Pbd: p.source == b,r in TimePeriods : r <= t)ypt[p.id][r];
 } 

请提出建议。

【问题讨论】:

    标签: cplex opl


    【解决方案1】:

    要在 OPL CPLEX 中计数,您可以使用 https://github.com/AlexFleischerParis/zooopl/blob/master/zoocounttrueconstraints.mod 中的逻辑约束

    int nbKids=300;
    
    // a tuple is like a struct in C, a class in C++ or a record in Pascal
    tuple bus
    {
      key int nbSeats;
      float cost;
    }
    
    // This is a tuple set
    {bus} buses={<40,500>,
        <30,400>,
        <35,450>,
        <20,300>};
    
    // asserts help make sure data is fine
    assert forall(b in buses) b.nbSeats>0;
    assert forall(b in buses) b.cost>0;
    
    // decision variable array
    dvar int+ nbBus[buses];
    
    // objective
    minimize
         sum(b in buses) b.cost*nbBus[b];
         
    // constraints
    subject to
    {
       sum(b in buses) b.nbSeats*nbBus[b]>=nbKids;
       
       // Number of sizes where we have 1 or 2 buses should be at least 3
       
       sum(b in buses) (1<=nbBus[b]<=2) >=3;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多