Originally posted by: MuberraOzmen
Hello,
We are constructing the integer L shaped method for a two stage stochastic program. Actually what we are trying to do is generating an optimality cut using incumbent callback, adding this cut by cut callback and then generating a child node with this new cut. We stuck in using branch callback. We would be very thankful if anyone who have performed something similar to this and know how to use branchcall back can help us. This is our code:
#include <ilcplex/ilocplex.h>
#include <stdlib.h>
#include <math.h>
ILOSTLBEGIN
IloEnv env;
typedef IloArray<IloNumArray> TwoDMatrix;
typedef IloArray<TwoDMatrix> ThreeDMatrix;
//typedef IloArray<ThreeDMatrix> FourDMatrix;
typedef IloArray<IloNumVarArray> TwoDVariable;
typedef IloArray<TwoDVariable> ThreeDVariable;
typedef IloArray<ThreeDVariable> FourDVariable;
typedef IloArray<FourDVariable> FiveDVariable;
//IloInt numCuts = 0;
int NumATMs;
int NumCenters;
int NumScenarios;
/*float L=0;
int Period = 5;
float Capacity;
float cR = 10;
float cO = 20;
int addcut;*/
IloNumArray prob;
TwoDMatrix Distance;
ThreeDMatrix Scenario;
/*IloNum tetaR;
IloNum zbar = IloInfinity;
IloExpr A;
int Sr = 0;*/
ILOINCUMBENTCALLBACK1(OptimalityCutGeneration, TwoDVariable, x, IloNumVar, teta) {
IloNum Oldteta;
TwoDMatrix OldX;
try{
IloEnv env = getEnv();
Oldteta = getValue(teta);
for (int i = 0; i < NumATMs; i++) {
for (int j = 0; j < NumCenters; j++) {
OldX[i][j] = getValue(x[i][j]);
Sr = Sr + OldX[i][j];
}
}
for (int i = 0; i < NumATMs; i++) {
for (int j = 0; j < NumCenters; j++) {
if (OldX[i][j]>0)
{
A += x[i][j];
}
else
{
A += -x[i][j];
}
}
}
A.end();
//Subproblem solution//
IloEnv subenv;
IloModel SubProblem(subenv);
FiveDVariable y(subenv, NumATMs);
for (int i = 0; i < NumATMs; i++){
y[i] = FourDVariable(subenv, NumATMs);
for (int j = 0; j < NumATMs; j++){
y[i][j] = ThreeDVariable(subenv, Period);
for (int t = 0; t < Period; t++){
y[i][j][t] = TwoDVariable(subenv, NumCenters);
for (int k = 0; k < NumCenters; k++){
y[i][j][t][k] = IloNumVarArray(subenv, NumScenarios, 0, 1, ILOINT);
}
}
}
}
ThreeDVariable O(subenv, NumCenters);
for (int k = 0; k < NumCenters; k++){
O[k] = TwoDVariable(subenv, Period);
for (int t = 0; t < Period; t++){
O[k][t] = IloNumVarArray(subenv, NumScenarios, 0, IloInfinity, ILOFLOAT);
}
}
IloExpr ExpCost;
for (int g = 0; g < NumScenarios ; g++){
for (int t = 0; t < Period; t++){
for (int i = 0; i < NumATMs; i++){
for (int j = 0; j < NumATMs; j++){
for (int k = 0; k < NumCenters; k++){
ExpCost += prob[g] * cR*Distance[i][j] * y[i][j][t][k][g];
}
}
}
}
}
for (int g = 0; g < NumScenarios; g++){
for (int t = 0; t < Period; t++){
for (int k = 0; k < NumCenters; k++){
ExpCost += prob[g]*cO*O[k][t][g];
}
}
}
IloObjective Obj_Sub = IloMinimize(subenv, ExpCost);
for (int g = 0; g < NumScenarios; g++){
for (int t = 0; t < Period; t++){
for (int i = 0; i < NumATMs; i++){
IloExpr Const1;
for (int j = 0; j < NumATMs; j++){
for (int k = 0; k < NumCenters; k++){
Const1 += y[i][j][t][k][g];
}
}
SubProblem.add(Const1 == Scenario[i][t][g]);
Const1.end();
}
}
}
for (int g = 0; g < NumScenarios; g++){
for (int t = 0; t < Period; t++){
for (int j = 0; j < NumATMs; j++){
IloExpr Const2;
for (int i = 0; i < NumATMs; i++){
for (int k = 0; k < NumCenters; k++){
Const2 += y[i][j][t][k][g];
}
}
SubProblem.add(Const2 == Scenario[j][t][g]);
Const2.end();
}
}
}
for (int g = 0; g < NumScenarios; g++){
for (int t = 0; t < Period; t++){
for (int j = 0; j < NumATMs; j++){
for (int i = 0; i < NumATMs; i++){
for (int k = 0; k < NumCenters; k++){
SubProblem.add(y[i][j][t][k][g] <= OldX[i][k]);
}
}
}
}
}
for (int g = 0; g < NumScenarios; g++){
for (int t = 0; t < Period; t++){
for (int j = 0; j < NumATMs; j++){
for (int i = 0; i < NumATMs; i++){
for (int k = 0; k < NumCenters; k++){
SubProblem.add(y[i][j][t][k][g] <= OldX[j][k]);
}
}
}
}
}
for (int g = 0; g < NumScenarios; g++){
for (int t = 0; t < Period; t++){
for (int k = 0; k < NumCenters; k++){
IloExpr Const3;
for (int i = 0; i < NumATMs; i++){
for (int j = 0; j < NumATMs; j++){
Const3 += Distance[i][j]*y[i][j][t][k][g];
}
}
SubProblem.add(Const3 - O[k][t][g] <= Capacity);
Const3.end();
}
}
}
//add subtour elimination constraints
IloCplex cplex(subenv);
cplex.extract(SubProblem);
cplex.exportModel("subproblem.lp");
cplex.solve();
tetaR = cplex.getValue(Obj_Sub);
if (tetaR < zbar){
zbar = tetaR;
}
if (Oldteta>=tetaR)
{
addcut = 0;
}
else
{
addcut = 1;
}
}
catch (IloException &e){
cerr << "Error in callback: " << e << endl;
throw;
}
}
ILOUSERCUTCALLBACK5(OptimalityCutAddition, int, addcut, IloNum, tetaR, float, L, IloExpr, A, int, Sr){
if (addcut){
add(teta >= (tetaR - L) * A - (tetaR - L)*(Sr - 1) + L);
} //else yazılması gerekebilir
}
ILOBRANCHCALLBACK1(ChildNodeGenaration, int, addcut){
if (addcut){
makeBranch(const )
//makeBranch; hiç bilmiyoruz nasıl kullanıldığını
} //else yazılması gerekebilir
}
int main(int argc, char **data) {
////////Initialization///////
int NumATMs=0, NumCenters=0, NumScenarios=0;
TwoDMatrix Distance(env);
//////Data file Reading/////
const char* filename = "datafile.txt";
if (argc >1)
filename = data[1];
ifstream file(filename);
if (!file) {
cerr << "ERROR: could not open file '" << filename << "' for reading" << endl;
cerr << "usage: " << data[0] << " <file>" << endl;
throw(-1);
}
file >> NumATMs >> NumCenters >> NumScenarios ;
file.close();
printf("*\n");
const char* filename2 = "Distance.txt";
if (argc >1)
filename = data[1];
ifstream file2(filename2);
if (!file2) {
cerr << "ERROR: could not open file '" << filename2 << "' for reading" << endl;
cerr << "usage: " << data[0] << " <file2>" << endl;
throw(-1);
}
for (int i = 0; i < NumATMs; i++)
{
for (int j = 0; j < NumATMs; j++)
{
file2 >> Distance[i][j];
}
}
file2.close();
/*printf("%d\n", Distance[6][4]);*/
//Distance okunamadı, senaryolar okunmadı
env.out() << "NumATMs: " << NumATMs << endl;
env.out() << "NumCenters: " << NumCenters << endl;
env.out() << "NumScenarios: " << NumScenarios << endl;
printf("NumATMs: %d ",NumATMs);
printf("NumCenters: %d ", NumCenters);
printf("NumScenarios: %d ", NumScenarios);
printf("*\n");
//////First Stage Decision Variables/////
IloNumVar teta(env, 0, IloInfinity, ILOFLOAT);
TwoDVariable x(env, NumATMs);
for (int i = 0; i < NumATMs; i++)
{
x[i] = IloNumVarArray(env, NumCenters, 0, 1, ILOINT);
}
///////Initial RMP//////////
IloModel RMP(env);
IloObjective Obj = IloMinimize(env, teta);
RMP.add(Obj);
for (int i = 0; i < NumATMs; i++) {
IloExpr assign_ATMs(env);
for (int j = 0; j < NumCenters; j++){
assign_ATMs += x[i][j];
}
RMP.add(assign_ATMs == 1);
assign_ATMs.end();
}
IloCplex cplex(RMP);
/*cplex.use(OptimalityCutGeneration(env, x, teta));
cplex.use(OptimalityCutAddition(env, addcut, tetaR, L, A, Sr));
cplex.use(ChildNodeGenaration(env, addcut));*/
cplex.extract(RMP);
cplex.exportModel("RMP_Model.lp");
cplex.solve();
double a, b, c;
a = cplex.getValue(x[5][0]);
b = cplex.getValue(x[5][1]);
printf("%f\n", a);
printf("%f\n", b);
env.end();
printf("*");
return 0;
}
#CPLEXOptimizers#DecisionOptimization