【问题标题】:Single-source and multi-destination problem in CPLEX/Docplex?CPLEX/Docplex 中的单源和多目标问题?
【发布时间】:2021-04-22 04:46:33
【问题描述】:

我们能否将 CPLEX/Docplex 用于网络中的单源和多目标问题?例如,在一次行程中将车辆从源头路由到多个目的地,从而最大限度地缩短总行程时间。

【问题讨论】:

    标签: cplex constraint-programming docplex operations-research docplexcloud


    【解决方案1】:

    https://community.ibm.com/community/user/datascience/communities/community-home/digestviewer/viewthread?GroupId=5557&MessageKey=a7f94f07-bb8d-420a-b82e-6c45525f6949&CommunityKey=ab7de0fd-6f43-47a9-8261-33578a231bb7&tab=digestviewer&ReturnUrl=%2fcommunity%2fuser%2fdatascience%2fcommunities%2fcommunity-home%2fdigestviewer%3fcommunitykey%3dab7de0fd-6f43-47a9-8261-33578a231bb7%26tab%3ddigestviewer 有同样的问题

    嗨,

    您可以查看 tsp OPL 示例

    examples/opl/models/TravelingSalesmanProblem
    

    如果你想做单一来源和多目的地,你可以改变目标

    minimize sum (<i,j> in Edges) dist[<i,j>]*x[<i,j>];​
    

    minimize sum (<i,j> in Edges) dist[<i,j>]*x[<i,j>]-max(j in Cities:<1,j> in Edges) dist[<1,j>]*x[<1,j>];​
    

    你在https://raw.githubusercontent.com/IBMDecisionOptimization/cplex_code_examples/master/docplex/tsp.py的python docplex中有同样的例子

    对于您的具体实例:

    using CP;
    
    execute
    {
      cp.param.timelimit=10;
    }
    
    {string} nodes={"O","A","B","C","D","E","T"};
    
    tuple edge
    {
      key string o;
      key string d;
      int time;
    }
    
    {edge} edges with o,d in nodes=
    {
      <"O","A",40>,
      <"O","B",60>,
      <"O","C",50>,
      <"A","B",10>,
      <"C","B",20>,
      <"A","D",70>,
      <"B","D",55>,
      <"B","E",40>,
      <"D","E",10>,
      <"D","T",60>,
      <"E","T",80>
    };
    
    string origin="O";
    {string} targets={"A","C"};
    int bigvalue=1000;
    int repeat=3;
    range ranks=1..repeat;
    
    {edge} edgeswithsym=edges union {<d,o,t> | <o,d,t> in edges};
    
    {edge} transitions=edgeswithsym union {<o,d,bigvalue> | o,d in nodes: <o,d> not in edgeswithsym};
    
    tuple triplet {int id1; int id2; int value;};
    {triplet} M = {<ord(nodes,tr.o)+1,ord(nodes,tr.d)+1,tr.time> | tr in transitions};
    
    assert card(transitions)==card(nodes)*(card(nodes));
    
    // Interval for visiting a node
    dvar interval itvs[nodes][ranks] optional;
    
    // Sequence means visits
    dvar sequence seq in all(n in nodes,r in ranks)itvs[n][r] types 
    all(n in nodes,r in ranks)(ord(nodes,n)+1); 
    
    // First we want to minimize the time for latest visit
    // Second we want to minimize present intervals
    minimize 
    staticLex(max(t in targets) min(r in ranks) startOf(itvs[t,r],bigvalue),
    sum(n in nodes,r in ranks) presenceOf(itvs[n][r]));
    subject to
    {
      // We visit origin at time 0
      startOf(itvs[origin,1])==0;
      
      // origin and destinations should be present
      presenceOf(itvs[origin,1])==1;
      forall(t in targets) presenceOf(itvs[t,1])==1;
      
      // noOverlap constraint will enforce time matrix
      noOverlap(seq,M,true);
      
      // break sym
      forall(n in nodes) forall(r in ranks:r!=1) 
        presenceOf(itvs[n,r-1])>=presenceOf(itvs[n,r]);
      
    }
    
    int nbActiveIntervals=sum(n in nodes,r in ranks) presenceOf(itvs[n][r]);
    range R=1..nbActiveIntervals;
    
    // Display solution
    execute {
      
    
      writeln(origin);
      var s=seq.first(); 
      for(var i in R) 
      {
       if (i!=nbActiveIntervals)
          writeln(Opl.item(nodes,-1+Opl.typeOfNext(seq,s,bigvalue,0)));
       s=seq.next(s); 
       
      } 
       
    }
    
    /*
    
    gives
    
    O
    A
    B
    C
    
    */
    

    【讨论】:

    • 我查看了您提供的示例。我的问题有点不同。就我而言,我有一个连接的网络,我想访问一组目的地,这可能也需要访问中间节点,因为源节点和目标节点之间可能没有直接边缘。我想访问所有目的地,包括中间节点(不是所有节点,只有那些有助于在最短时间完成旅行的节点)。例如,此链接上的网络link。源可以是 O,目标可以是 A、C 和 T。
    • 然后您可以尝试从github.com/AlexFleischerParis/howtowithopl/blob/master/… 开始,并使用 noOverlap 和时间矩阵,并有可选的间隔来模拟一个节点可能不会被访问或多次访问
    猜你喜欢
    • 2022-09-30
    • 1970-01-01
    • 2019-07-20
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    相关资源
    最近更新 更多