Error in solving a model with two decision variables
AnsweredHi,
I am trying to solve a robotic assembly line balancing problem and I am receiving the following error message while running the code 'AddConstr is for linear constraints; use AddQConstr to create a quadratic constraint'. Could you please help? Thanks in advance.
#include "gurobi_c++.h"
#include <iostream>
#include<ctime>
#include <cstdlib>
#include<fstream>
#include<iomanip>
#include<stdio.h>
//#include<windows.h>
#include <time.h>
#include <sstream>
#include <string.h>
#include <assert.h>
using namespace std;
FILE *yfile;
//
void read_file(int);
int activity, numOfResources, * noofSuccessors, * maxResource, maxPeakPower, maxWage, dueDate;
int** projectResource, ** allConst, nPconst, **projectDurationReal, **projectPowerLoad, **projectWage;
int noSuccessors, ** constList, local_max;
int sumofPT = 0, allOP = 0, *PT_array, *ess, *lss, bigM;
void printSolutionRCPSP(GRBModel& model, GRBVar Cmax);
double carbon, *humanFactor, w1, w2, unitTardiness, unitEarliness, unitEnergy, unitWage;
int totalFixed;
//
int n_task, n_ws, n_robo;
int** task_time;
void read_RALB();
int** predence_const, numofconst = -1;
int main(int argc,
char* argv[])
{
GRBEnv* env = 0;
try
{
read_RALB();
env = new GRBEnv();
GRBModel model = GRBModel(*env);
model.getEnv().set(GRB_DoubleParam_TimeLimit, 60);
//sum of processing times
sumofPT = 0;
for (int local_i = 0; local_i < n_task; local_i++)
{
int temp = task_time[local_i][0];
for (int local_j = 1; local_j < n_robo; local_j++)
{
if (temp< task_time[local_i][local_j])
sumofPT += task_time[local_i][local_j];
}
}
//create decision variables that equals 1 if activity is started on machine that is run by operatorer type at time (otherwise 0)
PT_array = new int[sumofPT];
ess = new int[n_task];
lss = new int[n_task];
for(int n=0;n< n_task;n++){
ess[n]=0;
lss[n]=sumofPT-1;
}
/////////
GRBVar** y = 0;
y = new GRBVar * [n_task];
for (int local_i = 0; local_i < n_task; local_i++)
{
y[local_i] = model.addVars(n_ws, GRB_BINARY);
model.update();
for (int local_j = 0; local_j < n_ws; local_j++)
{
ostringstream vname;
vname << "Y_" << local_i << "." << local_j;
if (local_i == n_task - 1) y[local_i][local_j].set(GRB_DoubleAttr_Obj, local_j);
y[local_i][local_j].set(GRB_StringAttr_VarName, vname.str());
}
}
model.update();
GRBVar** z = 0;
z = new GRBVar * [n_robo];
for (int local_i = 0; local_i < n_robo; local_i++)
{
z[local_i] = model.addVars(n_ws, GRB_BINARY);
model.update();
for (int local_j = 0; local_j < n_ws; local_j++)
{
ostringstream vname;
vname << "Z_" << local_i << "." << local_j;
if (local_i == n_task - 1) z[local_i][local_j].set(GRB_DoubleAttr_Obj, local_j);
z[local_i][local_j].set(GRB_StringAttr_VarName, vname.str());
}
}
model.update();
////////
int local_k = 0;
int local_a = 0;
for (int local_i = 0; local_i < n_task; local_i++)
{
GRBQuadExpr trot1 = 0;
GRBQuadExpr trot2 = 0;
for (int local_j = 0; local_j < numofconst; local_j++)
{
local_k = predence_const[local_j][1];
for (; local_a < numofconst; local_a++)
{
if (local_k == local_i)
{
for (int local_b = 0; local_b < n_ws; local_b++)
{
for (int local_c = 0; local_c < n_robo; local_c++)
{
trot1 += y[local_i][local_b] * z[local_c][local_b] * task_time[local_i][local_b];
}
}
for (int local_b = 0; local_b < n_ws; local_b++)
{
for (int local_c = 0; local_c < n_robo; local_c++)
{
trot2 += y[predence_const[local_i][0]][local_b] * z[local_c][local_b] * task_time[predence_const[local_i][0]][local_b];
}
}
}
}
}
model.addConstr(trot1 >= trot2);
}
model.update();
//constraint: each task can be allocated to one station only
for (int local_i = 0; local_i < n_task; local_i++)
{
GRBLinExpr trot1 = 0;
for (int local_c = 0; local_c < n_ws; local_c++)
{
trot1 += y[local_i][local_c];
}
model.addConstr(trot1 ==1);
}
model.update();
//
//constraint:each robo can be allocated to one station only
for (int local_j = 0; local_j < n_robo; local_j++)
{
GRBLinExpr trot2 = 0;
for (int local_c = 0; local_c < n_ws; local_c++)
{
trot2 += z[local_j][local_c];
}
model.addConstr(trot2 == 1);
}
model.update();
//constraint:all tasks cannot be allocated to one station only
//
GRBQuadExpr CT = 0;
for (int local_i = 0; local_i < n_ws; local_i++)
{
for (int local_k = 0; local_k < n_robo; local_k++)
{
for (int local_j = 0; local_j < n_task; local_j++)
{
CT += (task_time[local_k][local_j] * y[local_j][local_i]* z[local_k][local_i]);
}
}
}
model.update();
model.setObjective(CT, GRB_MINIMIZE);
model.optimize();
int optimstatus = model.get(GRB_IntAttr_Status);
//model.write("/Users/Downloads.lp");
cout << "Obj: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
}
catch (GRBException e)
{
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
}
catch (...)
{
cout << "Exception during optimization" << endl;
}
delete env;
//
delete [] maxResource;
delete[] PT_array;
return 0;
}
void read_RALB()
{
char file_name[80];
sprintf(file_name, "RALB_Data.txt");
ifstream myfile;
myfile.open(file_name, ios::in);
myfile >> n_task;
myfile >> n_ws;
myfile >> n_robo;
task_time = new int* [n_task];
for (int local_i = 0; local_i < n_task; local_i++)
task_time[local_i] = new int[n_robo];
for (int local_i = 0; local_i < n_task; local_i++)
{
for (int local_j = 0; local_j < n_robo; local_j++)
myfile >> task_time[local_i][local_j];
}
predence_const = new int*[n_task * 2];//
for (int local_l = 0; local_l < n_task * 2; local_l++)
predence_const [local_l] = new int [2];
//read data for precedence relationship
int temp;
for (int local_i = 0; ; local_i++)
{
myfile >> temp;
if (temp != -1)
{
numofconst++;
predence_const [numofconst][0]= temp;
myfile >> temp;
predence_const[numofconst][1] = temp;
}
else
break;
}
myfile.close();
//
cout << endl << endl;
for (int local_i = 0; local_i< numofconst; local_i++)
cout << endl << predence_const[local_i][0] <<" "<< predence_const[local_i][1];
}
void printSolutionRCPSP(GRBModel& model, GRBVar Cmax)
{
if (model.get(GRB_IntAttr_Status) == GRB_OPTIMAL)
cout << Cmax.get(GRB_DoubleAttr_X);
else
{
cout << "No solution" << endl;
}
}
-
Hi Mohammed,
You are creating quadratic expressions (QuadExpr objects) trot1 and trot2. When you use them in a constraint you will be creating a quadratic constraint and they needed to be added with the addQConstr method, as suggested by the error message.
I.e. replace
model.addConstr(trot1 ==1);
with
model.addQConstr(trot1 ==1);
and similarly for other instances where you have used addConstr with quadratic expressions.
- Riley
0 -
Dear Riely,
Thank you very much for your comment. I have changed the model and its running. However, I face another issue. It shows that the model has got an optimal result, but the actual optimal result is lower than that (since it is a minimization problem. I have implemented the mathematical model presented in this paper (page 1067-1068): https://www.sciencedirect.com/science/article/pii/S0360835208002222
Could please help?// test_gurobi.cpp : This file contains the 'main' function. Program execution begins and ends there.
///* Copyright 2022, Gurobi Optimization, LLC */
/* Solve the classic diet model, showing how to add constraints
to an existing model. */#include "gurobi_c++.h"
#include <iostream>
#include<ctime>
#include <cstdlib>
#include<fstream>
#include<iomanip>
#include<stdio.h>
//#include<windows.h>
#include <time.h>
#include <sstream>
#include <string.h>
#include <assert.h>
using namespace std;
FILE* yfile;//
void read_file(int);
int activity, numOfResources, * noofSuccessors, * maxResource, maxPeakPower, maxWage, dueDate;
int** projectResource, ** allConst, nPconst, ** projectDurationReal, ** projectPowerLoad, ** projectWage;
int noSuccessors, ** constList, local_max;
int sumofPT = 0, allOP = 0, * PT_array, * ess, * lss, bigM;
void printSolutionRCPSP(GRBModel& model, GRBVar Cmax);
double carbon, * humanFactor, w1, w2, unitTardiness, unitEarliness, unitEnergy, unitWage;
int totalFixed;
//
int n_task, n_ws, n_robo;
int** task_time;void read_RALB();
int** predence_const, numofconst = -1;int main(int argc,
char* argv[])
{
GRBEnv* env = 0;
try
{
read_RALB();
env = new GRBEnv();
GRBModel model = GRBModel(*env);
model.getEnv().set(GRB_DoubleParam_TimeLimit, 120);
model.getEnv().set(GRB_IntParam_NonConvex, 2);//sum of processing times
sumofPT = 0;
for (int local_i = 0; local_i < n_task; local_i++)
{
int temp = task_time[local_i][0];
for (int local_j = 1; local_j < n_robo; local_j++)
{
if (temp < task_time[local_i][local_j])
temp = task_time[local_i][local_j];
}
sumofPT += temp;
}
//create decision variables that equals 1 if activity is started on machine that is run by operatorer type at time (otherwise 0)
PT_array = new int[sumofPT];
ess = new int[n_task];
lss = new int[n_task];
for (int n = 0; n < n_task; n++) {
ess[n] = 0;
lss[n] = sumofPT - 1;
}
/////////GRBVar** y = 0;
y = new GRBVar * [n_task];for (int local_i = 0; local_i < n_task; local_i++)
{
y[local_i] = model.addVars(n_ws, GRB_BINARY);
model.update();for (int local_j = 0; local_j < n_ws; local_j++)
{
ostringstream vname;
vname << "Y_" << local_i << "." << local_j;if (local_i == n_task - 1) y[local_i][local_j].set(GRB_DoubleAttr_Obj, local_j);
y[local_i][local_j].set(GRB_StringAttr_VarName, vname.str());}
}
model.update();
GRBVar** z = 0;
z = new GRBVar * [n_robo];for (int local_i = 0; local_i < n_robo; local_i++)
{
z[local_i] = model.addVars(n_ws, GRB_BINARY);
model.update();for (int local_j = 0; local_j < n_ws; local_j++)
{
ostringstream vname;
vname << "Z_" << local_i << "." << local_j;if (local_i == n_robo - 1) z[local_i][local_j].set(GRB_DoubleAttr_Obj, local_j);
z[local_i][local_j].set(GRB_StringAttr_VarName, vname.str());}
}
model.update();
////
int local_k = 0;
int local_a = 0;
for (int local_i = 0; local_i < n_task; local_i++)
{for (; local_a < (numofconst+1); local_a++)
{
if (local_k == local_i)
{
GRBLinExpr tr1 = 0;
GRBLinExpr tr2 = 0;for (int local_b = 0; local_b < n_ws; local_b++)
{
tr1 += y[local_i][local_b] * local_b;
}
for (int local_b = 0; local_b < n_ws; local_b++)
{
tr2 += y[predence_const[local_a][0]][local_b] * local_b;
}model.addConstr(tr2 >= tr1);
}
else
break;
}
}
model.update();
////////
for (int local_i = 0; local_i < n_task; local_i++)
{
GRBLinExpr trot1 = 0;
for (int local_c = 0; local_c < n_ws; local_c++)
{
trot1 += y[local_i][local_c];
}
model.addConstr(trot1 == 1);
}
model.update();
//////constraint:each robo can be allocated to one station only
/*for (int local_j = 0; local_j < n_robo; local_j++)
{
GRBLinExpr trot2 = 0;
for (int local_c = 0; local_c < n_ws; local_c++)
{
trot2 += z[local_j][local_c];
}
model.addConstr(trot2 == 1);
}
model.update();*///constraint:each robo can be allocated to one station only
for (int local_c = 0; local_c < n_ws; local_c++)
{
GRBLinExpr trot3 = 0;
for (int local_j = 0; local_j < n_robo; local_j++)
{
trot3 += z[local_j][local_c];
}
model.addConstr(trot3 == 1);
}
model.update();//constraint:all tasks cannot be allocated to one station only
//
GRBVar CT = model.addVar(1, INFINITY, 1, GRB_INTEGER);
GRBQuadExpr statTime;for (int local_i = 0; local_i < n_ws; local_i++)
{
statTime = 0;
for (int local_j = 0; local_j < n_task; local_j++)
{
for (int local_k = 0; local_k < n_robo; local_k++)
{
statTime += (task_time[local_j][local_k] * y[local_j][local_i] * z[local_k][local_i]);
}}
model.addQConstr(CT >= statTime);
}
model.update();GRBLinExpr minCT = CT;
model.update();model.setObjective(minCT, GRB_MINIMIZE);
model.optimize();
int optimstatus = model.get(GRB_IntAttr_Status);
//model.write("/Users/Downloads.lp");cout << "Obj: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
cout << endl;
for (int local_i = 0; local_i < n_task; local_i++)
{
for (int local_c = 0; local_c < n_ws; local_c++)
{
cout << y[local_i][local_c].get(GRB_DoubleAttr_X) << " ";
}cout << endl << "gap" << endl;
}cout << endl << endl << "robo" << endl;
for (int local_c = 0; local_c < n_ws; local_c++)
{
for (int local_i = 0; local_i < n_robo; local_i++)
{
cout << z[local_i][local_c].get(GRB_DoubleAttr_X) << " ";
}
cout << endl << "gap" << endl;
}
cout << endl;
}catch (GRBException e)
{
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
}
catch (...)
{
cout << "Exception during optimization" << endl;
}delete env;
//
delete[] maxResource;
delete[] PT_array;
return 0;
}void read_RALB()
{
char file_name[80];
sprintf(file_name, "RALB_Data.txt");
ifstream myfile;myfile.open(file_name, ios::in);
myfile >> n_task;
myfile >> n_ws;
myfile >> n_robo;task_time = new int* [n_task];
for (int local_i = 0; local_i < n_task; local_i++)
task_time[local_i] = new int[n_robo];for (int local_i = 0; local_i < n_task; local_i++)
{
for (int local_j = 0; local_j < n_robo; local_j++)
myfile >> task_time[local_i][local_j];
}predence_const = new int* [n_task * 3];//
for (int local_l = 0; local_l < n_task * 3; local_l++)
predence_const[local_l] = new int[2];//read data for precedence relationship
int temp;
for (int local_i = 0; ; local_i++)
{
myfile >> temp;
if (temp != -1)
{
numofconst++;
predence_const[numofconst][0] = temp;
cout << endl << temp;
myfile >> temp;
predence_const[numofconst][1] = temp;
cout << " " << temp;
}else
break;}
myfile.close();
//
cout << endl << endl;
for (int local_i = 0; local_i < numofconst+1; local_i++)
cout << endl << predence_const[local_i][0] << " " << predence_const[local_i][1];}
void printSolutionRCPSP(GRBModel& model, GRBVar Cmax)
{
if (model.get(GRB_IntAttr_Status) == GRB_OPTIMAL)
cout << Cmax.get(GRB_DoubleAttr_X);
else
{
cout << "No solution" << endl;
}}
0 -
Hi Mohammad,
Are you able to force the solver to take the optimal solution you are expecting, via setting lower and upper bounds on decision variables to fix them, and then verify that the solver considers it feasible?
- Riley
0 -
Thanks, Riley. I debug the model and identified the issue. The representation of the precedence constraint was incorrect in the model and therefore, it shows infeasible results.
0
Please sign in to leave a comment.
Comments
4 comments