Example #1
0
int
main (void)
{
   IloEnv env;
   int retval = -1;

   try {
      // Create the model.
      IloModel model(env);
      IloCplex cplex(env);
      IloObjective obj(env);
      IloNumVarArray vars(env);
      IloRangeArray rngs(env);
      IloIntArray cone(env);
      createmodel(model, obj, vars, rngs, cone);

      // Extract model.
      cplex.extract(model);

      // Solve the problem. If we cannot find an _optimal_ solution then
      // there is no point in checking the KKT conditions and we throw an
      // exception.
      cplex.setParam(IloCplex::Param::Barrier::QCPConvergeTol, CONVTOL);
      if ( !cplex.solve() || cplex.getStatus() != IloAlgorithm::Optimal )
         throw string("Failed to solve problem to optimality");

      // Test the KKT conditions on the solution.
      if ( !checkkkt (cplex, obj, vars, rngs, cone, TESTTOL) ) {
         env.error() << "Testing of KKT conditions failed." << endl;
      }
      else {
         env.out() << "Solution status: " << cplex.getStatus() << endl;
         env.out() << "KKT conditions are satisfied." << endl;
         retval = 0;
      }

      env.end();
   } catch (IloException &e) {
      cerr << "IloException: " << e << endl;
      if (env.getImpl())
         env.end();
      ::abort();
   } catch (string& e) {
      cerr << e << endl;
      if (env.getImpl())
         env.end();
      ::abort();
   }
   return retval;
}
vector<array<double,3>> solveLP(int size, graph g){
	
	double EPS = 1;
	int bigM = 200;
	auto type = IloNumVar::Bool;
	vector<array<double,3>> result;
	
	
	IloEnv env;
	try {
		IloModel model(env);
		IloNumVarArray vars(env);
		IloConstraintArray cons(env);
		
		unordered_map<string,int> v;
		int counter = 0;
		
		//setup easy access to variables!
		variable_access x(name_x, vars, v);
		variable_access t(name_t, vars, v);
		variable_access y(name_y, vars, v);
		variable_access e1(name_e1, vars, v);
		variable_access e2(name_e2, vars, v);
		variable_access n1(name_n1, vars, v);
		variable_access n2(name_n2, vars, v);
		variable_access a1(name_a1, vars, v);
		variable_access a2(name_a2, vars, v);
		variable_access z1(name_z1, vars, v);
		variable_access z2(name_z2, vars, v);
		
		//variables: lower and upper bound and the name! 
		//add varibles
		for(int i=1;  i<= size; ++i){
			//t
			v[name_t(i)] = counter++;
			vars.add( IloNumVar(env,  0, bigM,  IloNumVar::Float, name_t(i).c_str() ) );	
			//x
			v[name_x(i)] = counter++;
			vars.add( IloNumVar(env,  0, bigM,  IloNumVar::Float, name_x(i).c_str() ) );
			//y
			v[name_y(i)] = counter++;
			vars.add( IloNumVar(env,  0, bigM, IloNumVar::Float, name_y(i).c_str() ) );
			for(int j=1; j<=size; ++j){
				if(i==j) continue;
				//e1
				v[name_e1(i,j)] = counter++;
				vars.add( IloNumVar(env,  0, 1, type, name_e1(i,j).c_str() ) );
				//e2
				v[name_e2(i,j)] = counter++;
				vars.add( IloNumVar(env,  0, 1, type, name_e2(i,j).c_str() ) );
				//n1
				v[name_n1(i,j)] = counter++;
				vars.add( IloNumVar(env,  0, 1, type, name_n1(i,j).c_str() ) );
				//n2
				v[name_n2(i,j)] = counter++;
				vars.add( IloNumVar(env,  0, 1, type, name_n2(i,j).c_str() ) );
				//a1
				v[name_a1(i,j)] = counter++;
				vars.add( IloNumVar(env,  0, 1, type, name_a1(i,j).c_str() ) );
				//a2
				v[name_a2(i,j)] = counter++;
				vars.add( IloNumVar(env,  0, 1, type, name_a2(i,j).c_str() ) );
				
				//z1
				v[name_z1(i,j)] = counter++;
				vars.add( IloNumVar(env,  0, 1, type, name_z1(i,j).c_str() ) );
				//z2
				v[name_z2(i,j)] = counter++;
				vars.add( IloNumVar(env,  0, 1, type, name_z2(i,j).c_str() ) );
			}
		}
		
		//add all constraints
		model.add(vars);		
				
		//subject: feasibility
		model.add(IloMaximize(env, 0));
		
		
		//add constraints
		//add constraints for arcs
		for(int i=1;  i<= size; ++i){
			for(int j=1;  j<= size; ++j){
				if(i==j) continue;
				if(g.is_arc(i,j)){
					cout<< "constr. for arc ("<<i<<":"<<j<<")" <<endl;
	 				//xi < xj
					cons.add( x(i)  <= x(j) - EPS );
					
					//|ti-tj| < |xi - xj|
					cons.add(  t(j)  - t(i)  <= x(j) - x(i) + (1-a1(i,j))*bigM -EPS);		
					cons.add( t(i)  - t(j)  <= x(j) - x(i) + (1-a1(i,j))*bigM -EPS);
					cons.add( t(j)  - t(i)  <= x(i) - x(j) + (1-a2(i,j))*bigM -EPS);		
					cons.add( t(i)  - t(j)  <= x(i) - x(j) + (1-a2(i,j))*bigM -EPS);	
										
					cons.add( a1(i,j) + a2(i,j) >= 1 );
					
				}
				
			}
		}
		
		//constraints for edges
		for(int i=1;  i<= size; ++i){
			for(int j=1;  j<= size; ++j){
				if(i==j) continue;
				if (g.is_edge(i,j)){
					cout<< "constr. for  edge ("<<i<<":"<<j<<")" <<endl;
					// |t1-t2| < |y1-y2|
					cons.add( t(j)  - t(i)  <= y(j) - y(i) + (1-e1(i,j))*bigM -EPS);
					cons.add( t(i)  - t(j)  <= y(j) - y(i) + (1-e1(i,j))*bigM -EPS);
					cons.add( t(j)  - t(i)  <= y(i) - y(j) + (1-e2(i,j))*bigM -EPS);
					cons.add( t(i)  - t(j)  <= y(i) - y(j) + (1-e2(i,j))*bigM -EPS);
					cons.add( e1(i,j) + e2(i,j) >= 1 );
			
					//|x1-x2| <= |t1-t2| 	
					cons.add( x(j)  - x(i)  <= t(j) - t(i) + (1-z1(i,j))*bigM );
					cons.add( x(i)  - x(j)  <= t(j)  - t(i) + (1-z1(i,j))*bigM);
					cons.add( x(j)  - x(i)  <= t(i)  - t(j) + (1-z2(i,j))*bigM);
					cons.add( x(i)  - x(j)  <= t(i)  - t(j) + (1-z2(i,j))*bigM);
					
					cons.add( z1(i,j) + z2(i,j) >= 1 );
				}
			}
		}


		//constraints for non-existing edges
		for(int i=1;  i<= size; ++i){
			for(int j=1;  j<= size; ++j){
				if(i==j) continue;
				if (g.is_no_edge(i,j)){
					cout<< "constr. for non_edge ("<<i<<":"<<j<<")" <<endl;
					// |y1-y2| <= |t1-t2|
					cons.add( y(j)  - y(i)  <= t(j) - t(i) + (1-n1(i,j))*bigM);
					cons.add( y(i)  - y(j)  <= t(j) - t(i) + (1-n1(i,j))*bigM);
					cons.add( y(j)  - y(i)  <= t(i) - t(j) + (1-n2(i,j))*bigM);
					cons.add( y(i)  - y(j)  <= t(i) - t(j) + (1-n2(i,j))*bigM);
					
					cons.add( n1(i,j) + n2(i,j) >= 1 );
			
			
					//|x1-x2| <= |t1-t2| 		
					cons.add(  x(j)  - x(i)  <= t(j) - t(i) + (1-z1(i,j))*bigM );
					cons.add( x(i)  - x(j)  <= t(j) - t(i) + (1-z1(i,j))*bigM);
					cons.add( x(j)  - x(i)  <= t(i) - t(j) + (1-z2(i,j))*bigM);
					cons.add( x(i)  - x(j)  <= t(i) - t(j) + (1-z2(i,j))*bigM);
					
					cons.add( z1(i,j) + z2(i,j) >= 1 );
				}
			}
		}
		
		//add all constraints to the model
		model.add(cons);
		
		
		//solve the model
		IloCplex cplex(model);
		cplex.extract(model);
		cout<< model<<endl;
		
		//solve silently
		//cplex.setOut(env.getNullStream());
		bool solved = cplex.solve();
		if ( !solved ) {
			cerr<<"MIP model is infeasible!"<<endl;
			
			
			//conflict refiner
			IloConstraintArray infeas(env);
		    IloNumArray preferences(env);

			infeas.add(cons );
			
		     for (IloInt i = 0; i<vars.getSize(); i++) {
		        if ( vars[i].getType() != IloNumVar::Bool ) {
		          infeas.add(IloBound(vars[i], IloBound::Lower));
		          infeas.add(IloBound(vars[i], IloBound::Upper));
		        }
		     }

		     for (IloInt i = 0; i<infeas.getSize(); i++) {
		       preferences.add(1.0);  // user may wish to assign unique preferences
		     }

		     if ( cplex.refineConflict(infeas, preferences) ) {
		      IloCplex::ConflictStatusArray conflict = cplex.getConflict(infeas);
		        env.getImpl()->useDetailedDisplay(IloTrue);
		        cout << "Conflict :" << endl;
		        for (IloInt i = 0; i<infeas.getSize(); i++) {
		          if ( conflict[i] == IloCplex::ConflictMember)
		               cout << "Proved  : " << infeas[i] << endl;
		          if ( conflict[i] == IloCplex::ConflictPossibleMember)
		               cout << "Possible: " << infeas[i] << endl;
		        }
		     }
		     else
		        cout << "Conflict could not be refined" << endl;
         cout << endl;
			
			
			env.end();
			return result;
		}
		
		for(int i=1;  i<= size; ++i){
			array<double,3> coord = {{cplex.getValue(x(i)),
									  cplex.getValue(y(i)),
						   			  cplex.getValue(t(i))}}; 
			result.push_back(coord);
		}
		
		//print variables
		for(int i=1;  i<= size; ++i){
			cout<<  x(i).getName() << " = "<<	cplex.getValue(x(i));
			cout<<"\t\t"<< y(i).getName() << " = "<<	cplex.getValue(y(i));
			cout<<"\t\t"<< t(i).getName() << " = "<<	cplex.getValue(t(i))<<endl;			
		}
		cout<<endl;
		for(int i=1;  i<= size; ++i)
			for(int j=1;  j<= size; ++j){
				if(i==j) continue;
				cout<<  z1(i,j).getName() << " = "<<	cplex.getValue(z1(i,j));
				cout<<"\t"<< z2(i,j).getName() << " = "<<	cplex.getValue(z2(i,j))<<endl;			
			}	
		for(int i=1;  i<= size; ++i)
			for(int j=1;  j<= size; ++j){
				if(i==j) continue;
				if (not g.is_edge(i,j)) continue;
				cout<<   e1(i,j).getName() << " = "<<	cplex.getValue(e1(i,j));
				cout<<"\t"<< e2(i,j).getName() << " = "<<	cplex.getValue(e2(i,j))<<endl;			
			}
		for(int i=1;  i<= size; ++i)
			for(int j=1;  j<= size; ++j){
				if(i==j) continue;
				if (g.is_edge(i,j)) continue;
				cout<<  n1(i,j).getName() << " = "<<	cplex.getValue(n1(i,j));
				cout<<"\t"<< n2(i,j).getName() << " = "<<	cplex.getValue(n2(i,j))<<endl;			
			}
		for(int i=1;  i<= size; ++i)
			for(int j=1;  j<= size; ++j){
				if(i==j) continue;
				if (not g.is_arc(i,j)) continue;
				cout<< a1(i,j).getName() << " = "<<	cplex.getValue(a1(i,j));
				cout<<"\t"<< a2(i,j).getName() << " = "<<	cplex.getValue(a2(i,j))<<endl;			
			}
	}
	catch (IloException& e) {
		cerr << "Concert exception caught: " << e << endl;
	}
	catch (...) {
		cerr << "Unknown exception caught" << endl;
	}
	env.end();
	return result;
}