如何在 Cplex Script流控制中向现有模型添加新约束?

问题描述

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

解决方法

我不确定这是否是最佳方法(但我没有找到更好的方法),但是如果您的约束具有已知结构,您可以(在运行时)编辑 .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
,

/* 很多时候,在解决模型之后,我们需要添加新的变量和约束。我们可以通过编写新模型来做到这一点,但我们也可以逐步做到这一点。 假设我们首先需要知道如果我们需要相同数量的 40 个座位和 30 个座位的公共汽车,然后在模型中允许 50 个座位的公共汽车会发生什么。 我们可以写 int nbKids=300; 浮动成本总线40=500; 浮动成本总线30=400; float costBus50=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 "," 40 seats buses and "," 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,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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...