【问题标题】:How can I add new constraints to existing model in Cplex Script (flow control)?如何在 Cplex 脚本(流控制)中向现有模型添加新约束?
【发布时间】:2021-01-23 18:09:24
【问题描述】:

在我的启发式算法中,我使用不同的数据多次求解模型,每次求解后,我需要向现有模型添加一些新约束并再次求解。我想在 Cplex Script(流控制)中执行此操作。

【问题讨论】:

    标签: cplex opl flow-control


    【解决方案1】:

    我不确定这是否是最佳方法(但我没有找到更好的方法),但如果您的约束具有已知结构,您可以(在运行时)编辑 .dat 中的一组边界文件并让 CPLEX 从中生成约束。

    dvar float k;
    
    {float} bounds = ...; //data.dat: bounds = {4.0};
    
    main {
      var model = thisOplModel
      model.generate()
      cplex.solve()
      writeln(cplex.getObjValue())
    
      var model2 = new IloOplModel(model.modelDefinition, cplex)
      var data = model.dataElements
      data.bounds.add(3.0)
      model2.addDataSource(data)
      model2.generate()
      cplex.solve()
      writeln(cplex.getObjValue())
    }
    
    maximize k;
    
    subject to {
      forall (b in bounds) k <= b;
    }
    

    然后是输出

    4
    3
    

    【讨论】:

      【解决方案2】:

      /* 很多时候,在求解模型之后,我们需要添加新的变量和约束。我们可以通过编写新模型来做到这一点,但我们也可以渐进式地做到这一点。 假设我们首先需要知道如果我们需要有相同数量的 40 座和 30 座公共汽车,然后在模型中允许 50 座公共汽车会发生什么。 我们可以写 诠释 nbKids=300; 浮动成本Bus40=500; 浮动成本Bus30=400; 浮动成本Bus50=700;

          dvar int+ nbBus40;
          dvar int+ nbBus30;
          dvar int+ nbBus50;
           
          minimize
           costBus40*nbBus40  +nbBus30*costBus30+nbBus50*costBus50;
           
          subject to
          {
           ctKids:40*nbBus40+nbBus30*30+nbBus50*50>=nbKids;
           
           nbBus30==nbBus40;
           nbBus50==0;
          }
          execute DISPLAY_After_SOLVE
          {
          writeln("The minimum cost is ",costBus40*nbBus40  +nbBus30*costBus30+costBus50*nbBus50);
          writeln("We will use ",nbBus40," 40 seats buses ",nbBus30," 30 seats buses and ",
          nbBus50," buses 50 seats");
          }
      which will give
       
          The minimum cost is 4500
          We will use 5 40 seats buses 5 30 seats buses and 0 buses 50 seats
      and then if we comment
           nbBus50==0;
      which means we allow 50 seats buses then we ll get
       
          The minimum cost is 4100
          We will use 3 40 seats buses 3 30 seats buses and 2 buses 50 seats
      But to do that we generate 3 times the matrix which can take time.
       
      We can do that in a main and be incremental. And then we do not generate new matrixes but rely on incremental changes.
      The technique is simply to have spare decision variables and constraints:
      */
      
       
      
          int nbKids=300;
          float costBus40=500;
          float costBus30=400;
           
          dvar int+ nbBus40;
          dvar int+ nbBus30;
          dvar int+ emptyVar;
           
          minimize
           costBus40*nbBus40  +nbBus30*costBus30;
           
          subject to
          {
           ctKids:40*nbBus40+nbBus30*30>=nbKids;
           
           ctEmpty:0<=0;
      
          }
      
          execute DISPLAY_After_SOLVE
          {
          writeln("The minimum cost is ",costBus40*nbBus40  +nbBus30*costBus30);
          writeln("We will use ",nbBus40," 40 seats buses and ",nbBus30," 30 seats buses ");
          writeln();
          }
      
          main
          {
          thisOplModel.generate();
      
          writeln("Basic model");
      
          cplex.solve();
          thisOplModel.postProcess();
      
          writeln("Let us add a row : saying that nbBus40 and nbBus30 should be equal");
      
          thisOplModel.ctEmpty.setCoef(thisOplModel.nbBus40,1);
          thisOplModel.ctEmpty.setCoef(thisOplModel.nbBus30,-1);
          thisOplModel.ctEmpty.setBounds(0,0);
          cplex.solve();
          thisOplModel.postProcess();
      
          writeln("Let us add a column : saying that nbBus50 could also be used and their cost is 700");
          cplex.setObjCoef(thisOplModel.emptyVar,700);
          thisOplModel.ctKids.setCoef(thisOplModel.emptyVar,50);
          cplex.solve();
          writeln("The minimum cost is ",
          thisOplModel.costBus40*thisOplModel.nbBus40.solutionValue  +thisOplModel.nbBus30.solutionValue*thisOplModel.costBus30
          +700*thisOplModel.emptyVar.solutionValue);
          writeln("We will use ",thisOplModel.nbBus40.solutionValue," 40 seats buses ",thisOplModel.nbBus30.solutionValue,
          " 30 seats buses and "+thisOplModel.emptyVar.solutionValue," 50 seats buses");
          }
      
      /*
      gives
       
          Basic model
          The minimum cost is 3800
          We will use 6 40 seats buses and 2 30 seats buses
          Let us add a row : saying that nbBus40 and nbBus30 should be equal
          The minimum cost is 4500
          We will use 5 40 seats buses and 5 30 seats buses
          Let us add a column : saying that nbBus50 could also be used and their cost is 700
          The minimum cost is 4100
          We will use 3 40 seats buses 3 30 seats buses and 2 50 seats buses
      Of course we get the same results. 
      */
      

      来自https://www.linkedin.com/pulse/making-decision-optimization-simple-alex-fleischer/

      Adding rows and columns incrementally

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多