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; }
// 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); }
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; }
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; } }
//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; }
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(); }
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; }
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; }
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; }
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); }