使用 'main block' 在 CPLEX 求解器中循环
Loop in CPLEX solver with 'main block'
如何将优化模型放入 IBM ILOG CPLEX 求解器的循环中?
基本上我想在每次迭代中更改参数值。
How to measure random seed variability in OPL in How to With OPL
中的小例子
int n=30; // number of random seeds
int d[1..n]; // duration
int o[1..n]; // objective
int iter[1..n]; // iterations
// start of the model we want to test
int Fixed = 100;
int NbWarehouses = 50;
int NbStores = 200;
assert( NbStores > NbWarehouses );
range Warehouses = 1..NbWarehouses;
range Stores = 1..NbStores;
int Capacity[w in Warehouses] =
NbStores div NbWarehouses +
w % ( NbStores div NbWarehouses );
int SupplyCost[s in Stores][w in Warehouses] =
1 + ( ( s + 10 * w ) % 100 );
dvar int Open[Warehouses] in 0..1;
dvar float Supply[Stores][Warehouses] in 0..1;
dexpr int TotalFixedCost = sum( w in Warehouses ) Fixed * Open[w];
dexpr float TotalSupplyCost = sum( w in Warehouses, s in Stores ) SupplyCost[s][w] * Supply[s][w];
minimize TotalFixedCost + TotalSupplyCost;
subject to {
forall( s in Stores )
ctStoreHasOneWarehouse:
sum( w in Warehouses )
Supply[s][w] == 1;
forall( w in Warehouses )
ctOpen:
sum( s in Stores )
Supply[s][w] <= Open[w] * Capacity[w];
}
// end of the model we want to test
main {
thisOplModel.generate();
var sum_d=0;
var sum_o=0;;
var sum_iter=0;
writeln("seed objective iteration runtime");
for(var i=1;i<=thisOplModel.n;i++)
{
var opl=new IloOplModel(thisOplModel.modelDefinition);
opl.generate();
cplex.randomseed=i;
var d1=new Date();
cplex.solve();
var d2=new Date();
thisOplModel.d[i]=d2-d1;
sum_d+=d2-d1;
thisOplModel.d[i]=d2-d1;
thisOplModel.o[i]=Opl.ftoi(Opl.round(cplex.getObjValue()));
sum_o+=thisOplModel.o[i];
thisOplModel.iter[i]=cplex.getNiterations();
sum_iter+=thisOplModel.iter[i];
writeln(i," ",thisOplModel.o[i]," ",thisOplModel.iter[i]," ",
thisOplModel.d[i]/1000);
cplex.clearModel();
}
writeln("-----------------------------------------");
writeln("average ",sum_o/thisOplModel.n," ",
sum_iter/thisOplModel.n," ",sum_d/thisOplModel.n/1000);
writeln("std dev ",Opl.standardDeviation(thisOplModel.o)," ",
Opl.standardDeviation(thisOplModel.iter)," ",Opl.standardDeviation(thisOplModel.d)/1000);
}
如何将优化模型放入 IBM ILOG CPLEX 求解器的循环中? 基本上我想在每次迭代中更改参数值。
How to measure random seed variability in OPL in How to With OPL
中的小例子 int n=30; // number of random seeds
int d[1..n]; // duration
int o[1..n]; // objective
int iter[1..n]; // iterations
// start of the model we want to test
int Fixed = 100;
int NbWarehouses = 50;
int NbStores = 200;
assert( NbStores > NbWarehouses );
range Warehouses = 1..NbWarehouses;
range Stores = 1..NbStores;
int Capacity[w in Warehouses] =
NbStores div NbWarehouses +
w % ( NbStores div NbWarehouses );
int SupplyCost[s in Stores][w in Warehouses] =
1 + ( ( s + 10 * w ) % 100 );
dvar int Open[Warehouses] in 0..1;
dvar float Supply[Stores][Warehouses] in 0..1;
dexpr int TotalFixedCost = sum( w in Warehouses ) Fixed * Open[w];
dexpr float TotalSupplyCost = sum( w in Warehouses, s in Stores ) SupplyCost[s][w] * Supply[s][w];
minimize TotalFixedCost + TotalSupplyCost;
subject to {
forall( s in Stores )
ctStoreHasOneWarehouse:
sum( w in Warehouses )
Supply[s][w] == 1;
forall( w in Warehouses )
ctOpen:
sum( s in Stores )
Supply[s][w] <= Open[w] * Capacity[w];
}
// end of the model we want to test
main {
thisOplModel.generate();
var sum_d=0;
var sum_o=0;;
var sum_iter=0;
writeln("seed objective iteration runtime");
for(var i=1;i<=thisOplModel.n;i++)
{
var opl=new IloOplModel(thisOplModel.modelDefinition);
opl.generate();
cplex.randomseed=i;
var d1=new Date();
cplex.solve();
var d2=new Date();
thisOplModel.d[i]=d2-d1;
sum_d+=d2-d1;
thisOplModel.d[i]=d2-d1;
thisOplModel.o[i]=Opl.ftoi(Opl.round(cplex.getObjValue()));
sum_o+=thisOplModel.o[i];
thisOplModel.iter[i]=cplex.getNiterations();
sum_iter+=thisOplModel.iter[i];
writeln(i," ",thisOplModel.o[i]," ",thisOplModel.iter[i]," ",
thisOplModel.d[i]/1000);
cplex.clearModel();
}
writeln("-----------------------------------------");
writeln("average ",sum_o/thisOplModel.n," ",
sum_iter/thisOplModel.n," ",sum_d/thisOplModel.n/1000);
writeln("std dev ",Opl.standardDeviation(thisOplModel.o)," ",
Opl.standardDeviation(thisOplModel.iter)," ",Opl.standardDeviation(thisOplModel.d)/1000);
}