Пример #1
0
/* prüft, die Länge der Tour, dabei ist
 * sol ein Array, dass die Werte der Kanten enthält (angeordnet als LU Dreieck),
 * visited ist ein Hilfsarray, dass sich merkt, welche Punkte schon besucht wurden
 * tol ist die numerische Toleranz (vgl. andere Bsp. für Lazy Constraints)
 * */
int getTourLen(IloNumArray sol, IloNumArray visited, IloNum tol, tour_t *tour, bool mip)
{
    int j;
    const int n = sol.getSize();
    const int N = sqrt(n);
    int last = -1;
    int length = 0;
    int current = 0;

    visited.clear();
    visited.add(n, 0.0); // mit 0 initialisieren

    // Problemgröße von 0? Das sollte nicht passieren
    if(n == 0)
    {
        printf(ERROR "argghh! zero! zero length LP representation!\n");
        return (N+1);
    }

    // bis ich wieder da ankomme, wo ich gewesen bin
    while(visited[current] == 0)
    {
        length++;
        visited[current] = length; // notiere Position auf der Stadt

        // suche die nächste Stadt in der Waagerechten des UL Dreiecks
        for(j=0; j<current; j++)
            if(j != last && sol[current*N + j] >= 1.0-tol)
                break;

        // wenn ich nicht abgebrochen habe -> nicht gefunden
        // suche die nächste Stadt in der Senkrechten des UL Dreiecks
        if(j == current)
            for(j = current+1; j < N; j++)
                if(j != last && sol[j*N + current] >= 1.0-tol)
                    break;

        // es gibt keinen Nachbarn ?! Das sollte nicht passieren.
        if(j == N)
        {
            if(mip)
                printf(ERROR "argghh! separated point! no neighbors! everybody panic!\n");
            return (N+1);
        }

        // gehe zur nächsten Stadt
        last = current;
        current = j;

        if(tour != NULL)
            tour->push_back(current);
    }

    // Länge der getroffenen Subtour
    return length;
}
Пример #2
0
void addInitColumn(IloNumVarArray lambda, IloObjective rmpObj, 
	IloRangeArray maintConEng, IloRangeArray removeMod, IloRangeArray convex, 
	IloNumArray2 addXCol, IloNumArray addZCol, 
	const IloNumArray compCosts, const IloNumArray convexityCoef) {

	// loop counter
	IloInt t;		

	// counter for objective function coefficient for lambda
	// variable to be added.
	IloNum lambdaObjCoef = 0;

	// function assumes addXCol and addZCol contains proper values.

	// calculate objective function coefficient lambdaObjCoef
	for (t = 0; t < TIME_SPAN; t++) {

		// for each fixed t: scalar product of x[m]* vector and
		// component costs vector compCosts[m]:
		lambdaObjCoef += IloScalProd(addXCol[t],compCosts);

		// also clear the addXCol subarrays as soon as they
		// have been used
		addXCol[t].clear();
	}
			
	// now add this column and it's associated lambda variable to the RMP.
	lambda.add(IloNumVar(rmpObj(lambdaObjCoef) + maintConEng(addZCol) + 
		removeMod(addZCol) + convex(convexityCoef), 0.0, 1.0));

	// clear addZCol num array.
	addZCol.clear();

} // END of addColumn
Пример #3
0
void addColumn(IloCplex subSolver, IloNumVarArray2 x, IloNumVarArray z, IloNumVarArray lambda,
	IloObjective rmpObj, IloRangeArray maintConEng, IloRangeArray removeMod,
	IloRangeArray convex, IloNumArray2 addXCol, IloNumArray addZCol, 
	const IloNumArray compCosts, const IloNumArray convexityCoef) {

	// loop counter
	IloInt t;		

	// counter for objective function coefficient for lambda
	// variable to be added.
	IloNum lambdaObjCoef = 0;

	// extract subproblem-optimal solution values
	// (into IloNumArrays addXCol (2d) and addZCol (1d)).

	// z values:
	subSolver.getValues(addZCol,z);

	//cout << endl << endl << "z = " << endl << addZCol << endl;
	//cin.get();

	// !!! OBS !!!
	// here we might want to save these z values some column pool's custom-nitted class
	// array. Or to be specific, we want to add the indexes for NON-ZERO-ENTRIES in addZCol
	// to our class that keep place of columns.
	// E.g., given variable lambda(m)_(q_m), we want to know in our own class object,
	// given (m)(q_m), the indexes of non-zeros in that Z column.
	


	// and for each t...
	for (t = 0; t < TIME_SPAN; t++) {

		// x values:
		subSolver.getValues(addXCol[t],x[t]);
		//cout << endl << endl << "x[t=" << t << "] =" << endl << addXCol[t] << endl;
	}
	//cin.get();

	// calculate objective function coefficient lambdaObjCoef
	for (t = 0; t < TIME_SPAN; t++) {

		// for each fixed t: scalar product of x[m]* vector and
		// component costs vector compCosts[m]:
		lambdaObjCoef += IloScalProd(addXCol[t],compCosts);

		// also clear the addXCol subarrays as soon as they
		// have been used
		addXCol[t].clear();
	}
			
	// now add this column and it's associated lambda variable to the RMP.
	lambda.add(IloNumVar(rmpObj(lambdaObjCoef) + maintConEng(addZCol) + 
		removeMod(addZCol) + convex(convexityCoef), 0.0, 1.0));

	// clear addZCol num array.
	addZCol.clear();

} // END of addColumn
ILOCPLEXGOAL1(MyBranchGoal, IloNumVarArray, vars) {
   IloNumArray x;
   IloNumArray obj;
   IntegerFeasibilityArray feas;

   x    = IloNumArray(getEnv());
   obj  = IloNumArray(getEnv());
   feas = IntegerFeasibilityArray(getEnv());
   getValues(x, vars);
   getObjCoefs(obj, vars);
   getFeasibilities(feas, vars);

   IloInt bestj  = -1;
   IloNum maxinf = 0.0;
   IloNum maxobj = 0.0;
   IloInt cols = vars.getSize();
   for (IloInt j = 0; j < cols; j++) {
      if ( feas[j] == Infeasible ) {
         IloNum xj_inf = x[j] - IloFloor (x[j]);
         if ( xj_inf > 0.5 )
            xj_inf = 1.0 - xj_inf;
         if ( xj_inf >= maxinf                             &&
             (xj_inf > maxinf || IloAbs (obj[j]) >= maxobj)  ) {
            bestj  = j;
            maxinf = xj_inf;
            maxobj = IloAbs (obj[j]);
         }
      }
   }

   IloCplex::Goal res;
   if ( bestj >= 0 ) {
      res = AndGoal(OrGoal(vars[bestj] >= IloFloor(x[bestj])+1,
                           vars[bestj] <= IloFloor(x[bestj])),
                    this);
   }

   x.end();
   obj.end();
   feas.end();

   return res;
}
Пример #5
0
ILOHEURISTICCALLBACK1(Rounddown, IloNumVarArray, vars) {
   IntegerFeasibilityArray feas;
   IloNumArray             obj;
   IloNumArray             x;
   try {
      feas = IntegerFeasibilityArray(getEnv());
      obj  = IloNumArray(getEnv());
      x    = IloNumArray(getEnv());
      getFeasibilities(feas, vars);
      getObjCoefs     (obj , vars);
      getValues       (x   , vars);

      IloNum objval = getObjValue();
      IloInt cols   = vars.getSize();
      for (IloInt j = 0; j < cols; j++) {
         // Set the fractional variable to zero and update the objective value
         if ( feas[j] == Infeasible ) {
            objval -= x[j] * obj[j];
            x[j] = 0.0;
         }
      }
      setSolution(vars, x, objval);
   }
   catch (...) {
      feas.end();
      obj.end();
      x.end();
      throw;
   }
   feas.end();
   obj.end();
   x.end();
}
Пример #6
0
ILOBRANCHCALLBACK1(MyBranch, IloNumVarArray, vars) {
   if ( getBranchType() != BranchOnVariable )
      return;

   // Branch on var with largest objective coefficient
   // among those with largest infeasibility

   IloNumArray x;
   IloNumArray obj;
   IntegerFeasibilityArray feas;

   try {
      x    = IloNumArray(getEnv());
      obj  = IloNumArray(getEnv());
      feas = IntegerFeasibilityArray(getEnv());
      getValues(x, vars);
      getObjCoefs(obj, vars);
      getFeasibilities(feas, vars);

      IloInt bestj  = -1;
      IloNum maxinf = 0.0;
      IloNum maxobj = 0.0;
      IloInt cols = vars.getSize();
      for (IloInt j = 0; j < cols; j++) {
         if ( feas[j] == Infeasible ) {
            IloNum xj_inf = x[j] - IloFloor (x[j]);
            if ( xj_inf > 0.5 )
               xj_inf = 1.0 - xj_inf;
            if ( xj_inf >= maxinf                              &&
                 (xj_inf > maxinf || IloAbs (obj[j]) >= maxobj)  ) {
               bestj  = j;
               maxinf = xj_inf;
               maxobj = IloAbs (obj[j]);
            }
         }
      }

      if ( bestj >= 0 ) {
         makeBranch(vars[bestj], x[bestj], IloCplex::BranchUp,   getObjValue());
         makeBranch(vars[bestj], x[bestj], IloCplex::BranchDown, getObjValue());
      }
   }
   catch (...) {
      x.end();
      obj.end();
      feas.end();
      throw;
   }
   x.end();
   obj.end();
   feas.end();
}
Пример #7
0
IloNum sumArray(IloNumArray redCosts) { 

	// delcare loop counter:
	IloInt m;

	// default/starting value: 0.
	IloNum arrSum = 0.0;
	
	// loop over the array members
	for (m = 0; m < redCosts.getSize(); m++) {
		
		// add member by member
		arrSum += redCosts[m];
	}

	// return minimum
	return arrSum;

} // END of sumArray
Пример #8
0
IloNum minMemberValue(IloNumArray redCosts) { 

	// delcare loop counter:
	IloInt m;

	// default/starting minimum: 0.
	IloNum currentMin = 0.0;
	
	// loop over the array members
	for (m = 0; m < redCosts.getSize(); m++) {

		// see if current members improves minimum
		if (redCosts[m] < currentMin) {
			currentMin = redCosts[m];
		}
	}

	// return minimum
	return currentMin;

} // END of minMemberValue				
Пример #9
0
void
makeCuts(const IloNumVarArray vars, IloExprArray lhs, IloNumArray rhs) {
   IloNumVar x11, x12, x13, x14, x15;
   IloNumVar x21, x22, x23, x24, x25;
   IloNumVar x31, x32, x33, x34, x35;
   IloNumVar x41, x42, x43, x44, x45;
   IloNumVar x51, x52, x53, x54, x55;
   IloNumVar w11, w12, w13, w14, w15;
   IloNumVar w21, w22, w23, w24, w25;
   IloNumVar w31, w32, w33, w34, w35;
   IloNumVar w41, w42, w43, w44, w45;
   IloNumVar w51, w52, w53, w54, w55;
   IloInt num = vars.getSize();

   for (IloInt i = 0; i < num; i++) {
      if      ( strcmp(vars[i].getName(), "X11") == 0 ) x11 = vars[i];
      else if ( strcmp(vars[i].getName(), "X12") == 0 ) x12 = vars[i];
      else if ( strcmp(vars[i].getName(), "X13") == 0 ) x13 = vars[i];
      else if ( strcmp(vars[i].getName(), "X14") == 0 ) x14 = vars[i];
      else if ( strcmp(vars[i].getName(), "X15") == 0 ) x15 = vars[i];
      else if ( strcmp(vars[i].getName(), "X21") == 0 ) x21 = vars[i];
      else if ( strcmp(vars[i].getName(), "X22") == 0 ) x22 = vars[i];
      else if ( strcmp(vars[i].getName(), "X23") == 0 ) x23 = vars[i];
      else if ( strcmp(vars[i].getName(), "X24") == 0 ) x24 = vars[i];
      else if ( strcmp(vars[i].getName(), "X25") == 0 ) x25 = vars[i];
      else if ( strcmp(vars[i].getName(), "X31") == 0 ) x31 = vars[i];
      else if ( strcmp(vars[i].getName(), "X32") == 0 ) x32 = vars[i];
      else if ( strcmp(vars[i].getName(), "X33") == 0 ) x33 = vars[i];
      else if ( strcmp(vars[i].getName(), "X34") == 0 ) x34 = vars[i];
      else if ( strcmp(vars[i].getName(), "X35") == 0 ) x35 = vars[i];
      else if ( strcmp(vars[i].getName(), "X41") == 0 ) x41 = vars[i];
      else if ( strcmp(vars[i].getName(), "X42") == 0 ) x42 = vars[i];
      else if ( strcmp(vars[i].getName(), "X43") == 0 ) x43 = vars[i];
      else if ( strcmp(vars[i].getName(), "X44") == 0 ) x44 = vars[i];
      else if ( strcmp(vars[i].getName(), "X45") == 0 ) x45 = vars[i];
      else if ( strcmp(vars[i].getName(), "X51") == 0 ) x51 = vars[i];
      else if ( strcmp(vars[i].getName(), "X52") == 0 ) x52 = vars[i];
      else if ( strcmp(vars[i].getName(), "X53") == 0 ) x53 = vars[i];
      else if ( strcmp(vars[i].getName(), "X54") == 0 ) x54 = vars[i];
      else if ( strcmp(vars[i].getName(), "X55") == 0 ) x55 = vars[i];
      else if ( strcmp(vars[i].getName(), "W11") == 0 ) w11 = vars[i];
      else if ( strcmp(vars[i].getName(), "W12") == 0 ) w12 = vars[i];
      else if ( strcmp(vars[i].getName(), "W13") == 0 ) w13 = vars[i];
      else if ( strcmp(vars[i].getName(), "W14") == 0 ) w14 = vars[i];
      else if ( strcmp(vars[i].getName(), "W15") == 0 ) w15 = vars[i];
      else if ( strcmp(vars[i].getName(), "W21") == 0 ) w21 = vars[i];
      else if ( strcmp(vars[i].getName(), "W22") == 0 ) w22 = vars[i];
      else if ( strcmp(vars[i].getName(), "W23") == 0 ) w23 = vars[i];
      else if ( strcmp(vars[i].getName(), "W24") == 0 ) w24 = vars[i];
      else if ( strcmp(vars[i].getName(), "W25") == 0 ) w25 = vars[i];
      else if ( strcmp(vars[i].getName(), "W31") == 0 ) w31 = vars[i];
      else if ( strcmp(vars[i].getName(), "W32") == 0 ) w32 = vars[i];
      else if ( strcmp(vars[i].getName(), "W33") == 0 ) w33 = vars[i];
      else if ( strcmp(vars[i].getName(), "W34") == 0 ) w34 = vars[i];
      else if ( strcmp(vars[i].getName(), "W35") == 0 ) w35 = vars[i];
      else if ( strcmp(vars[i].getName(), "W41") == 0 ) w41 = vars[i];
      else if ( strcmp(vars[i].getName(), "W42") == 0 ) w42 = vars[i];
      else if ( strcmp(vars[i].getName(), "W43") == 0 ) w43 = vars[i];
      else if ( strcmp(vars[i].getName(), "W44") == 0 ) w44 = vars[i];
      else if ( strcmp(vars[i].getName(), "W45") == 0 ) w45 = vars[i];
      else if ( strcmp(vars[i].getName(), "W51") == 0 ) w51 = vars[i];
      else if ( strcmp(vars[i].getName(), "W52") == 0 ) w52 = vars[i];
      else if ( strcmp(vars[i].getName(), "W53") == 0 ) w53 = vars[i];
      else if ( strcmp(vars[i].getName(), "W54") == 0 ) w54 = vars[i];
      else if ( strcmp(vars[i].getName(), "W55") == 0 ) w55 = vars[i];
   }

   lhs.add(x21 - x22);
   rhs.add(0.0);

   lhs.add(x22 - x23);
   rhs.add(0.0);

   lhs.add(x23 - x24);
   rhs.add(0.0);

   lhs.add(2.08*x11 + 2.98*x21 + 3.47*x31 + 2.24*x41 + 2.08*x51 +
           0.25*w11 + 0.25*w21 + 0.25*w31 + 0.25*w41 + 0.25*w51);
   rhs.add(20.25);

   lhs.add(2.08*x12 + 2.98*x22 + 3.47*x32 + 2.24*x42 + 2.08*x52 +
           0.25*w12 + 0.25*w22 + 0.25*w32 + 0.25*w42 + 0.25*w52);
   rhs.add(20.25);

   lhs.add(2.08*x13 + 2.98*x23 + 3.47*x33 + 2.24*x43 + 2.08*x53 +
           0.25*w13 + 0.25*w23 + 0.25*w33 + 0.25*w43 + 0.25*w53);
   rhs.add(20.25);

   lhs.add(2.08*x14 + 2.98*x24 + 3.47*x34 + 2.24*x44 + 2.08*x54 +
           0.25*w14 + 0.25*w24 + 0.25*w34 + 0.25*w44 + 0.25*w54);
   rhs.add(20.25);

   lhs.add(2.08*x15 + 2.98*x25 + 3.47*x35 + 2.24*x45 + 2.08*x55 +
           0.25*w15 + 0.25*w25 + 0.25*w35 + 0.25*w45 + 0.25*w55);
   rhs.add(16.25);
}
Пример #10
0
bool getCut( IloNumArray& vals, IloNumVarArray& vars, CutMode cutmode, int set, 
						IloCplex::ControlCallbackI::IntegerFeasibilityArray feas, 
						IloRange& cut, int** graph, int* old_winner ){

	int n = vals.getSize()/2;
	
	bool marked[n];
	for( int i = 0; i < n; ++i )
		marked[i] = false;
	
	int winner;
	int count_marked = 0;
	list<int> indices;

	int acc[n][n];//mudar para lista adjacencia
	memset(acc, 0, sizeof(acc));
	
	static int cont=0;
	for( int i = 0; i < n; ++i ){
			if(feas[i+n*set] == IloCplex::ControlCallbackI::Infeasible)
				marked[i] = false;
			else{
				marked[i]=true;
				count_marked++;
			}
		}


		//int cont=0;
		int cnt=0;
		while( count_marked < n ){
			//choose the star node
			cnt++;


			winner = -1;
			for( int i = 0; i < n; ++i ){
				if(old_winner[i+n*set])continue;

				if( !marked[i] ){
					if( winner == -1 ){
						winner = i;
					}
					else if( cutmode == CLQ2B && fabs(vals[i+n*set]-0.5) < fabs(vals[winner+n*set]-0.5) && vals[i+n*set] > 0 && vals[i+n*set] < 1 ){
						winner = i;
					}
					else if( cutmode == CLQ2A && vals[i+n*set] > vals[winner+n*set] && vals[i+n*set] < 1 ){
						winner = i;
					}
				}
			}
			if(winner==-1)return false; //??

			old_winner[winner+n*set]=1;
			++count_marked;
			marked[winner] = true;
			indices.push_back( winner+n*set );
		

			for( int i = 0; i < n; ++i ){
				if( !graph[i][winner] ){
					if( !marked[i] ){
						marked[i] = true;
						++count_marked;
					}
				}
			}
		}
	
	list<int>::iterator it = indices.begin();
	float sum = 0;
	while( it != indices.end() ){
		sum += vals[*it];
		++it;
	}
	for(list<int>::iterator it1 = indices.begin(); it1!= indices.end(); it1++){
		for(list<int>::iterator it2 = indices.begin(); it2!= indices.end(); it2++){
			int v1 = *it1;
			int v2 = *it2;
			if(v1==v2)continue;
			v1 -= n*set;
			v2 -= n*set;
			if(!graph[v1][v2] || !graph[v2][v1]){
				puts("ERRO NAO CLICK");
				printf("%d %d\n", v1, v2);
				exit(-1);
			}
		}
	}
	
	if(sum > 1+0.000001 ){
		it = indices.begin();
		while( it != indices.end() ){
			cut.setLinearCoef( vars[*it], 1 );
			//printf("x[%d] ", *it);
			++it;
		}
		//printf(" <= 1\n");
		return true;
	}
	return false;
}
Пример #11
0
int
main(int argc, char **argv)
{
   char const *modelfile = NULL;
   int jobs = 0;
   char const **machine = 0;

#if defined(USE_MPI)
   int numprocs, rank;

   // Initialize MPI.
   // We must have at least three processors (master and 2 workers) and
   // the master must have rank 0.
   MPI_Init(&argc, &argv);
   MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
   if ( numprocs < 3 ) {
      fprintf (stderr, "Invalid number of processors (%d)\n", numprocs);
      abort ();
   }
   MPI_Comm_rank (MPI_COMM_WORLD, &rank);
   if ( rank != 0 ) {
      fprintf (stderr, "Master must have rank 0!\n");
      MPI_Finalize ();
      abort ();
   }
   machine = new char const*[numprocs];
   for (int i = 0; i < numprocs; ++i)
      machine[i] = "mpimachine";
   jobs = numprocs - 1;
#elif defined(USE_PROCESS)
   // The default binary is CPLEX but that can be overwritten
   // by command line arguments.
   char const *bin = "cplex";

   machine = new char const *[argc];

#elif defined(USE_TCPIP)
   machine = new char const *[argc];
#else
#   error "No transport type selected"
#endif


   // Parse the command line.
   Worker::OUTPUT output = Worker::OUTPUT_SILENT;
   double absgap = 1e-6;
   for (int i = 1; i < argc; ++i) {
      if ( strncmp (argv[i], "-model=", 7) == 0 )
         modelfile = argv[i] + 7;
#if defined(USE_MPI)
      // no MPI specific commands supported
#elif defined(USE_PROCESS)
      // For process transport
      // - machine=<command> specifies the name of a machine to which
      //   we connect (via ssh)
      // -bin=<binary> specifies the binary to execute (default is "cplex")
      else if ( strncmp (argv[i], "-machine=", 9) == 0 )
         machine[jobs++] = argv[i] + 9;
      else if ( strncmp (argv[i], "-bin=", 5) == 0 )
         bin = argv[i] + 5;
#elif defined(USE_TCPIP)
      // For TCP/IP process
      // -address=<host>:<port> specifies a worker address to which to
      //  connect
      else if ( strncmp (argv[i], "-address=", 9) == 0 )
         machine[jobs++] = argv[i];
#endif
      // Further arguments
      // -absgap=<gap>     stop if that absolute gap is reached
      // -output-prefixed  prefix all worker output by the worker number
      // -output-log       output worker log messages
      else if ( strncmp (argv[i], "-absgap=", 8) == 0 )
         absgap = strtod (argv[i] + 8, NULL);
      else if ( strcmp (argv[i], "-output-prefixed") == 0 )
         output = Worker::OUTPUT_PREFIXED;
      else if ( strcmp (argv[i], "-output-log") == 0 )
         output = Worker::OUTPUT_LOG;
   }

   // Validate arguments.
   if ( !modelfile )
      throw "No model file specified with -model=<modelfile>";
   if ( jobs < 1 )
      throw "Invalid job count";
   
   // Find the place at which to find the shared object that implements
   // the user function. On Windows the path to the current directory is
   // likely to contain blanks, so better quote it.
   char cwd[MAX_PATH_LEN];
   char usrfunc[MAX_PATH_LEN];
   getcwd (cwd, sizeof (cwd));
   usrfunc[0] = 0;
#ifdef _WIN32
   strcat (usrfunc, "-libpath=\"");
   strcat (usrfunc, cwd);
   strcat (usrfunc, "\"");
#else
   strcat (usrfunc, "-libpath=");
   strcat (usrfunc, cwd);
#endif

   IloEnv env;
   SolveState state;

   // Initialize the workers.
   // The main thing to do here is to set up the connection arguments
   // for the IloCplex constructor. Once we have them we just instantiate
   // the Worker class. The constructor for this class will also start
   // an asynchronous solve immediately.
   Worker **workers = new Worker*[jobs];
   for (int i = 0; i < jobs; ++i) {
      char const *transport = 0;
      char const *args[16];
      int nextarg = 0;

#if defined(USE_MPI)
      char rankbuf[256];

      sprintf (rankbuf, "-remoterank=%d", i + 1);
      transport = "mpitransport";
      args[nextarg++] = rankbuf;
#elif defined(USE_PROCESS)
      char logbuf[1024];

      transport = "processtransport";
      // If the machine is not "localhost" then use ssh to connect to
      // this machine. Otherwise just fork a process on the local
      // machine.
      if ( machine[i] != NULL && strcmp (machine[i], "localhost") != 0 ) {
         args[nextarg++] = "/usr/bin/ssh";
         args[nextarg++] = machine[i];
      }
      args[nextarg++] = bin;
      args[nextarg++] = "-worker=process";
      if ( machine[i] != NULL )
         args[nextarg++] = "-stdio";
      else
         args[nextarg++] = "-namedpipes=.";
      args[nextarg++] = usrfunc;
      args[nextarg++] = "-userfunction=iloparmipopt_userfunction=REGISTER_USERFUNCTION";
      sprintf (logbuf, "-logfile=server%d.log", i);
      args[nextarg++] = logbuf;
#elif defined(USE_TCPIP)
      transport = "tcpiptransport";
      args[nextarg++] = machine[i];
#endif


      std::cout << "Initializing worker for " << machine[i] << std::endl;
      try {
         workers[i] = new Worker(env, i, &state,
                                 transport, nextarg, args,
                                 modelfile, output, 1e-5);
      } catch (...) {
         while (--i >= 0)
            delete workers[i];
         delete[] workers;
         throw;
      }
   }
   delete[] machine;

   try {
      // At this point all workers have been started and are
      // solving the problem. We just wait until either the first
      // worker has finished or if the best known global primal and dual
      // bounds are close enough.
      IloObjective::Sense const objsen = workers[0]->getObjectiveSense();
      int active = jobs;
      int frequency = 10000; // Print current bounds every two seconds.
      while (active > 0) {
         // Check if we should stop all solves.
         // We stop them if the absolute mipgap is reached.
         if ( state.primal.valid && state.dual.valid &&
              ((objsen == IloObjective::Minimize &&
                state.dual.bound + absgap >= state.primal.bound) ||
               (objsen == IloObjective::Maximize &&
                state.dual.bound - absgap <= state.primal.bound)) )
         {
            std::cout << "Stopping criterion reached. Stopping all pending solves."
                      << std::endl;
            for (int i = 0; i < jobs; ++i)
               workers[i]->kill();
            break;
         }
         if ( --frequency == 0 ) {
            std::cout << "dual=" << state.dual.bound << ", "
                      << "primal=" << state.primal.bound
                      << std::endl;
            frequency = 10000;
         }

         // Loop over all solvers and test if they are still running.
         for (int i = 0; i < jobs; ++i) {
            if ( !workers[i]->isRunning() ) {
               // The job is finished. We have a solution, so kill all
               // others.
               --active;
               std::cout << "First job (" << i << ") is finished, killing the rest"
                         << std::endl;
               for (int j = 0; j < jobs; ++j) {
                  if ( j != i ) {
                     workers[j]->kill();
                     --active;
                  }
               }
               break;
            }
         }
         // Sleep a little so that we do not poll the workers like crazy.
         millisleep (10);
      }

      // All workers have finished or have been killed. Join them.
      // For each worker we print its status, its dettime and its bounds.
      for (int i = 0; i < jobs; ++i) {
         double obj = -IloInfinity;
         bool const result = workers[i]->join();
         if ( !result ) {
            // No feasible solution found (yet) on this machine.
            // Just set objective function to a very big value
            obj = (objsen == IloObjective::Minimize) ? IloInfinity : -IloInfinity;
         }
         else {
            obj = workers[i]->getObjective();
         }

         std::cout << "Job " << i << ": " << obj << ", stat " << workers[i]->getStatus()
                   << std::endl
                   << "\t" << workers[i]->getDetTime() << ", "
                   << workers[i]->getDual() << ", "
                   << workers[i]->getPrimal() << std::endl;
      }

      // Fetch the x vector from the solver that produced the best
      // primal bound.
      int const bestidx = state.primal.idx;
      if ( bestidx < 0 ) {
         std::cout << "No solution (model infeasible)" << std::endl;
      }
      else {
         IloNumArray x = workers[bestidx]->getX();
         std::cout << "Optimal solution:" << std::endl;
         for (IloInt c = 0; c < x.getSize(); ++c)
            std::cout << "x[" << c << "]: " << x[c] << std::endl;
         x.end();
      }

      // Release the workers.
      for (int i = jobs - 1; i >= 0; --i)
         delete workers[i];
      delete[] workers;

      env.end();
   } catch (...) {
      // In case of any error we still need to delete the workers.
      // This is to make sure that we properly disconnect from the
      // remote workers. The destructor of a worker will automatically
      // kill and join the worker if that was not already done.
      for (int i = jobs - 1; i >= 0; --i)
         delete workers[i];
      delete[] workers;
      throw;
   }

#ifdef USE_MPI
   MPI_Finalize ();
#endif


   return 0;
}
Пример #12
0
ILOBRANCHCALLBACK1(SOSbranch, IloSOS1Array, sos) {
    IloNumArray    x;
    IloNumVarArray var;

    try {
        IloInt i;
        x   = IloNumArray(getEnv());
        var = IloNumVarArray(getEnv());
        IloNum bestx = EPS;
        IloInt besti = -1;
        IloInt bestj = -1;
        IloInt num = sos.getSize();

        for (i = 0; i < num; i++) {
            if ( getFeasibility(sos[i]) == Infeasible ) {
                var.clear();
                sos[i].getVariables(var);
                getValues(x, var);
                IloInt n = var.getSize();
                for (IloInt j = 0; j < n; j++) {
                    IloNum inf = IloAbs(x[j] - IloRound(x[j]));
                    if ( inf > bestx ) {
                        bestx = inf;
                        besti = i;
                        bestj = j;
                    }
                }
            }
        }

        if ( besti >= 0 ) {
            IloCplex::BranchDirectionArray dir;
            IloNumArray                    val;
            try {
                dir = IloCplex::BranchDirectionArray(getEnv());
                val = IloNumArray(getEnv());
                var.clear();
                sos[besti].getVariables(var);
                IloInt n = var.getSize();
                for (IloInt j = 0; j < n; j++) {
                    if ( j != bestj ) {
                        dir.add(IloCplex::BranchDown);
                        val.add(0.0);
                    } else {
                        dir.add(IloCplex::BranchUp);
                        val.add(1.0);
                    }
                }
                makeBranch(var,        val, dir,                  getObjValue());
                makeBranch(var[bestj], 0.0, IloCplex::BranchDown, getObjValue());
            }
            catch (...) {
                dir.end();
                val.end();
                throw;
            }
            dir.end();
            val.end();
        }
    }
    catch (...) {
        var.end();
        x.end();
        throw;
    }

    var.end();
    x.end();
}