|
Go to the documentation of this file.
47 #include "objscip/objscip.h"
48 #include "objscip/objscipdefplugins.h"
65 vector<vector<int> >& distance
68 static const string DIMENSION = "DIMENSION";
69 static const string DEMAND_SECTION = "DEMAND_SECTION";
70 static const string DEPOT_SECTION = "DEPOT_SECTION";
71 static const string EDGE_WEIGHT_TYPE = "EDGE_WEIGHT_TYPE";
72 static const string EUC_2D = "EUC_2D";
73 static const string EXPLICIT = "EXPLICIT";
74 static const string LOWER_DIAG_ROW = "LOWER_DIAG_ROW";
75 static const string EDGE_WEIGHT_FORMAT = "EDGE_WEIGHT_FORMAT";
76 static const string EDGE_WEIGHT_SECTION = "EDGE_WEIGHT_SECTION";
77 static const string NODE_COORD_SECTION = "NODE_COORD_SECTION";
78 static const string CAPACITY = "CAPACITY";
80 ifstream file(filename);
84 cerr << "Cannot open file " << filename << endl;
88 string edge_weight_type = "";
89 string edge_weight_format = "";
102 if ( key == DIMENSION )
107 demand.resize(num_nodes, 0);
108 distance.resize(num_nodes);
109 for ( int i = 0; i < num_nodes; ++i)
110 distance[i].resize(i, 0);
113 if ( key == CAPACITY )
118 else if ( key == EDGE_WEIGHT_TYPE )
121 file >> edge_weight_type;
122 if ( edge_weight_type != EUC_2D && edge_weight_type != EXPLICIT )
124 cerr << "Wrong " << EDGE_WEIGHT_TYPE << " " << edge_weight_type << endl;
127 if ( edge_weight_type == EUC_2D )
129 x.resize(num_nodes, 0);
130 y.resize(num_nodes, 0);
133 else if ( key == EDGE_WEIGHT_FORMAT )
136 file >> edge_weight_format;
138 else if ( key == EDGE_WEIGHT_FORMAT + ":" )
140 file >> edge_weight_format;
142 else if ( key == EDGE_WEIGHT_SECTION )
144 if ( edge_weight_type != EXPLICIT || edge_weight_format != LOWER_DIAG_ROW )
146 cerr << "Error. Unsupported edge length type." << endl;
149 for ( int i = 0; i < num_nodes; ++i)
151 for ( int j = 0; j < i; ++j)
159 else if ( key == NODE_COORD_SECTION )
161 if ( edge_weight_type != EUC_2D )
163 cerr << "Error. Data file contains " << EDGE_WEIGHT_TYPE << " " << edge_weight_type << " and " << NODE_COORD_SECTION << endl;
166 for ( int i = 0; i < num_nodes; ++i)
174 cerr << "Error reading " << NODE_COORD_SECTION << endl;
180 for ( int i = 0; i < num_nodes; ++i)
182 for ( int j = 0; j < i; ++j)
184 int dx = x[i] - x[j];
185 int dy = y[i] - y[j];
186 distance[i][j] = int( sqrt(( double)dx*dx + dy*dy) + 0.5 );
190 else if ( key == DEMAND_SECTION )
192 for ( int i = 0; i < num_nodes; ++i)
199 cerr << "Error reading " << DEMAND_SECTION << endl;
205 else if ( key == DEPOT_SECTION )
207 for ( int i = 0; i != -1 ;)
210 if ( i != -1 && i != 1 )
212 cerr << "Error: This file specifies other depots than 1." << endl;
219 getline(file, dummy);
229 int main( int argc, char** argv)
233 cout << "Solving the vehicle routing problem using SCIP." << endl;
234 cout << "Implemented by Andreas Bley." << endl << endl;
236 if ( argc != 2 && argc != 3 )
238 cerr << "Usage: vrp [-h] datafile" << endl;
239 cerr << "Options:" << endl;
240 cerr << " -h Uses hop limit instead of capacity limit for tours."<< endl;
249 static const char* VRP_PRICER_NAME = "VRP_Pricer";
251 vector<vector<int> > distance;
256 if ( read_problem(argv[argc-1], num_nodes, capacity, demand, distance) )
258 cerr << "Error reading data file " << argv[argc-1] << endl;
262 cout << "Number of nodes: " << num_nodes << endl;
266 if ( string( "-h") != argv[1] )
268 cerr << "Unknow option " << argv[2] << endl;
272 int total_demand = 0;
273 for ( int i = 1; i< num_nodes; ++i)
274 total_demand += demand[i];
275 capacity = (num_nodes - 1) * capacity / total_demand;
276 demand.assign(num_nodes, 1);
278 cout << "Max customers per tour: " << capacity << endl << endl;
281 cout << "Max demand per tour: " << capacity << endl << endl;
288 SCIP_CALL( SCIPcreate(&scip) );
294 SCIPprintVersion(scip, NULL);
295 SCIPinfoMessage(scip, NULL, "\n");
298 SCIP_CALL( SCIPincludeDefaultPlugins(scip) );
301 SCIP_CALL( SCIPsetIntParam(scip, "display/verblevel", 5) );
305 SCIP_CALL( SCIPcreateProb(scip, "VRP", 0, 0, 0, 0, 0, 0, 0) );
309 vector< vector<SCIP_VAR*> > arc_var( num_nodes );
310 for ( int i = 0; i < num_nodes; ++i)
312 arc_var[i].resize(i, (SCIP_VAR*) NULL);
313 for ( int j = 0; j < i; ++j)
316 SCIPsnprintf(var_name, 255, "E%d_%d", i, j );
318 SCIP_CALL( SCIPcreateVar(scip,
324 SCIP_VARTYPE_INTEGER,
328 SCIP_CALL( SCIPaddVar(scip, var) );
335 vector< vector<SCIP_CONS*> > arc_con( num_nodes );
336 for ( int i = 0; i < num_nodes; ++i)
338 arc_con[i].resize(i, (SCIP_CONS*)NULL);
339 for ( int j = 0; j < i; ++j)
342 SCIPsnprintf(con_name, 255, "A%d_%d", i, j);
343 SCIP_VAR* index = arc_var[i][j];
344 SCIP_Real coeff = -1;
345 SCIP_CALL( SCIPcreateConsLinear(scip, &con, con_name, 1, &index, &coeff,
358 SCIP_CALL( SCIPaddCons(scip, con) );
364 for ( int i = 1; i < num_nodes; ++i)
367 SCIPsnprintf(con_name, 255, "D%d", i);
368 SCIP_CALL( SCIPcreateConsLinear(scip, &con, con_name, 0, 0, 0,
381 SCIP_CALL( SCIPaddCons(scip, con) );
382 for ( int j = 0; j < num_nodes; ++j)
386 SCIP_CALL( SCIPaddCoefLinear(scip, con, i > j ? arc_var[i][j] : arc_var[j][i], 1.0) );
392 vector<SCIP_CONS*> part_con(num_nodes, (SCIP_CONS*)NULL);
393 for ( int i = 1; i < num_nodes; ++i)
395 SCIP_CONS* con = NULL;
396 SCIPsnprintf(con_name, 255, "C%d", i);
397 SCIP_CALL( SCIPcreateConsLinear( scip, &con, con_name, 0, NULL, NULL,
410 SCIP_CALL( SCIPaddCons(scip, con) );
416 arc_var, arc_con, part_con);
418 SCIP_CALL( SCIPincludeObjPricer(scip, vrp_pricer_ptr, true) );
421 SCIP_CALL( SCIPactivatePricer(scip, SCIPfindPricer(scip, VRP_PRICER_NAME)) );
430 SCIP_CALL( SCIPsolve(scip) );
436 SCIP_CALL( SCIPprintStatistics(scip, NULL) );
438 SCIP_CALL( SCIPprintBestSol(scip, NULL, FALSE) );
446 SCIP_CALL( SCIPfree(&scip) );
448 BMScheckEmptyMemory();
|