Пример #1
0
    bool LpSolve::solve() {
        set_add_rowmode(lp, TRUE);
        for (size_t c = 0; c < moduleIndexMap.size(); ++c) {
            colno[c] = c + 1;
            set_binary(lp, c + 1, TRUE);
        }
        for (auto &equation : equations) {
            memset(row, 0, moduleIndexMap.size() * sizeof(*row));
            for (auto const &module : equation->getModules()) {
                row[moduleIndexMap.at(module->toString())] = 1;
            }
            add_constraintex(lp, moduleIndexMap.size(), row, colno, equation->getIsEqualityConstraint() ? EQ : LE, 1);
        }
        set_add_rowmode(lp, FALSE);
        memset(row, 0, moduleIndexMap.size() * sizeof(*row));
        set_obj_fnex(lp, moduleIndexMap.size(), row, colno);

        if (::solve(lp) != OPTIMAL) {
            return false;
        }
        get_variables(lp, row);
        for (size_t j = 0; j < moduleIndexMap.size(); j++)
            printf("%s: %f\n", get_col_name(lp, j + 1), row[j]);
        return true;
    }
Пример #2
0
// TODO there's a seriouxx need for refactoring here !
Solution LpsolveAdaptator::getAdmissibleSolution(LinearProblem * lp) {
	lprec *lprec;
	int nbCol = lp->getVariables().size();
	lprec = make_lp(0, nbCol);

	if (lprec == NULL) {
		// TODO raise an exception
	}

	/* set variables name to ease debugging */
	for (int i = 0; i < (int)lp->getVariables().size(); ++i) {
		Variable * var = (lp->getVariables())[i];
		set_col_name(lprec, i+1, var->getNameToChar());
		if (var->isBinary()) {
			set_binary(lprec, i+1, TRUE);
		}
	}

	/* to build the model faster when adding constraints one at a time */
	set_add_rowmode(lprec, TRUE);

	for (int i = 0; i < (int)(lp->getConstraints().size()); ++i) {
		// FIXME there's a bug here but I can't find it
		Constraint c = (Constraint)(lp->getConstraints()[i]);
		TermList terms = c.getTerms();
		int col[terms.size()];
		REAL row[terms.size()];
		int j = 0;
		for (TermList::const_iterator it = terms.begin(); it != terms.end();
				++it, ++j) {
			// TODO check if this is fixed
			col[j] = ((Term)*it).getVariable().getPosition();
			row[j] = ((Term)*it).getCoeff();
		}
		// WARNING the Consraint uses the same operator values than in lp_lib.h
		if (!add_constraintex(lprec, j, row, col, c.getOperator(), c.getBound())) {
			// TODO raise an exception
		}
	}

	/* the objective function requires rowmode to be off */
	set_add_rowmode(lprec, FALSE);

	return getSolution(lprec);
}
Пример #3
0
int main ( int argv, char * argc[] )
{

# if defined ERROR
#  undef ERROR
# endif
# define ERROR() { fprintf(stderr, "Error\n"); exit(1); }
  lprec *lp;
  int majorversion, minorversion, release, build;

#if defined FORTIFY
  Fortify_EnterScope();
#endif

  lp_solve_version(&majorversion, &minorversion, &release, &build);
  printf("lp_solve %d.%d.%d.%d demo\n\n", majorversion, minorversion, release, build);
  printf("This demo will show most of the features of lp_solve %d.%d.%d.%d\n", majorversion, minorversion, release, build);
  press_ret();
  printf("\nWe start by creating a new problem with 4 variables and 0 constraints\n");
  printf("We use: lp=make_lp(0,4);\n");
  if ((lp = make_lp(0,4)) == NULL)
    ERROR();
  press_ret();

  printf("We can show the current problem with print_lp(lp)\n");
  print_lp(lp);
  press_ret();
  printf("Now we add some constraints\n");
  printf("add_constraint(lp, {0, 3, 2, 2, 1}, LE, 4)\n");
  {
    double row[] = {0, 3, 2, 2, 1};
    if (!add_constraint(lp, row, LE, 4))
      ERROR();
  }
  print_lp(lp);
  press_ret();
  printf("add_constraintex is now used to add a row. Only the npn-zero values must be specfied with this call.\n");
  printf("add_constraintex(lp, 3, {4, 3, 1}, {2, 3, 4}, GE, 3)\n");
  {
    int colno[] = {2, 3, 4};
    double row[] = {4, 3, 1};
    if (!add_constraintex(lp, sizeof(colno) / sizeof(*colno), row, colno, GE, 3))
      ERROR();
  }
  print_lp(lp);
  press_ret();
  printf("Set the objective function\n");
  printf("set_obj_fn(lp, {0, 2, 3, -2, 3})\n");
  {
    double row[] = {0, 2, 3, -2, 3};
    if (!set_obj_fn(lp, row))
      ERROR();
  }
  print_lp(lp);
  press_ret();
  printf("Now solve the problem with printf(solve(lp));\n");
  printf("%d",solve(lp));
  press_ret();
  printf("The value is 0, this means we found an optimal solution\n");
  printf("We can display this solution with print_objective(lp) and print_solution(lp)\n");
  print_objective(lp);
  print_solution(lp, 1);
  print_constraints(lp, 1);

  press_ret();
  printf("The dual variables of the solution are printed with\n");
  printf("print_duals(lp);\n");
  print_duals(lp);
  press_ret();
  printf("We can change a single element in the matrix with\n");
  printf("set_mat(lp,2,1,0.5)\n");
  if (!set_mat(lp,2,1,0.5))
    ERROR();
  print_lp(lp);
  press_ret();
  printf("If we want to maximize the objective function use set_maxim(lp);\n");
  set_maxim(lp);
  print_lp(lp);
  press_ret();
  printf("after solving this gives us:\n");
  solve(lp);
  print_objective(lp);
  print_solution(lp, 1);
  print_constraints(lp, 1);
  print_duals(lp);
  press_ret();
  printf("Change the value of a rhs element with set_rh(lp,1,7.45)\n");
  set_rh(lp,1,7.45);
  print_lp(lp);
  solve(lp);
  print_objective(lp);
  print_solution(lp, 1);
  print_constraints(lp, 1);
  press_ret();
  printf("We change %s to the integer type with\n", get_col_name(lp, 4));
  printf("set_int(lp, 4, TRUE)\n");
  set_int(lp, 4, TRUE);
  print_lp(lp);
  printf("We set branch & bound debugging on with set_debug(lp, TRUE)\n");
  set_debug(lp, TRUE);
  printf("and solve...\n");
  press_ret();
  solve(lp);
  print_objective(lp);
  print_solution(lp, 1);
  print_constraints(lp, 1);
  press_ret();
  printf("We can set bounds on the variables with\n");
  printf("set_lowbo(lp,2,2); & set_upbo(lp,4,5.3)\n");
  set_lowbo(lp,2,2);
  set_upbo(lp,4,5.3);
  print_lp(lp);
  press_ret();
  solve(lp);
  print_objective(lp);
  print_solution(lp, 1);
  print_constraints(lp, 1);
  press_ret();
  printf("Now remove a constraint with del_constraint(lp, 1)\n");
  del_constraint(lp,1);
  print_lp(lp);
  printf("Add an equality constraint\n");
  {
    double row[] = {0, 1, 2, 1, 4};
    if (!add_constraint(lp, row, EQ, 8))
      ERROR();
  }
  print_lp(lp);
  press_ret();
  printf("A column can be added with:\n");
  printf("add_column(lp,{3, 2, 2});\n");
  {
    double col[] = {3, 2, 2};
    if (!add_column(lp, col))
      ERROR();
  }
  print_lp(lp);
  press_ret();
  printf("A column can be removed with:\n");
  printf("del_column(lp,3);\n");
  del_column(lp,3);
  print_lp(lp);
  press_ret();
  printf("We can use automatic scaling with:\n");
  printf("set_scaling(lp, SCALE_MEAN);\n");
  set_scaling(lp, SCALE_MEAN);
  print_lp(lp);
  press_ret();
  printf("The function get_mat(lprec *lp, int row, int column) returns a single\n");
  printf("matrix element\n");
  printf("%s get_mat(lp,2,3), get_mat(lp,1,1); gives\n","printf(\"%f %f\\n\",");
  printf("%f %f\n", (double)get_mat(lp,2,3), (double)get_mat(lp,1,1));
  printf("Notice that get_mat returns the value of the original unscaled problem\n");
  press_ret();
  printf("If there are any integer type variables, then only the rows are scaled\n");
  printf("set_scaling(lp, SCALE_MEAN);\n");
  set_scaling(lp, SCALE_MEAN);
  printf("set_int(lp,3,FALSE);\n");
  set_int(lp,3,FALSE);
  print_lp(lp);
  press_ret();
  solve(lp);
  printf("print_objective, print_solution gives the solution to the original problem\n");
  print_objective(lp);
  print_solution(lp, 1);
  print_constraints(lp, 1);
  press_ret();
  printf("Scaling is turned off with unscale(lp);\n");
  unscale(lp);
  print_lp(lp);
  press_ret();
  printf("Now turn B&B debugging off and simplex tracing on with\n");
  printf("set_debug(lp, FALSE), set_trace(lp, TRUE) and solve(lp)\n");
  set_debug(lp, FALSE);
  set_trace(lp, TRUE);
  press_ret();
  solve(lp);
  printf("Where possible, lp_solve will start at the last found basis\n");
  printf("We can reset the problem to the initial basis with\n");
  printf("default_basis(lp). Now solve it again...\n");
  press_ret();
  default_basis(lp);
  solve(lp);

  printf("It is possible to give variables and constraints names\n");
  printf("set_row_name(lp,1,\"speed\"); & set_col_name(lp,2,\"money\")\n");
  if (!set_row_name(lp,1,"speed"))
    ERROR();
  if (!set_col_name(lp,2,"money"))
    ERROR();
  print_lp(lp);
  printf("As you can see, all column and rows are assigned default names\n");
  printf("If a column or constraint is deleted, the names shift place also:\n");
  press_ret();
  printf("del_column(lp,1);\n");
  del_column(lp,1);
  print_lp(lp);
  press_ret();

  write_lp(lp, "lp.lp");

  delete_lp(lp);

  printf("An lp structure can be created and read from a .lp file\n");
  printf("lp = read_lp(\"lp.lp\", TRUE);\n");
  printf("The verbose option is used\n");
  if ((lp = read_LP("lp.lp", TRUE, "test")) == NULL)
    ERROR();
  press_ret();
  printf("lp is now:\n");
  print_lp(lp);

  press_ret();
  printf("solution:\n");
  set_debug(lp, TRUE);
  solve(lp);
  set_debug(lp, FALSE);
  print_objective(lp);
  print_solution(lp, 1);
  print_constraints(lp, 1);
  press_ret();

  delete_lp(lp);

#if defined FORTIFY
  Fortify_LeaveScope();
#endif

    return 0;
}
Пример #4
0
vector<PathPoint *> LPPath :: findPath(vertex *curr) {
	lprec *lp;
	
	int numDropoff = 0;
	int numDropped = 0;
	int numPickup = 0;
	
	//find pairs for each dropoff point
	for(int i = 0; i < points.size(); i++) {
		if(points[i]->type == 1) {
			bool foundPair = false;
			
			for(int j = 0; j < points.size(); j++) {
				if(j != i && points[j]->pairIndex == points[i]->pairIndex) {
					pairIndex[i] = j;
					foundPair = true;
					break;
				}
			}
			
			//sometimes, there's an error and the pair cannot be found
			//in that case, print out some debugging information
			if(!foundPair) {
				cout << i << ":" << points[i]->pairIndex << "  ";
				for(int j = 0; j < points.size(); j++) {
					cout << points[j]->type << ":" << points[j]->pairIndex << " ";
				}
				cout << endl;
			}
		}
	}
	
	//occasionally we encounter a model that takes hours or days to solve
	//we set a timeout on the solve function, and then advance to the next iteration
	//as the iteration increases, we introduce more randomness into the model
	// (this is done via the getNonZero function)
	for(int iteration = 0; ; iteration += 10) {
		//calculate cost matrix
		for(int i = 0; i < points.size(); i++) {
			PathPoint *ipoint = points[i];
		
			if(ipoint->type == 0) numPickup++;
			else if(ipoint->type == 1) numDropoff++;
			else if(ipoint->type == 2) numDropped++;
			
			//from this point to itself
			costMatrix[i + 1][i] = getNonZero(0, iteration);
			
			//from this point to every other point
			for(int j = 0; j < points.size(); j++) {
				if(i != j)
					costMatrix[i + 1][j] = getNonZero(length(ipoint, points[j]), iteration);
			}
			
			//from the current location to this point
			costMatrix[0][i] = getNonZero(taxiPath->shortestPath(curr, ipoint->vert), iteration);
		}

	
		//calculate m matrix
		//first, we have to find earliest and latest
		
		//the current location must occur at time zero
		latest[0] = 0;
	
		for(int i = 0; i < points.size(); i++) {
			if(points[i]->type == 0 || points[i]->type == 2) {
				//this is a pickup or stand-alone dropoff point
				//the earliest time occurs when we go directly
				// from the current location to here
				//the latest time is set by the pickup constraint
				
				earliest[i] = costMatrix[0][i];
				latest[i + 1] = points[i]->remaining;
			} else if(points[i]->type == 1) {
				//this is a dropoff point
				//the earliest time occurs when we go directly
				// to the pickup point, then here
				//the latest time occurs when we get to the pickup
				// point the latest, and then here the latest
				// (stretch both pickup and service constraints)
				earliest[i] = costMatrix[0][pairIndex[i]] + costMatrix[pairIndex[i] + 1][i];
				latest[i + 1] = points[pairIndex[i]]->remaining + points[i]->remaining;
			}
		}
		
		//calculate m
		double test;
		for(int i = 0; i < points.size() + 1; i++) {
			for(int j = 0; j < points.size(); j++) {
				test = latest[i] + costMatrix[i][j] - earliest[j];
				if(test > 0) m[i][j] = test;
				else m[i][j] = 0;
			}
		}
		
		//find the number of binary columns
		//each x_ij determines whether or not the taxi will move
		// from i to j
		//in the comments below these movements will be referred
		// to as route segments (_from_ i _to_ j)
		int ncol = (points.size() + 1) * points.size();
		
		//find the total number of columns
		//besides the binary ones, there are ones for the time
		// at which the taxi will reach a point (B_i)
		int ncol_total = ncol + points.size() + 1;
		
		//create the lp instance
		lp = make_lp(0, ncol_total);
		
		//colno and row are used to define the constraints, and
		// later row will store the result from lpsolve
		//colno identifies the variable (column), and row identifies
		// the constants (multiplied by the variable); then, a
		// separate value determines the number of variables
		// that will be read (since we are using a sparse matrix -
		// otherwise we wouldn't need colno)
		//note**: column numbers are labeled starting from 1, not 0
		int *colno = new int[ncol_total];
		REAL *row = new REAL[ncol_total];
		
		//since we're going to be adding constraints equation
		// by equation, we set add row mode to make it faster
		set_add_rowmode(lp, TRUE);
		
		//disable most output from lpsolve
		set_verbose(lp, CRITICAL);
		
		//set timeout of three seconds so we don't spend forever on this model
		set_timeout(lp, 3);
		
		//set up the binary constraints
		for(int i = 0; i < ncol; i++) {
			set_binary(lp, i + 1, TRUE);
		}
		
		//constraints 1 to 3
		//these have one constraint per point
		for(int i = 0; i < points.size(); i++) {
			//1. the total number of route segments to here will
			// be equal to one
			for(int j = 0; j < points.size() + 1; j++) {
				colno[j] = j * points.size() + i + 1;
				row[j] = 1;
			}
			
			add_constraintex(lp, points.size() + 1, row, colno, EQ, 1);
			
			//2. there will be no route segment from here to itself
			colno[0] = (i + 1) * points.size() + i + 1;
			row[0] = 1;
			add_constraintex(lp, 1, row, colno, EQ, 0);
			
			//3. the total number of route segments from here will
			// be less than or equal to one (since the last point in
			// the route will be zero)
			for(int j = 0; j < points.size(); j++) {
				colno[j] = (i + 1) * points.size() + j + 1;
				row[j] = 1;
			}
			
			add_constraintex(lp, points.size(), row, colno, LE, 1);
		}
		
		//4. there will be exactly one route segment from the
		// current location
		for(int i = 0; i < points.size(); i++) {
			colno[i] = i + 1;
			row[i] = 1;
		}
	
		add_constraintex(lp, points.size(), row, colno, EQ, 1);
	
		//5. the relative time that the taxi reaches the current
		// location is zero
		colno[0] = ncol + 1;
		row[0] = 1;
		add_constraintex(lp, 1, row, colno, EQ, 0);
	
		//6. defined for each route segment (i, j)
		//if the segment (i, j) exists, then the time B_j
		// the taxi reaches j will be greater than
		//    B_i + time(i, j)
		// (time is interchangeable with distance)
		//in other words,
		//    B_j >= ( B_i + time(i, j) ) * x_ij
		//
		//**but that's non-linear (since B_i * x_ij)
		//to achieve the if statement, we subtract a large
		// number M from the right and M * x_ij on the left
		//the equation becomes:
		//    B_j - B_i - M*x_ij >= time(i, j) - M
		//
		//m_ij that we found earlier is suitable for M, since
		// if x_ij = 0 the equation reduces to
		//    B_j - B_i >= time(i, j) - M
		// >> M >= B_i + time(i, j) - B_j
		// we used the maximum possible value for B_i (latest[i])
		//  and the minimim for B_j (earliest[j]), so everything
		//  is good :)
		for(int i = 0; i < points.size() + 1; i++) {
			for(int j = 0; j < points.size(); j++) {
				colno[0] = ncol + 1 + i;
				colno[1] = ncol + 1 + j + 1; //make sure to add an extra 1 because we're not including current location
				colno[2] = i * points.size() + j + 1;
			
				double constant = costMatrix[i][j] - m[i][j];
			
				//only use positive constants or it seems to explode
				if(constant >= 0) {
					row[0] = -1;
					row[1] = 1;
					row[2] = -m[i][j];
		
					add_constraintex(lp, 3, row, colno, GE, constant);
				} else {
					row[0] = 1;
					row[1] = -1;
					row[2] = m[i][j];
		
					add_constraintex(lp, 3, row, colno, LE, -constant);
				}
			}
		}
	
		//constraints 7, 8, and 9
		for(int i = 0; i < points.size(); i++) {
			if(points[i]->type == 1) {
				//dropoff point
				
				//make sure to add an extra 1 because we're not including current location
				colno[0] = ncol + 1 + i + 1;
				colno[1] = ncol + 1 + pairIndex[i] + 1;
			
				row[0] = 1;
				row[1] = -1;
			
				//constraints on L_i (= B_i - B_pickup[i])
				
				//7. L_i >= time(pickup[i], i)
				add_constraintex(lp, 2, row, colno, GE, costMatrix[pairIndex[i] + 1][i]);
				
				//8. L_i <= remaining service constraint
				add_constraintex(lp, 2, row, colno, LE, points[i]->remaining);
			} else if(points[i]->type == 0 || points[i]->type == 2) {
				//pickup or stand-alone dropoff point
				colno[0] = ncol + 1 + i + 1;
				row[0] = 1;
				
				//9. B_i <= remaining pickup constraint
				add_constraintex(lp, 1, row, colno, LE, points[i]->remaining);
			}
		}
	
		//10. this used to enforce that all varibles be
		// non-negative, but it seems to be working now
		// (lpsolve makes variables non-negative unless
		// explicitly stated in a constraint)
		for(int i = ncol; i < ncol_total; i++) {
			colno[0] = i + 1;
			row[0] = 1;
			//add_constraintex(lp, 1, row, colno, GE, 0);
		}
		
		//disable rowmode because we're done building model
		set_add_rowmode(lp, FALSE);
		
		//objective function: minimize sum( time(i, j) * x_ij )
		//we maximize the negative though
		// (we could change to set_minim(lp), but it's the same thing)
		for(int i = 0; i < points.size() + 1; i++) {
			for(int j = 0; j < points.size(); j++) {
				colno[i * points.size() + j] = i * points.size() + j + 1;;
				row[i * points.size() + j] = -costMatrix[i][j];
			}
		}
	
		set_obj_fnex(lp, ncol, row, colno);
		set_maxim(lp); //maximize the objective function
		
		struct timeval solveStartTime;
		struct timeval solveEndTime;
		gettimeofday(&solveStartTime, NULL);
		
		int ret = solve(lp);
		
		gettimeofday(&solveEndTime, NULL);
		long tS = solveStartTime.tv_sec*1000000 + (solveStartTime.tv_usec);
		long tE = solveEndTime.tv_sec*1000000 + (solveEndTime.tv_usec);
		long solveTime = tE - tS;
		
		if(iteration == 0 && ret != TIMEOUT) {
			lpTotalTime += solveTime;
			if(solveTime > lpMaxTime) lpMaxTime = solveTime;
			lpNum++;
			
			cout << "lptimestatus: " << lpTotalTime / lpNum << " " << lpMaxTime << " " << lpNum << " " << solveTime << endl;
		}
		
		//if we didn't get the optimal solution, don't continue
		if(ret != OPTIMAL) {
			delete colno;
			delete row;
			delete_lp(lp);
			bestList.clear();
			
			if(ret == TIMEOUT) {
				//if we timed out, then we need to try again
				cout << "timed out on iteration " << iteration << ", advancing..." << endl;
				continue;
			} else {
				return bestList;
			}
		}
	
		get_variables(lp, row); //store variables in our row array
	
		//extract the ordering of the points from the x_ij in the row
		//at the same time, we calculate the route's distance
		
		int previous = 0;
		minTour = 0;
		
		for(int i = 0; i < points.size(); i++) {
			for(int j = 0; j < points.size(); j++) {
				if(row[previous * points.size() + j] == 1) {
					minTour += costMatrix[previous][j];
				
					bestList.push_back(points[j]);
					previous = j + 1;
					break;
				}
			}
		}

		delete colno;
		delete row;
		delete_lp(lp);
		
		//sometimes errors occur, probably because M was
		// too large and double-precision isn't accurate
		// enough
		//in these cases, since they're rare enough, we
		// assume that the model was infeasible
		if(bestList.size() != points.size()) {
			bestList.clear();
			minTour = numeric_limits<double>::max();
			return bestList;
		}
	
		return bestList;
	}
}
Пример #5
0
//Execute function
int LPSolveClass::Execute()
{
	/*
	std::cout << "---------------------------------\n";
	std::cout << "objective function\n";
	for (unsigned int i = 0; i < coefficients.size(); i++)
		std::cout << coefficients[i] << "\t";
	std::cout << "\nConstant Value = " << obj_const << std::endl;

	std::cout << "---------------------------------\n";
	std::cout << "Equality Constraints\n";	
	for (unsigned int i = 0; i < A_equ.size(); i++){
		//std::cout << "Row index = " << i << "\t\t";
		for (unsigned int j = 0; j < A_equ[i].size(); j++)
			std::cout << A_equ[i][j] << "\t";
		std::cout << "\n";
	}
	std::cout << "b\n";
	for (unsigned int i = 0; i < b_equ.size(); i++)
		std::cout << b_equ[i] << "\t";
	std::cout << "\n";


	std::cout << "---------------------------------\n";
	std::cout << "InEquality Constraints\n";	
	for (unsigned int i = 0; i < A_inequ.size(); i++){
		//std::cout << "Row index = " << i << "\t\t";
		for (unsigned int j = 0; j < A_inequ[i].size(); j++)
			std::cout << A_inequ[i][j] << "\t";
		std::cout << "\n";
	}
	std::cout << "b\n";
	for (unsigned int i = 0; i < b_inequ.size(); i++)
		std::cout << b_inequ[i] << "\t";
	std::cout << "\n";
	*/

	lprec *lp;
	int Ncol = coefficients.size(), *colno = NULL, j, ret = 0;
	REAL *row = NULL;
	
	/* We will build the model row by row
     So we start with creating a model with 0 rows and n columns */

	lp = make_lp(0, Ncol);
	if (lp == NULL)
		ret = 1;/* couldn't construct a new model... */
		
	if (ret == 0){
		//let us name our variables
		std::string s = "x";
		for (int i = 0; i < Ncol; i++){
			std::stringstream out;
			out << i;
			s = s + out.str();
			char *cpy = new char[s.size()+1] ;
			strcpy(cpy, s.c_str());			
			set_col_name(lp, i+1, cpy);
		}

		/* create space large enough for one row */
		colno = (int *) malloc(Ncol * sizeof(*colno));
    	row = (REAL *) malloc(Ncol * sizeof(*row));
		if ((colno == NULL) || (row == NULL))
      		ret = 2;
	}

	set_add_rowmode(lp, TRUE);
	//add the equation constraints
	if (ret == 0){
		/* makes building the model faster if it is done rows by row */
		if (A_equ.size() > 0){
			for (unsigned int i = 0; i < A_equ.size(); i++){//loop over the rows of equality constraints
				for (unsigned int j = 0; j < A_equ[i].size(); j++){//loop over the columns of equality constraints
					colno[j] = j+1;//add the j-th column to lpsolve
					row[j] = A_equ[i][j];
				}
				/* add the row to lpsolve */
				if(!add_constraintex(lp, A_equ[i].size(), row, colno, EQ, b_equ[i]))
					ret = 2;
			}
		}
	}
	
	//add the inequality constraints
	if (ret == 0){
		/* makes building the model faster if it is done rows by row */
		if (A_inequ.size() > 0){
			for (unsigned int i = 0; i < A_inequ.size(); i++){//loop over the rows of inequality constraints
				for (unsigned int j = 0; j < A_inequ[i].size(); j++){//loop over the columns of inequality constraints
					colno[j] = j+1;//add the j-th column to lpsolve
					row[j] = A_inequ[i][j];
				}
				/* add the row to lpsolve */
				if(!add_constraintex(lp, A_inequ[i].size(), row, colno, LE, b_inequ[i]))
					ret = 3;
			}
		}
	}

	//add the const constraint	
	if (ret == 0){
		if (b_const.size()>0){
			for (unsigned int i = 0; i < b_const.size(); i++){
				if (b_const[i] > 0){
					for (unsigned int j = 0; j < b_const.size(); j++){
						if (i == j){
							colno[j] = j+1;//add the j-th column to lpsolve
							row[j] = 1.0;						
						}				
						else{
							colno[j] = j+1;//add the j-th column to lpsolve
							row[j] = 0.0;
						}
					}
					if(!add_constraintex(lp, b_const.size(), row, colno, EQ, b_const[i]))
						ret = 4;		
				}
			}
		}
	}

	//set the variables to be integer
	if (ret == 0){
		for (int i = 0; i < Ncol; i++)
			set_int(lp, i+1, TRUE);
	}
	
	/* rowmode should be turned off again when done building the model */
	set_add_rowmode(lp, FALSE);	
	//add the objective function
	if (ret == 0){
		//set the objective function
		for (unsigned int i = 0; i < coefficients.size(); i++){
			colno[i] = i+1;
			row[i] = coefficients[i];
		}
		//set the objective in lpsolve
		if(!set_obj_fnex(lp, coefficients.size(), row, colno))
      		ret = 4;
	}

	//set the objective to minimize
	if (ret == 0){
		set_minim(lp);

		/* just out of curioucity, now show the model in lp format on screen */
    	/* this only works if this is a console application. If not, use write_lp and a filename */
    	write_LP(lp, stdout);

		/* I only want to see important messages on screen while solving */
    	set_verbose(lp, IMPORTANT);

    	/* Now let lpsolve calculate a solution */
    	ret = solve(lp);
    	if(ret == OPTIMAL)
      		ret = 0;
    	else
      		ret = 5;
	}

	//get some results
	if (ret == 0){
		/* a solution is calculated, now lets get some results */

    	/* objective value */
    	std::cout << "Objective value: " << get_objective(lp) << std::endl;

		/* variable values */
    	get_variables(lp, row);

		/* variable values */
		variables.resize(Ncol);
		for(j = 0; j < Ncol; j++)
			variables[j] = row[j];

		/* we are done now */
	}
	else{
		std::cout << "The optimal value can't be solved for linear programming, please check the constraints!!\n";
		exit(1);

	}
		
	
	std::cout << "print the result\t # of line segments is \n";
	for (int i = 0; i < Ncol; i++)
		std::cout << "index = " << i << "\t# = " << variables[i] << std::endl;

	/* free allocated memory */
  	if(row != NULL)
    	free(row);
  	if(colno != NULL)
    	free(colno);

	/* clean up such that all used memory by lpsolve is freed */
	if (lp != NULL)
		delete_lp(lp);

	return ret;
}
Пример #6
0
int CLPLpsolve::addConstraints(
							  int rcnt,
							  const double* rhs,
							  const char* sense,
							  const double* rngval,
							  char** rowname,
							  int numcoefs,
							  const int* rowlist,
							  const int* collist,
							  const double* vallist
							  )
{

	/*
	int rcnt, //number of constraints
	const double* rhs, //constraints's bounds
	const char* sense, //constraints'sense
	const double* rngval,
	char** rowname, //constraints's names
	int numcoefs, //nonzeros variables number
	const int* rowlist, //y index of coeffs
	const int* collist, //x index of coeffs
	const double* vallist //coeffs's table
	*/

	int rowindex = -1, nbVals, constraintCounter = 0;
	int *beglist = new int[rcnt];
	int * cols = new int[numcoefs];
	double *newRhs = new double[rcnt];
	char * newSense = new char[rcnt];
	char ** newRowname = new char*[rcnt];

	for (int i = 0; i < numcoefs; ++i) {

		int newrowindex = rowlist[i];
		if (newrowindex == rowindex)
			continue;

		rowindex = newrowindex;

		beglist[constraintCounter] = i;
		newRhs[constraintCounter] = rhs[rowindex];
		newSense[constraintCounter] = sense[rowindex];

		newRowname[constraintCounter] = rowname[rowindex];
		++constraintCounter;
	}

	for(int i = 0; i < constraintCounter; ++i)
	{
		if(i < constraintCounter - 1)
			nbVals = beglist[i+1] - beglist[i];
		else
			nbVals = numcoefs - beglist[i];

		if(nbVals <= 0)
			continue;

		for (int j = beglist[i]; j < beglist[i] + nbVals; ++j) {
			cols[j - beglist[i]] = collist[j] + 1;
		}

		//m_status = set_rowex(m_env, i + 1, numcoefs, const_cast<double *>(vallist), cols);

		char senseV;
		switch (newSense[i]) {
		case 'L' :
			senseV = LE;
			break;

		case 'G' :
			senseV = GE;
			break;

		case 'E' :
			senseV = EQ;
			break;
		}
		m_status = add_constraintex(m_env, nbVals, &(const_cast<double*>(vallist)[beglist[i]]), cols, senseV ,newRhs[i]);

		//m_status = set_rh_range(m_env, i + 1, rngval[i];
		m_status = set_row_name(m_env, i + 1, newRowname[i]);
	}
	
	delete [] beglist;
	delete [] cols;
	delete [] newRhs;
	delete [] newSense;
	delete [] newRowname;


	return getStatus();
}
Пример #7
0
double solve_constraints(int this_task)
{
	lprec *lp;
	int numVar = 0, *var = NULL, ret = 0, i, j, k, var_count;
	double *coeff = NULL, lhs,rhs, obj;
	char col_name[10];

	/* Creating a model */
	for(i = 1;i < this_task; i++)
		numVar+=i;	
	lp = make_lp(0, numVar);
	if(lp == NULL)
		ret = 1; /* Couldn't construct a new model */
		
	if(ret == 0) {
		var_count = 1;
		for(i = 1 ; i < this_task; i++){
			for(j = i+1 ; j <= this_task; j++)
			{
				sprintf(col_name, "%dNNP%d_%d", this_task, i, j);
				set_col_name(lp, var_count, col_name);
				var_count++;			
			}
		}
		/* create space large enough for one row(i.e. equation) */
		var = (int *) malloc(numVar * sizeof(*var));
		coeff = (double *) malloc(numVar * sizeof(*coeff));
		if((var == NULL) || (coeff == NULL))
			ret = 2;
	}	
	
	/* add the equations to lpsolve */
	if(ret == 0) {
		set_add_rowmode(lp, TRUE);
		/* --------------------adding EQN-D-------------------- */
		for(j = 2;j <= this_task;j++){
			var_count = 0;
			for(i = 1; i < j; i++){
				sprintf(col_name,"%dNNP%d_%d",this_task, i, j);
				var[var_count] = get_nameindex(lp, col_name, FALSE);
				coeff[var_count] = 1;
				var_count++;
			}

			lhs= 0;
			for(i = 1; i < j; i++)
				lhs+= nnp_min[i][j];
			lhs*= floor(R[this_task]/task[j].p);			
			
			rhs = 0;
			for(i = 1; i < j; i++)
				rhs += nnp_max[i][j];
			rhs *= ceil(R[this_task]/task[j].p);
			
			if(!add_constraintex(lp, var_count, coeff, var, GE, lhs))
				ret = 3;
			if(!add_constraintex(lp, var_count, coeff, var, LE, rhs))
				ret = 3;			
		}
	}
	
	if(ret == 0) {	
		/* --------------------adding EQN-E-------------------- */
		for(k = 2;k <= this_task;k++)
		{			
			var_count = 0;
			for(j = 2; j <= k; j++){
				for(i = 1; i < j; i++){
					sprintf(col_name,"%dNNP%d_%d",this_task, i, j);
					var[var_count] = get_nameindex(lp, col_name, FALSE);
					coeff[var_count] = 1;
					var_count++;
				}
			}
			
			rhs = 0;
			for(i = 1; i < k; i++)
				rhs += ceil(R[this_task]/task[i].p);
			if(!add_constraintex(lp, var_count, coeff, var, LE,rhs))
				ret = 3;
		}
	}
	
	if(ret == 0) {
		/* ------------------adding EQN-G & H------------------ */
		for(j = 2; j <= this_task ; j++){
			for(i = 1; i < j; i++){
				lhs= floor(R[this_task]/task[j].p) * nnp_min[i][j];
				sprintf(col_name,"%dNNP%d_%d",this_task, i, j);
				var[0] = get_nameindex(lp, col_name, FALSE);
				coeff[0] = 1;
				if(!add_constraintex(lp, 1, coeff, var, GE, lhs))
					ret = 3;
				
				rhs = min(ceil(R[this_task]/task[i].p), ceil(R[this_task]/task[j].p) * ceil(R[j]/task[i].p), ceil(R[this_task]/task[j].p) * nnp_max[i][j]);
				if(!add_constraintex(lp, 1, coeff, var, LE,rhs))
					ret = 3;
			}
		}
	}
	
	if(ret == 0) {
 		/* --------------------adding EQN-I-------------------- */
		for(i = 1; i < this_task; i++){
			var_count = 0;
			for(j = i+1; j <= this_task; j++){
				sprintf(col_name,"%dNNP%d_%d",this_task, i, j);
				var[var_count] = get_nameindex(lp, col_name, FALSE);
				coeff[var_count] = 1;
				var_count++;				
			}
			rhs = ceil(R[this_task]/task[i].p);
			if(!add_constraintex(lp, var_count, coeff, var, LE,rhs))
				ret = 3;
		}
	}
		
	set_add_rowmode(lp, FALSE);
	if(ret == 0) {
		/* -----------------set the objective----------------- */
		var_count = 0;
		for(i = 1 ; i < this_task; i++){
			for(j = i+1 ; j<= this_task; j++){
				sprintf(col_name,"%dNNP%d_%d",this_task, i, j);
				var[var_count] = get_nameindex(lp, col_name, FALSE);
				coeff[var_count] = get_f(this_task, i, j);
				var_count++;
			}			
		}
		if(!set_obj_fnex(lp, var_count, coeff, var))
			ret = 4;
		set_maxim(lp);
		write_LP(lp, stdout);
		set_verbose(lp, IMPORTANT);
		ret = solve(lp);
		if(ret == OPTIMAL)
			ret = 0;
		else
			ret = 5;
	}
	if(ret == 0) {
		obj = get_objective(lp);
		/* Displaying calculated values */		
		/* variable values */
		printf("\nVariable values:\n");
		get_variables(lp, coeff);
		printf("\n");
		for(j = 0; j < numVar; j++)
			printf("%s: %f\n", get_col_name(lp, j + 1), coeff[j]);		
		/* objective value */
		printf("\nObjective value: %f\n\n", obj);
	}
	printf("LP ERROR = %d\n\n", ret);
	
	/* free allocated memory */
	if(coeff != NULL)
		free(coeff);
	if(var != NULL)
		free(var);
	if(lp != NULL) 		
		delete_lp(lp);
	
	return ret == 0 ? obj : 0;
}
Пример #8
0
    int  calculate (IN  int nCols /* variables in the model */,
                    IN  int nRows,
                    IN  double** rows,
                    IN  double*  rights,
                    IN  double*  objectives,
                    OUT int* answer,
                    IN  int verbose)
    {
      lprec *lp;
      int result = 0;

      char *str = NULL;
      int *colno = NULL;
      double *row = NULL;

      /*  We will build the model row by row
       *  So we start with creating a model
       *  with 0 rows and 2 columns
       */
      if ( !(lp = make_lp (0, nCols)) )
      { 
        /* couldn't construct a new model... */
        result = 1;
        goto RESULT;
      }

      if ( !(str = (char*) malloc ((log10 (nCols) + 10) * sizeof (*str))) )
      {
        result = 2;
        goto RESULT;
      }

      /*  let us name our variables. Not required, 
       *  but can be useful for debugging
       */
      for ( int i = 1; i <= nCols; ++i )
      {       
        str[0] = 't';
        _itoa (i, str + 1, 10);

        set_col_name (lp, i, str);
        // set_int (lp, i, TRUE);
      }

      /* create space large enough for one row */
      colno = (int   *) malloc (nCols * sizeof (*colno));
      row   = (double*) malloc (nCols * sizeof (*row));

      if ( (colno == NULL) || (row == NULL) )
      {
        result = 2;
        goto RESULT;
      }

      for ( int j = 0; j < nCols; ++j )
      { colno[j] = j + 1; /* (j + 1) column */ }

      /* makes building the model faster if it is done rows by row */
      set_add_rowmode (lp, TRUE);
      
      for ( int i = 0; i < nRows; ++i )
      {
        // /* construct j row */
        // for ( int j = 0; j < nCols; ++j )
        // { row[j] = ??? ; }

        /* (210 * t2 + 156 * t3 == 0.0178) */
        /* (230 * t2 + 160 * t3 == 0.0176) */

        /* add the row to lp_solve */
        if ( !add_constraintex (lp, nCols, rows[i], colno, EQ, rights[i]) )
        {
          result = 3;
          goto RESULT;
        }
      }

      /* rowmode should be turned off again when done building the model */
      set_add_rowmode (lp, FALSE); 

      // /* set the objective function  */
      // for ( int j = 0; j < nCols; ++j )
      // { row[j] = objectives[j]; }

      /* (t1 + t2 + t3 + t4) */

      /* set the objective in lp_solve */
      if ( !set_obj_fnex (lp, nCols, objectives, colno) )
      {
        result = 4;
        goto RESULT;
      }
      
      /* set the object direction to maximize */
      set_minim (lp);

      if ( verbose )
      {
        /* just out of curioucity, now show the model in lp format on screen */
        /* this only works if this is a console application. If not, use write_lp and a filename */
        write_LP (lp, stdout);
        /* write_lp(lp, "model.lp"); */
      }
      
      /* I only want to see important messages on screen while solving */
      set_verbose (lp, IMPORTANT);
      
      /* Now let lpsolve calculate a solution */
      result = solve (lp);
      if ( result == OPTIMAL )
      { result = 0; }
      else
      {
        result = 5;
        goto RESULT;
      }

      /*  a solution is calculated,
       *  now lets get some results
       */
      if ( verbose )
      {
        /* objective value */
        printf ("Objective value: %f\n", get_objective (lp));
      }

      /* variable values */
      get_variables (lp, row);
      for ( int j = 0; j < nCols; j++ )
      {
        if ( verbose )
          printf ("%s: %f\n", get_col_name (lp, j + 1), row[j]);
        
        answer[j] = row[j];
      }
      /* we are done now */

RESULT:;
      /* free allocated memory */
      if ( str != NULL )free (str);
      if ( row != NULL ) free (row);
      if ( colno != NULL ) free (colno);

      if ( lp != NULL )
      {
        /* clean up such that all used memory by lpsolve is freed */
        delete_lp (lp);
      }

      return result;
    }
