/* 09/10/01 This is the default encoding of the delivery variant of the vehicle routing problem with one base and a homogeneous fleet. PRECONDITIONS: 1. ILOG Dispatcher 3.0; 2. Data file in the following format: ************************************* 0 x_base y_base 0 earliest_start latest_end 0 1 x_1 y_1 demand_1 earliest_start_1 lateststart_1 service_time_1 ... i x_i y_i demand_i earliest_start_i lateststart_i service_time_i ... ************************************* The base and customers each are described by seven numbers in a separate line, in this order: (i) index (0 - for the base), (ii and iii) x and y coordinates of the base in the 2D right Cartesian reference frame; (iv) demand>=0 (0 for the base); (v) earliest start; (vi) latest end (for the base) and latest start (for customers); and (vii) service time. 2. Output file; 3. Index of Method: 0 for Guided Local Search, 1 for Tabu Search. 4. Search Parameter: penalty factor for Guided Local Search, tabu tenure for Tabu Search. 5. Index of Limit on Search: enter 0 if you want to set a limit on the number of moves, enter 1 if you want a limit on execution time. 6. Value of limit depending on what you enter as the 5th parameter. POSTCONDITIONS: 1. The first solution generated by the savings heuristic and solution(s) improved by either guided local search or tabu search with a limit (either on the number of moves or on execution time). The information is stored in the specified output file. */ #include #include ILOSTLBEGIN IloNum TimeLimit, MoveLimit; IloNum PenaltyFactor; IloInt TabuTenure; IloBool TypeOfMethod;//0-GLS,1-Tabu; void Info(IloDispatcher dispatcher, ofstream& fout) { IloSolver solver = dispatcher.getSolver(); fout<< "===============" << endl << "Cost : " << dispatcher.getTotalCost() << endl << "Number of vehicles used : " << dispatcher.getNbOfVehiclesUsed() << endl << "Solution : " << endl << dispatcher << endl; } void improveWithGLS_TimeLimitVersion(IloDispatcher dispatcher, IloRoutingSolution solution, IloNHood nhood, ofstream& fout) { IloNumVar cost = dispatcher.getCostVar(); IloEnv env = dispatcher.getEnv(); IloGoal instantiateCost = IloDichotomize(env, cost, IloFalse); IloRoutingSolution rsol = solution.makeClone(env); IloRoutingSolution best = solution.makeClone(env); IloDispatcherGLS dgls(env, PenaltyFactor); IloSearchSelector sel = IloMinimizeVar(env,dgls.getPenalizedCostVar()); IloGoal move = IloSingleMove(env, rsol, nhood, dgls, sel, instantiateCost); move = move && IloStoreBestSolution(env, best); IloSolver solver = dispatcher.getSolver(); IloCouple(nhood, dgls); clock_t tStart = clock()/CLK_TCK, time = tStart; while (time <= tStart + TimeLimit) { if (solver.solve(move)) { fout << "Cost = "<.exe \n"; env.out() <<" TypeOfMethod <0-GLS,1-TS> SearchParam \n"; env.out() <<" Limit <0-move, 1-time> LimitValue \n"; return 0; } char str[9]; cout <<"Problem "<> rubbish >> depotX >> depotY >> rubbish >> openTime >> closeTime >> rubbish; outfile<<"Solutions to "<= openTime); IloVisit last(depot, "Depot"); mdl.add(last.getCumulVar(time) <= closeTime); char name[16]; sprintf(name, "Vehicle %d", j); IloVehicle vehicle(first, last, name); vehicle.setCost(length, 1.0); vehicle.setCapacity(weight, capacity); mdl.add(vehicle); } for (IloInt i = 0; i < nbOfVisits; i++) { IloInt id; // visit identifier IloNum x, y, quantity, minTime, maxTime, dropTime; infile >> id >> x >> y >> quantity >> minTime >> maxTime >> dropTime; IloNode customer(env, x, y); char name[16]; sprintf(name, "%d", id); IloVisit visit(customer, name); mdl.add(visit.getDelayVar(time) == dropTime); mdl.add(visit.getTransitVar(weight) == quantity); mdl.add(minTime <= visit.getCumulVar(time) <= maxTime); mdl.add(visit); } infile.close(); IloSolver solver(mdl); IloDispatcher dispatcher(solver); IloRoutingSolution solution(mdl); //////////////////////////////////////////////// // // constructing the 1st solution with savings // //////////////////////////////////////////////// IloGoal instantiateCost = IloDichotomize(env, dispatcher.getCostVar(), IloFalse); IloGoal restoreSolution = IloRestoreSolution(env, solution); IloGoal goal = IloSavingsGenerate(env) && instantiateCost; if (!solver.solve(goal)) { solver.out() << "A first solution can't be constructed. Try to add more vehicles." << endl; return 0; } /////////////////////////////////////////// // // outputting the first solution // /////////////////////////////////////////// Info(dispatcher,outfile); solution.store(solver); //////////////////////////////////////////////// // // constructing the neighbourhood of a solution // //////////////////////////////////////////////// IloNHood nhood = IloTwoOpt(env) + IloOrOpt(env) + IloRelocate(env) + IloExchange(env) + IloCross(env); //////////////////////////////////////////////// // // improving the first solution // //////////////////////////////////////////////// if (TypeOfMethod==0) { if (TimeLimit>0) { improveWithGLS_TimeLimitVersion(dispatcher,solution,nhood,outfile); } else { improveWithGLS_MoveLimitVersion(dispatcher,solution,nhood,outfile); } } else { if (TimeLimit>0) { improveWithTabu_TimeLimitVersion(dispatcher,solution,nhood,outfile); } else { improveWithTabu_MoveLimitVersion(dispatcher,solution,nhood,outfile); } } /////////////////////////////////////////// // // outputting the improved solution // /////////////////////////////////////////// Info(dispatcher,outfile); } catch(IloException& ex) { cerr << "Error: " << ex << endl; } env.end(); return 0; }