82 vector<vector<int> >& dist
85 const string DIMENSION =
"DIMENSION";
86 const string DEMAND_SECTION =
"DEMAND_SECTION";
87 const string DEPOT_SECTION =
"DEPOT_SECTION";
88 const string EDGE_WEIGHT_TYPE =
"EDGE_WEIGHT_TYPE";
89 const string EUC_2D =
"EUC_2D";
90 const string EXPLICIT =
"EXPLICIT";
91 const string LOWER_DIAG_ROW =
"LOWER_DIAG_ROW";
92 const string EDGE_WEIGHT_FORMAT =
"EDGE_WEIGHT_FORMAT";
93 const string EDGE_WEIGHT_SECTION =
"EDGE_WEIGHT_SECTION";
94 const string NODE_COORD_SECTION =
"NODE_COORD_SECTION";
95 const string CAPACITY =
"CAPACITY";
97 ifstream file(filename);
104 cerr <<
"Cannot open file " << filename << endl;
108 string edge_weight_type =
"";
109 string edge_weight_format =
"";
122 if ( key == DIMENSION )
128 demand.resize(num_nodes, 0);
129 dist.resize(num_nodes);
130 for (
int i = 0;
i < num_nodes; ++
i)
131 dist[
i].resize(
i, 0);
134 if ( key == CAPACITY )
139 else if ( key == EDGE_WEIGHT_TYPE )
142 file >> edge_weight_type;
143 if ( edge_weight_type != EUC_2D && edge_weight_type != EXPLICIT )
145 cerr <<
"Wrong " << EDGE_WEIGHT_TYPE <<
" " << edge_weight_type << endl;
148 if ( edge_weight_type == EUC_2D )
151 x.resize(num_nodes, 0);
152 y.resize(num_nodes, 0);
155 else if ( key == EDGE_WEIGHT_FORMAT )
158 file >> edge_weight_format;
160 else if ( key == EDGE_WEIGHT_FORMAT +
":" )
162 file >> edge_weight_format;
164 else if ( key == EDGE_WEIGHT_SECTION )
166 if ( edge_weight_type != EXPLICIT || edge_weight_format != LOWER_DIAG_ROW )
168 cerr <<
"Error. Unsupported edge length type." << endl;
172 for (
int i = 0;
i < num_nodes; ++
i)
174 for (
int j = 0; j <
i; ++j)
182 else if ( key == NODE_COORD_SECTION )
184 if ( edge_weight_type != EUC_2D )
186 cerr <<
"Error. Data file contains " << EDGE_WEIGHT_TYPE <<
" " << edge_weight_type <<
" and " << NODE_COORD_SECTION << endl;
190 for (
int i = 0;
i < num_nodes; ++
i)
198 cerr <<
"Error reading " << NODE_COORD_SECTION << endl;
204 for (
int i = 0;
i < num_nodes; ++
i)
206 for (
int j = 0; j <
i; ++j)
208 int dx =
x[
i] -
x[j];
209 int dy =
y[
i] -
y[j];
210 dist[
i][j] = int( sqrt((
double)dx*dx + dy*dy) + 0.5 );
214 else if ( key == DEMAND_SECTION )
217 for (
int i = 0;
i < num_nodes; ++
i)
224 cerr <<
"Error reading " << DEMAND_SECTION << endl;
230 else if ( key == DEPOT_SECTION )
232 for (
int i = 0;
i != -1 ;)
235 if (
i != -1 &&
i != 1 )
237 cerr <<
"Error: This file specifies other depots than 1." << endl;
244 (void) getline(file, dummy);
258 cout <<
"Solving the vehicle routing problem using SCIP." << endl;
259 cout <<
"Implemented by Andreas Bley." << endl << endl;
261 if ( argc != 2 && argc != 3 )
263 cerr <<
"Usage: vrp [-h] datafile" << endl;
264 cerr <<
"Options:" << endl;
265 cerr <<
" -h Uses hop limit instead of capacity limit for tours."<< endl;
274 const char* VRP_PRICER_NAME =
"VRP_Pricer";
276 vector<vector<int> > dist;
281 if (
read_problem(argv[argc-1], num_nodes, capacity, demand, dist) )
283 cerr <<
"Error reading data file " << argv[argc-1] << endl;
289 cout <<
"Number of nodes: " << num_nodes << endl;
293 if (
string(
"-h") != argv[1] )
295 cerr <<
"Unknow option " << argv[2] << endl;
299 int total_demand = 0;
300 for (
int i = 1;
i< num_nodes; ++
i)
301 total_demand += demand[
i];
303 if( total_demand == 0.0 )
305 cerr <<
"Total demand is zero!" << endl;
309 capacity = (num_nodes - 1) * capacity / total_demand;
310 demand.assign(num_nodes, 1);
312 cout <<
"Max customers per tour: " << capacity << endl << endl;
315 cout <<
"Max demand per tour: " << capacity << endl << endl;
343 vector< vector<SCIP_VAR*> > arc_var( num_nodes );
344 for (
size_t i = 0;
i < (size_t)num_nodes; ++
i)
347 for (
size_t j = 0; j <
i; ++j)
369 vector< vector<SCIP_CONS*> > arc_con( num_nodes );
370 for (
size_t i = 0;
i < (size_t)num_nodes; ++
i)
373 for (
size_t j = 0; j <
i; ++j)
398 for (
size_t i = 1;
i < (size_t)num_nodes; ++
i)
416 for (
size_t j = 0; j < (size_t)num_nodes; ++j)
428 for (
size_t i = 1;
i < (size_t)num_nodes; ++
i)
451 arc_var, arc_con, part_con);
482 for (
size_t i = 0;
i < (size_t)num_nodes; ++
i)
488 for (
size_t j = 0; j <
i; ++j)
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreate(SCIP **scip)
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPprintVersion(SCIP *scip, FILE *file)
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
SCIP_PRICER * SCIPfindPricer(SCIP *scip, const char *name)
SCIP_RETCODE SCIPactivatePricer(SCIP *scip, SCIP_PRICER *pricer)
SCIP_RETCODE SCIPprintBestSol(SCIP *scip, FILE *file, SCIP_Bool printzeros)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
int SCIPsnprintf(char *t, int len, const char *s,...)
assert(minobj< SCIPgetCutoffbound(scip))
int main(int argc, char **argv)
static SCIP_RETCODE execmain(int argc, char **argv)
static int read_problem(const char *filename, int &num_nodes, int &capacity, vector< int > &demand, vector< vector< int > > &dist)
#define BMScheckEmptyMemory()
SCIP_RETCODE SCIPincludeObjPricer(SCIP *scip, scip::ObjPricer *objpricer, SCIP_Bool deleteobject)
C++ wrapper classes for SCIP.
C++ wrapper for default SCIP plugins.
SCIP_RETCODE SCIPincludeDefaultPlugins(SCIP *scip)
struct SCIP_Cons SCIP_CONS
enum SCIP_Retcode SCIP_RETCODE