Пример #9
0
void LoadBalancing::lp_create_model() {
	int Ncol=3*num_using_nodes_+(num_using_nodes_-1)*(num_quantiles_+2);
	int i,j;
	int *colno=(int*)malloc((Ncol+1)*sizeof(int));
	REAL *row=(REAL*)malloc((Ncol+1)*sizeof(REAL));
	int *sosvars=(int*)malloc((num_quantiles_+2)*sizeof(int));
	int ret;

	lp = make_lp(0,Ncol);
	if(lp == NULL) {
		fprintf(stderr, "Unable to create new LP model\n");
//		return(-1);
	}
	resize_lp(lp, 6*num_using_nodes_-3, Ncol);

	//Set objective function
	set_obj(lp,num_using_nodes_+1,1);

	//Add constraints:
	set_add_rowmode(lp, TRUE);

	// D*x + E*ip - t <= -G
	for(i=0;i<num_using_nodes_;i++){
		for(j=0;j<num_using_nodes_;j++){
			colno[j]=POS_Xi(j);
			row[j]=lp_D[i*num_using_nodes_+j];
		}
		colno[j]=POS_IPi(i); //ip(i);
		row[j]=Mopt_*lp_E[i];
		colno[j+1]=POS_T;
		row[j+1]=-1;// -t
		add_constraintex(lp,j+2,row,colno,LE,-lp_G[i]);
	}

	//Increasing constraints, considering the overlap, (x[n]-x[n+1]<=-2*overlap_)
	for(i=0;i<num_using_nodes_-2;i++){
		colno[0]=POS_Xi(i);
		row[0]=1;
		colno[1]=POS_Xi(i+1);
		row[1]=-1;
		add_constraintex(lp,2,row,colno,LE,-2*overlap_);
	}
	colno[0]=POS_Xi(i);
	row[0]=1;
	colno[1]=POS_Xi(i+1);
	row[1]=-1;
	add_constraintex(lp,2,row,colno,LE,-overlap_);


	//And the last cut must be 1: (x[num_using_nodes_]=1)
	colno[0]=POS_Xi(num_using_nodes_-1);
	row[0]=1;
	add_constraintex(lp,1,row,colno,EQ,1);

	//And now we define the number of interest points for each cut (ip1, ip2,...)
	// ip1=f1
	// ip2=f2-f1
	// ip3=f3-f2
	// ipN=1-f3

	//ip1:
	colno[0]=POS_IPi(0); //ip1
	row[0]=-1;
	colno[1]=POS_Fi(0); //f1
	row[1]=1;
	add_constraintex(lp,2,row,colno,EQ,0);

	//ip2 to ip(N-1):
	for(i=1;i<num_using_nodes_-1;i++){
		colno[0]=POS_IPi(i); //ip(i)
		row[0]=-1;
		colno[1]=POS_Fi(i); //f(i)
		row[1]=1;
		colno[2]=POS_Fi(i-1); //f(i-1)
		row[2]=-1;
		add_constraintex(lp,3,row,colno,EQ,0);
	}

	//ipN:
	colno[0]=POS_IPi(num_using_nodes_-1); //ipN
	row[0]=1;
	colno[1]=POS_Fi(num_using_nodes_-2); //f(N-1)
	row[1]=1;
	add_constraintex(lp,2,row,colno,EQ,1);


	//SOS variables:
	// d10+d11+d12+d13+...=1
	for(i=0;i<num_using_nodes_-1;i++){
		for(j=0;j<num_quantiles_+2;j++){
			colno[j]=POS_Dij(i,j);
			row[j]=1;
			sosvars[j]=POS_Dij(i,j);
		}
		char sosName[] = "SOS"; //Gives a warning otherwise...
		add_SOS(lp, sosName, 2, 1, num_quantiles_+2, sosvars, NULL);
		add_constraintex(lp,num_quantiles_+2,row,colno,EQ,1);
	}

	//So now we define the piecewise functions f (number of interest points left of x)
	for(i=0;i<num_using_nodes_-1;i++){
		colno[0]=POS_Fi(i); //fi
		row[0]=-1;
		for(j=0;j<num_quantiles_;j++){
			colno[j+1]=POS_Dij(i,j+1);
			row[j+1]=(j+1.0)/num_quantiles_;
		}
		colno[j+1]=POS_Dij(i,j+1);
		row[j+1]=1;
		add_constraintex(lp,num_quantiles_+2,row,colno,EQ,0);
	}

	// Now x1=q1*d11 + q2*d12 + ...
	for(i=0;i<num_using_nodes_-1;i++){
		colno[0]=POS_Xi(i);
		row[0]=-1;
		for(j=0;j<num_quantiles_;j++){
			colno[j+1]=POS_Dij(i,j+1);
			row[j+1]=(float)IPx_quantile_aprox_.at(j)/width_;
		}
		colno[j+1]=POS_Dij(i,j+1);
		row[j+1]=1;
		add_constraintex(lp,num_quantiles_+2,row,colno,EQ,0);
	}

	set_add_rowmode(lp, FALSE);

	free(colno);
	free(row);
	free(sosvars);
	is_lpmodel_created_=true;
}
Пример #10
0
int demo()
{
    lprec *lp;
    int Ncol, *colno = NULL, j, ret = 0;
    REAL *row = NULL;

    /* We will build the model row by row
       So we start with creating a model with 0 rows and 2 columns */
    Ncol = 2; /* there are two variables in the model */
    lp = make_lp(0, Ncol);
    if(lp == NULL)
        ret = 1; /* couldn't construct a new model... */

    if(ret == 0) {
        /* let us name our variables. Not required, but can be useful for debugging */
        set_col_name(lp, 1, "x");
        set_col_name(lp, 2, "y");

        /* create space large enough for one row */
        colno = (int *) malloc(Ncol * sizeof(*colno));
        row = (REAL *) malloc(Ncol * sizeof(*row));
        if((colno == NULL) || (row == NULL))
            ret = 2;
    }

    if(ret == 0) {
        set_add_rowmode(lp, TRUE);  /* makes building the model faster if it is done rows by row */

        /* construct first row (120 x + 210 y <= 15000) */
        j = 0;

        colno[j] = 1; /* first column */
        row[j++] = 120;

        colno[j] = 2; /* second column */
        row[j++] = 210;

        /* add the row to lpsolve */
        if(!add_constraintex(lp, j, row, colno, LE, 15000))
            ret = 3;
    }

    if(ret == 0) {
        /* construct second row (110 x + 30 y <= 4000) */
        j = 0;

        colno[j] = 1; /* first column */
        row[j++] = 110;

        colno[j] = 2; /* second column */
        row[j++] = 30;

        /* add the row to lpsolve */
        if(!add_constraintex(lp, j, row, colno, LE, 4000))
            ret = 3;
    }

    if(ret == 0) {
        /* construct third row (x + y <= 75) */
        j = 0;

        colno[j] = 1; /* first column */
        row[j++] = 1;

        colno[j] = 2; /* second column */
        row[j++] = 1;

        /* add the row to lpsolve */
        if(!add_constraintex(lp, j, row, colno, LE, 75))
            ret = 3;
    }

    if(ret == 0) {
        set_add_rowmode(lp, FALSE); /* rowmode should be turned off again when done building the model */

        /* set the objective function (143 x + 60 y) */
        j = 0;

        colno[j] = 1; /* first column */
        row[j++] = 143;

        colno[j] = 2; /* second column */
        row[j++] = 60;

        /* set the objective in lpsolve */
        if(!set_obj_fnex(lp, j, row, colno))
            ret = 4;
    }

    if(ret == 0) {
        /* set the object direction to maximize */
        set_maxim(lp);

        /* just out of curioucity, now show the model in lp format on screen */
        /* this only works if this is a console application. If not, use write_lp and a filename */
        write_LP(lp, stdout);
        /* write_lp(lp, "model.lp"); */

        /* I only want to see important messages on screen while solving */
        set_verbose(lp, IMPORTANT);

        /* Now let lpsolve calculate a solution */
        ret = solve(lp);
        if(ret == OPTIMAL)
            ret = 0;
        else
            ret = 5;
    }

    if(ret == 0) {
        /* a solution is calculated, now lets get some results */

        /* objective value */
        printf("Objective value: %f\n", get_objective(lp));

        /* variable values */
        get_variables(lp, row);
        for(j = 0; j < Ncol; j++)
            printf("%s: %f\n", get_col_name(lp, j + 1), row[j]);

        /* we are done now */
    }

    /* free allocated memory */
    if(row != NULL)
        free(row);
    if(colno != NULL)
        free(colno);

    if(lp != NULL) {
        /* clean up such that all used memory by lpsolve is freed */
        delete_lp(lp);
    }

    return(ret);
}