// Set components[i] to the representative of the // component that contains the vertex i. void getComponents (IloCplex &cplex, const IloArray <IloBoolVarArray>& solution, vector <int>& components) { // The size of the graph. int n = solution.getSize(); // Each vertex is a component itself. for (int i = 0; i < n; i++) components[i] = i; // For each 1 in the incidence matrix, // join the components of these vertex. for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) if (cplex.getValue (solution[i][j]) == 1) join (components, i, j); }
// Finds the total path if there's no irregularity or an sub-path that // contains I and not I - n (Infeasible for family (5)) void getPath (const IloCplex& cplex, const IloArray <IloBoolVarArray>& solution, vector <int>& P, vector<int>& VP, int src, const vector< Client > &precedences, bool reverse) { // The depot always belongs to P P.push_back(src); // Mark the vertex alread visited on the path vector< bool > visited ( solution.getSize(), false ); visited [src] = true; // Each iteration finds the next vertex on the path while ( P.size() < (size_t) solution.getSize() ) { // Finds the next vertex on the path (after src on the route) int v; for (v = ((reverse && (P.size() == 1)) ? 1 : 0); v < solution [src].getSize(); v++) { if ((cplex.getValue (solution [src][v])) && (visited [v] == false) ) break; } // There must be such a vertex v (This solution is TSP feasible) //assert (v < solution.getSize()); // Testing infeasibility (Searching in the precedence rules) for (size_t i = 0; i < precedences.size(); i++) { // If v is a location in this pair (rule) if (precedences[i].delivery == v || precedences[i].pickup == v) { // Adding v to the path and starting over with src == v; P.push_back(v); src = v; visited [v] = true; // Checking infeasibility if (!reverse) { // If v is a delivery vertex and its pickup wasn't visited yet if ((precedences[i].delivery == v) && (visited [ precedences[i].pickup ] == false)) { getCutComplement (visited, VP); return; } } else { // If v is a pickup vertex and its delivery wasn't visited yet if ((precedences[i].pickup == v) && (visited [ precedences[i].delivery ] == false)) { getCutComplement (visited, VP); return; } } // v is feasible break; } } // Test other vertex at the while } }
ILOSTLBEGIN int main(int argc, char** argv) { IloEnv env ; try { IloModel model(env) ; IloCplex cplex(env) ; // Get data // Import data from file try { //IloInt i, j ; const char* filename ; if (argc > 1) filename = argv[1] ; else filename = "data/tsp.dat" ; ifstream f(filename, ios::in) ; if (!f) { cerr << "No such file: " << filename << endl ; throw(1) ; } // Create data matrix IloArray<IloNumArray> costmatrix (env) ; f >> costmatrix ; IloInt n = costmatrix.getSize() ; // Define variables and "fill" them so as not to get seg faults IloArray<IloIntVarArray> x (env, n) ; for (i=0 ; i<n ; i++) { x[i] = IloIntVarArray (env, n) ; for(IloInt j=0 ; j<n ; j++) { x[i][j] = IloIntVar (env) ; } } IloIntVarArray u (env, n) ; for(i=0 ; i<n ; i++) { u[i] = IloIntVar (env) ; } // Define constraints IloExpr constr_i (env) ; IloExpr constr_j (env) ; IloExpr constr_u (env) ; // Vertical constraint // Create a full vector with a hole to express the vertical constraint as a scalar product IloIntArray basevector (env, n) ; basevector[0] = 0 ; for (int i=1 ; i<n ; i++) { basevector[i] = 1 ; } constr_i = IloScalProd(basevector, x[0]) ; model.add( constr_i == 1) ; for (i=1 ; i < n ; i++) { basevector[i-1] = 1 ; basevector[i] = 0 ; constr_i = IloScalProd(basevector, x[i]) ; model.add(constr_i == 1) ; for (j=0 ; j < n ; j++) { if (i != j) { constr_j += x[j][i] ; constr_u = u[i] - u[j] + n*x[i][j] ; model.add(constr_u == 1) ; } } model.add(constr_j == 1) ; } // Define objective IloExpr obj (env) ; for (i=1 ; i < n ; i++) { for (j=0 ; j < n ; j++) { if (i != j) { obj += costmatrix[i][j] * x[i][j] ; } } } model.add( IloMinimize(env, obj) ) ; // Extract model cplex.extract(model); // Export model // Set parameters // Solve if ( !cplex.solve() ) { env.error() << "Failed to optimize problem" << endl; cplex.out() << "Solution status " << cplex.getStatus() << endl ; cplex.out() << "Model" << cplex.getModel() << endl ; throw(-1); } cplex.out() << "Solution status " << cplex.getStatus() << endl; cplex.out() << "Objective value " << cplex.getObjValue() << endl; // Print solution details } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; } } catch (...) { cerr << "Unknown exception caught" << endl ; } // freeing memory env.end(); return 0; } // END main