/* maximise the objective function */ void __declspec(dllexport) WINAPI _set_maxim(lprec *lp) { if (lp != NULL) { freebuferror(); set_maxim(lp); } }
bool CFeasibilityMap::SolveLP(Matrix & A, ColumnVector &b, bool domax) { lprec *lp ; int n_row = A.nrows(); int n_col = A.ncols(); lp = make_lp(0,n_col) ; double *input_row = new double[1+n_col]; for (int i_row=1; i_row<=n_row; i_row++){ input_row[0] = 0 ; for (int j=1; j<=n_col; j++){ input_row[j] = A(i_row,j) ; } add_constraint(lp, input_row, LE, b(i_row)) ; } delete [] input_row; // we don't even need an objective function !! double *input_obj = new double[1+n_col]; // The first zero is for matrix form input_obj[0] = 0 ; for (int j=1; j<=n_col; j++){ input_obj[j] = 1 ; } set_obj_fn(lp, input_obj) ; if (domax) { set_maxim(lp); } delete [] input_obj; set_verbose(lp, IMPORTANT); // NEUTRAL (0), IMPORTANT (3), NORMAL (4), FULL (6) bool is_feasible = (solve(lp)==0); // 0: feasible solution found, 2: not found // solution for minimizing objective function delete_lp(lp); return is_feasible; }
void LP::setObjective(const size_t n, const bool maximize) { set_obj(pimpl_->lp_.get(), n+1, 1.0); if (maximize) set_maxim(pimpl_->lp_.get()); else set_minim(pimpl_->lp_.get()); maximize_ = maximize; }
void LP::setObjective(const bool maximize) { set_obj_fn(pimpl_->lp_.get(), pimpl_->conversionData()); if (maximize) set_maxim(pimpl_->lp_.get()); else set_minim(pimpl_->lp_.get()); maximize_ = maximize; }
bool CFeasibilityMap::SolveLP(Matrix &A, ColumnVector &b, ColumnVector &x) { lprec *lp ; int n_row = A.nrows(); int n_col = A.ncols(); x = ColumnVector(n_col); x = 0; lp = make_lp(0,n_col) ; double *input_row = new double[1+n_col]; for (int i_row=1; i_row<=n_row; i_row++){ input_row[0] = 0 ; // The first zero is for matrix form for (int j=1; j<=n_col; j++){ input_row[j] = A(i_row,j) ; } add_constraint(lp, input_row, LE, b(i_row)) ; } delete [] input_row; double *input_obj = new double[1+n_col]; // The first zero is for matrix form input_obj[0] = 0 ; for (int j=1; j<=n_col; j++){ input_obj[j] = 1 ; } set_obj_fn(lp, input_obj) ; delete [] input_obj; set_verbose(lp, IMPORTANT); // NEUTRAL (0), IMPORTANT (3), NORMAL (4), FULL (6) bool is_feasible = (solve(lp)==0); // 0: feasible solution found, 2: not found // solution for minimizing objective function double* x_min = new double[n_col]; double* x_max = new double[n_col]; if (is_feasible) { get_variables(lp, x_min); set_maxim(lp); is_feasible = (solve(lp)==0); // 0: feasible solution found, 2: not found if (is_feasible) { get_variables(lp, x_max); for (int i = 0; i < n_col; i++) { x(i+1) = (x_min[i] + x_max[i]) / 2.0; } } } delete [] x_min; delete [] x_max; delete_lp(lp); return is_feasible; }
int demoImplicit(void) { # if defined ERROR # undef ERROR # endif # define ERROR() { fprintf(stderr, "Error\n"); return(1); } lprec *lp; int majorversion, minorversion, release, build; char buf[1024]; if ((lp = make_lp(0,4)) == NULL) ERROR(); lp_solve_version(&majorversion, &minorversion, &release, &build); /* let's first demonstrate the logfunc callback feature */ put_logfunc(lp, Mylogfunc, 0); sprintf(buf, "lp_solve %d.%d.%d.%d demo\n\n", majorversion, minorversion, release, build); print_str(lp, buf); solve(lp); /* just to see that a message is send via the logfunc routine ... */ /* ok, that is enough, no more callback */ put_logfunc(lp, NULL, 0); /* Now redirect all output to a file */ /* set_outputfile(lp, "result.txt"); */ /* set an abort function. Again optional */ put_abortfunc(lp, Myctrlcfunc, 0); /* set a message function. Again optional */ put_msgfunc(lp, Mymsgfunc, 0, MSG_PRESOLVE | MSG_LPFEASIBLE | MSG_LPOPTIMAL | MSG_MILPEQUAL | MSG_MILPFEASIBLE | MSG_MILPBETTER); 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"); 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("str_add_constraint(lp, \"3 2 2 1\" ,LE,4)\n"); printf("This is the string version of add_constraint. For the normal version\n"); printf("of add_constraint see the help file.\n"); if (!str_add_constraint(lp, "3 2 2 1", LE, 4)) ERROR(); print_lp(lp); press_ret(); printf("str_add_constraint(lp, \"0 4 3 1\" ,GE,3)\n"); if (!str_add_constraint(lp, "0 4 3 1", GE, 3)) ERROR(); print_lp(lp); press_ret(); printf("Set the objective function\n"); printf("str_set_obj_fn(lp, \"2 3 -2 3\")\n"); if (!str_set_obj_fn(lp, "2 3 -2 3")) 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"); if (!str_add_constraint(lp, "1 2 1 4", EQ, 8)) ERROR(); print_lp(lp); press_ret(); printf("A column can be added with:\n"); printf("str_add_column(lp,\"3 2 2\");\n"); if (!str_add_column(lp,"3 2 2")) 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(); delete_lp(lp); /* printf("A lp structure can be created and read from a .lp file\n"); printf("lp = read_LP(\"lp_examples/demo_lag.lp\", TRUE);\n"); printf("The verbose option is used\n"); if ((lp = read_LP("lp_examples/demo_lag.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(); printf("You can see that branch & bound was used in this problem\n"); printf("Now remove the last constraint and use lagrangian relaxation\n"); printf("del_constraint(lp,6);\n"); printf("str_add_lag_con(lp, \"1 1 1 0 0 0\", LE, 2);\n"); del_constraint(lp,6); if (!str_add_lag_con(lp, "1 1 1 0 0 0", LE, 2)) ERROR(); print_lp(lp); */ /* printf("Lagrangian relaxation is used in some heuristics. It is now possible\n"); printf("to get a feasible integer solution without usage of branch & bound.\n"); printf("Use lag_solve(lp, 0, 30); 0 is the initial bound, 30 the maximum\n"); printf("number of iterations, the last variable turns the verbose mode on.\n"); press_ret(); set_lag_trace(lp, TRUE); printf("%d\n",lag_solve(lp, 0, 30)); printf("The returncode of lag_solve is 6 or FEAS_FOUND. this means that a feasible\n"); printf("solution has been found. For a list of other possible return values\n"); printf("see the help file. Print this solution with print_objective, print_solution\n"); print_objective(lp); print_solution(lp, 1); print_constraints(lp, 1); delete_lp(lp); */ press_ret(); return(0); }
int main(void) { lprec *lp1,*lp2; FILE *input_file; printf("lp_solve 2.0 demo by Jeroen J. Dirks ([email protected])\n\n"); printf("This demo will show most of the features of lp_solve 2.0\n"); press_ret(); printf("\nWe start by creating a new problem with 4 variables and 0 constraints\n"); printf("We use: lp1=make_lp(0,4);\n"); lp1=make_lp(0,4); press_ret(); printf("We can show the current problem with print_lp(lp1)\n"); print_lp(lp1); press_ret(); printf("Now we add some constraints\n"); printf("str_add_constraint(lp1, \"3 2 2 1\" ,LE,4)\n"); printf("This is the string version of add_constraint. For the normal version\n"); printf("of add_constraint see the file lpkit.h\n"); str_add_constraint(lp1, "3 2 2 1", LE, 4); print_lp(lp1); press_ret(); printf("str_add_constraint(lp1, \"0 4 3 1\" ,GE,3)\n"); str_add_constraint(lp1, "0 4 3 1", GE, 3); print_lp(lp1); press_ret(); printf("Set the objective function\n"); printf("str_set_obj_fn(lp1, \"2 3 -2 3\")\n"); str_set_obj_fn(lp1, "2 3 -2 3"); print_lp(lp1); press_ret(); printf("Now solve the problem with printf(solve(lp1));\n"); printf("%d",solve(lp1)); press_ret(); printf("The value is 0, this means we found an optimal solution\n"); printf("We can display this solution with print_solution(lp1)\n"); print_solution(lp1); press_ret(); printf("The dual variables of the solution are printed with\n"); printf("print_duals(lp1);\n"); print_duals(lp1); press_ret(); printf("We can change a single element in the matrix with\n"); printf("set_mat(lp1,2,1,0.5)\n"); set_mat(lp1,2,1,0.5); print_lp(lp1); press_ret(); printf("It we want to maximise the objective function use set_maxim(lp1);\n"); set_maxim(lp1); print_lp(lp1); press_ret(); printf("after solving this gives us:\n"); solve(lp1); print_solution(lp1); print_duals(lp1); press_ret(); printf("Change the value of a rhs element with set_rh(lp1,1,7.45)\n"); set_rh(lp1,1,7.45); print_lp(lp1); solve(lp1); print_solution(lp1); press_ret(); printf("We change Var[4] to the integer type with\n"); printf("set_int(lp1, 4, TRUE)\n"); set_int(lp1, 4, TRUE); print_lp(lp1); printf("We set branch & bound debugging on with lp1->debug=TRUE\n"); lp1->debug=TRUE; printf("and solve...\n"); press_ret(); solve(lp1); print_solution(lp1); press_ret(); printf("We can set bounds on the variables with\n"); printf("set_lowbo(lp1,2,2); & set_upbo(lp1,4,5.3)\n"); set_lowbo(lp1,2,2); set_upbo(lp1,4,5.3); print_lp(lp1); press_ret(); solve(lp1); print_solution(lp1); press_ret(); printf("Now remove a constraint with del_constraint(lp1, 1)\n"); del_constraint(lp1,1); print_lp(lp1); printf("Add an equality constraint\n"); str_add_constraint(lp1, "1 2 1 4", EQ, 8); print_lp(lp1); press_ret(); printf("A column can be added with:\n"); printf("str_add_column(lp1,\"3 2 2\");\n"); str_add_column(lp1,"3 2 2"); print_lp(lp1); press_ret(); printf("A column can be removed with:\n"); printf("del_column(lp1,3);\n"); del_column(lp1,3); print_lp(lp1); press_ret(); printf("We can use automatic scaling with:\n"); printf("auto_scale(lp1);\n"); auto_scale(lp1); print_lp(lp1); press_ret(); printf("The function mat_elm(lprec *lp, int row, int column) returns a single\n"); printf("matrix element\n"); printf("%s mat_elm(lp1,2,3), mat_elm(lp1,1,1); gives\n","printf(\"%f %f\\n\","); printf("%f %f\n",mat_elm(lp1,2,3), mat_elm(lp1,1,1)); printf("Notice that mat_elm returns the value of the original unscaled problem\n"); press_ret(); printf("It there are any integer type variables, then only the rows are scaled\n"); printf("set_int(lp1,3,FALSE);\n"); printf("auto_scale(lp1);\n"); set_int(lp1,3,FALSE); auto_scale(lp1); print_lp(lp1); press_ret(); solve(lp1); printf("print_solution gives the solution to the original problem\n"); print_solution(lp1); press_ret(); printf("Scaling is turned off with unscale(lp1);\n"); unscale(lp1); print_lp(lp1); press_ret(); printf("Now turn B&B debugging of and simplex tracing on with\n"); printf("lp1->debug=FALSE, lp1->trace=TRUE and solve(lp1)\n"); lp1->debug=FALSE; lp1->trace=TRUE; press_ret(); solve(lp1); 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("reset_basis(lp1). Now solve it again...\n"); press_ret(); reset_basis(lp1); solve(lp1); press_ret(); printf("It is possible to give variables and constraints names\n"); printf("set_row_name(lp1,1,\"speed\"); & set_col_name(lp1,2,\"money\")\n"); set_row_name(lp1,1,"speed"); set_col_name(lp1,2,"money"); print_lp(lp1); 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(lp1,1);\n"); del_column(lp1,1); print_lp(lp1); press_ret(); printf("A lp structure can be created and read from a .lp file\n"); printf("input_file=fopen(\"lp_examples/demo_lag.lp\",\"r\");\n"); printf("lp2 = read_lp_file(input_file, TRUE);\n"); printf("The verbose option is used\n"); input_file = fopen("lp_examples/demo_lag.lp", "r"); if (input_file == NULL) { printf("Can't find demo_lag.lp, stopping\n"); exit(EXIT_FAILURE); } lp2 = read_lp_file(input_file, TRUE, "test"); press_ret(); printf("lp2 is now:\n"); print_lp(lp2); press_ret(); printf("solution:\n"); lp2->debug=TRUE; solve(lp2); lp2->debug=FALSE; print_solution(lp2); press_ret(); printf("You can see that branch & bound was used in this problem\n"); printf("Now remove the last constraint and use lagrangian relaxation\n"); printf("del_constraint(lp2,6);\n"); printf("str_add_lag_con(lp2, \"1 1 1 0 0 0\", LE, 2);\n"); del_constraint(lp2,6); str_add_lag_con(lp2, "1 1 1 0 0 0", LE, 2); print_lp(lp2); printf("Lagrangian relaxation is used in some heuristics. It is now possible\n"); printf("to get a feasible integer soltution without usage of branch & bound.\n"); printf("Use lag_solve(lp2, 0, 40, TRUE); 0 is the initial bound, 30 the maximum\n"); printf("number of iterations, the last variable turns the verbose mode on.\n"); press_ret(); printf("%d\n",lag_solve(lp2, 0, 30, TRUE)); printf("The returncode of lag_solve is 6 or FEAS_FOUND. this means that a feasible\n"); printf("solution has been found. For a list of other possible return values\n"); printf("see \"lpkit.h\". Print this solution with print_solution\n"); print_solution(lp2); press_ret(); return(0); }
// check, if v is a positive integer combination of the vectors in gens bool is_spanned_by(const VecSparse& v, const std::set<VecSparse>& gens) { #ifdef LPSOLVE_OPT // std::cout << "Check: is " << v << "spanned by " << gens << "?..."; if(gens.empty()) { return false; } if(v.empty()) { return true; } if(gens.find(v) != gens.end()) { //std::cout << "trivially spanned!"<<std::endl; return true; } lprec *lp; unsigned int N = gens.size(); // dim = number of variables that "gens" is talking about (altogether) //collect the variables of all the sparse vectors (v and gens) and number them unsigned int num_vars = 1; //we start counting at 1, since the 0-th row will be the values of the objective function std::map<VarPtr, unsigned int> vars; for(auto &pair : v) { if(vars.find(pair.first) == vars.end()) { vars[pair.first] = num_vars; num_vars++; } } for(auto &g : gens) { for(auto &pair : g) { if(vars.find(pair.first) == vars.end()) { vars[pair.first] = num_vars; num_vars++; } } } unsigned int dim = num_vars-1; lp = make_lp(dim, N); //first row = objective function (will be zeros in our case)! if(lp==NULL) { std::cerr << "ERROR: could not create LP (make_lp) of size " << dim+1 << "," << N << std::endl; return false; } set_verbose(lp, IMPORTANT); int colno = 1; // set the columns of the LP to the generators for (auto &g : gens) { int num_entries = g.size(); //std::cout << "num_entries: " << num_entries << std::endl; REAL *sparsecolumn = new REAL[num_entries]; //non-zero-vals int *rowno = new int[num_entries]; //numbers of the non-zero rows int idx = 0; //assemble the columns and write them to the LP for(auto &pair : g) { sparsecolumn[idx] = pair.second; rowno[idx] = vars[pair.first]; idx++; } set_columnex(lp, colno, num_entries, sparsecolumn, rowno); colno++; delete[] sparsecolumn; delete[] rowno; } // set the rhs to v REAL *rhs = new REAL[dim+1]; for(auto pair : v) { rhs[vars[pair.first]] = pair.second; } set_rh_vec(lp, rhs); delete[] rhs; // set all variables to be integers and >=0 for(int i=1; i<=N; i++){ set_int(lp, i, TRUE); // set_lowbo(lp, i, 0); // the default should be 0 anyways } for(int i=1; i<=dim; i++){ set_constr_type(lp, i, EQ); } set_maxim(lp); //print_lp(lp); int ret = solve(lp); if(ret == 0) { // std::cout << "yes!" << std::endl; //feasible solution found /* REAL *row = new REAL[N]; get_variables(lp, row); for(int j = 0; j < N; j++) printf("%s: %f\n", get_col_name(lp, j + 1), row[j]); delete[] row; */ return true; } else if(ret == 2) { // std::cout << "no!" << std::endl; // LP is infeasible return false; } else { std::cerr << "ERROR: lp_solve returned: " << ret << std::endl; return false; } #else return false; #endif }
main(int argc, char **argv) #endif { char *stub; ASL *asl; FILE *nl; lprec *lp; ograd *og; int ct, i, intmin, *is, j, j0, j1, k, nalt, rc; short *basis, *lower; real *LU, *c, lb, objadj, *rshift, *shift, t, ub, *x, *x0, *x1; char buf[256]; typedef struct { char *msg; int code; } Sol_info; static Sol_info solinfo[] = { { "optimal", 0 }, { "integer programming failure", 502 }, { "infeasible", 200 }, { "unbounded", 300 }, { "failure", 501 }, { "bug", 500 } }; sprintf(lp_solve_version+9, "%.*s", (int)sizeof(lp_solve_version)-10, PATCHLEVEL); sprintf(lp_solve_vversion, "%s, driver(20001002)", lp_solve_version); asl = ASL_alloc(ASL_read_f); stub = getstub(&argv, &Oinfo); nl = jac0dim(stub, (fint)strlen(stub)); suf_declare(suftab, sizeof(suftab)/sizeof(SufDecl)); /* set A_vals to get the constraints column-wise */ A_vals = (real *)M1alloc(nzc*sizeof(real)); f_read(nl,0); lp = make_lp(n_con, 0); Oinfo.uinfo = (char *)lp; if (getopts(argv, &Oinfo)) return 1; i = n_var + n_con + 1; x = (real*)M1alloc(i*sizeof(real)); /* scratch vector */ memset(x, 0, i*sizeof(real)); x0 = x++; c = x + n_con; /* supply objective */ objadj = 0; if (--nobj >= 0 && nobj < n_obj) { for(og = Ograd[nobj]; og; og = og->next) c[og->varno] = og->coef; if (objtype[nobj]) set_maxim(lp); objadj = objconst(nobj); } /* supply columns and variable bounds */ LU = LUv; intmin = n_var - (nbv + niv); j1 = nalt = 0; rshift = shift = 0; for(i = 1; i <= n_var; i++, LU += 2) { lb = LU[0]; ub = LU[1]; j0 = j1; j1 = A_colstarts[i]; *x0 = *c++; /* cost coefficient */ if (lb <= negInfinity && ub < Infinity) { /* negate this variable */ nalt++; lb = -ub; ub = -LU[0]; for(j = j0; j < j1; j++) x[A_rownos[j]] = -A_vals[j]; *x0 = -*x0; add_column(lp, x0); if (lb) goto shift_check; } else { for(j = j0; j < j1; j++) x[A_rownos[j]] = A_vals[j]; add_column(lp, x0); if (lb <= negInfinity) { nalt++; if (i > intmin) set_int(lp, lp->columns, TRUE); /* split free variable */ *x0 = -*x0; for(j = j0; j < j1; j++) x[A_rownos[j]] *= -1.; add_column(lp,x0); } else if (lb) { shift_check: if (lb > 0) set_lowbo(lp, lp->columns, lb); else { if (!rshift) { rshift = (real*)M1zapalloc( (n_var+n_con)*sizeof(real)); shift = rshift + n_con - 1; } shift[i] = lb; for(j = j0; j < j1; j++) { k = A_rownos[j]; rshift[k] += lb*x[k]; } if (ub < Infinity) ub -= lb; objadj += lb**x0; } } if (ub < Infinity) set_upbo(lp, lp->columns, ub); } for(j = j0; j < j1; j++) x[A_rownos[j]] = 0; if (i > intmin) set_int(lp, lp->columns, TRUE); } if (objadj) { /* add a fixed variable to adjust the objective value */ *x0 = objadj; add_column(lp, x0); set_lowbo(lp, i, 1.); set_upbo(lp, i, 1.); } /* supply constraint rhs */ LU = LUrhs; for(i = 1; i <= n_con; i++, LU += 2) { t = LU[0]; if (t == LU[1]) ct = EQ; else if (t <= negInfinity) { t = LU[1]; if (t >= Infinity) { /* This is possible only with effort: */ /* one must turn presolve off and */ /* explicitly specify a constraint */ /* with infinite bounds. */ fprintf(Stderr, "Sorry, can't handle free rows.\n"); exit(1); } ct = LE; } else ct = GE; set_constr_type(lp, i, ct); set_rh(lp, i, rshift ? t - *rshift++ : t); if (ct == GE && LU[1] < Infinity) lp->orig_upbo[i] = LU[1] - t; } if (prlp) print_lp(lp); if (scaling) auto_scale(lp); /* Unfortunately, there seems to be no way to suggest */ /* a starting basis to lp_solve; thus we must ignore */ /* any incoming .sstatus values. */ rc = solve(lp); if (rc < 0 || rc > 5) rc = 5; solve_result_num = solinfo[rc].code; i = sprintf(buf, "%s: %s", Oinfo.bsname, solinfo[rc].msg); if (rc == OPTIMAL) i += sprintf(buf+i, ", objective %.*g", obj_prec(), lp->best_solution[0]); i += sprintf(buf+i,"\n%d simplex iterations", lp->total_iter); if (lp->max_level > 1 || lp->total_nodes > 1) sprintf(buf+i, "\n%d branch & bound nodes: depth %d", lp->total_nodes, lp->max_level); /* Prepare to report solution: deal with split free variables. */ x1 = lp->best_solution+lp->rows+1; if (nalt || shift) { x = x0; LU = LUv; for(i = 0; i < n_var; i++, LU += 2) { if (LU[0] > negInfinity) x[i] = *x1++; else if (LU[1] < Infinity) x[i] = -*x1++; else { x[i] = x1[0] - x1[1]; x1 += 2; } if (shift) x[i] += *++shift; } } else x = x1; if (solinfo[rc].code < 500 && !(nbv + niv)) { /* return .sstatus values */ basis = lp->basis; lower = lp->lower; is = M1alloc((n_var + n_con)*sizeof(int)); suf_iput("sstatus", ASL_Sufkind_con, is); for(i = 0; i < n_con; i++) { j = *++lower; *is++ = *++basis ? 1 : j ? 3 : 4; } suf_iput("sstatus", ASL_Sufkind_var, is); LU = LUv; for(i = 0; i < n_var; i++, LU += 2) { j0 = *++basis; j1 = *++lower; if (LU[0] > negInfinity) j = j0 ? 1 : j1 ? 3 : 4; else if (LU[1] < Infinity) j = j0 ? 1 : j1 ? 4 : 3; else { ++lower; j = *++basis || j0; } *is++ = j; } } write_sol(buf, x, lp->duals+1, &Oinfo); /* The following calls would only be needed */ /* if execution were to continue... */ delete_lp(lp); ASL_free(&asl); return 0; }
Solution LpsolveAdaptator::getBestSolution(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); TermList terms = lp->getObjective().getTerms(); int i = 0; int col[terms.size()]; REAL row[terms.size()]; for (TermList::const_iterator it = terms.begin(); it != terms.end(); ++it, ++i) { col[i] = ((Term)*it).getVariable().getPosition(); row[i] = (( Term )*it).getCoeff(); } if (!set_obj_fnex(lprec, i, row, col)) { // TODO raise an exception } if (lp->getObjective().isMinimize()) { set_minim(lprec); } else { set_maxim(lprec); } return getSolution(lprec); }
int main(int argc, char *argv[]) { lprec *lp = NULL; char *filen, *wlp = NULL, *wmps = NULL, *wfmps = NULL, plp = FALSE; int i; int verbose = IMPORTANT /* CRITICAL */; int debug = -1; MYBOOL report = FALSE; MYBOOL nonames = FALSE, norownames = FALSE, nocolnames = FALSE; MYBOOL write_model_after = FALSE; MYBOOL noint = FALSE; int print_sol = -1; MYBOOL print_stats = FALSE; int floor_first = -1; MYBOOL do_set_bb_depthlimit = FALSE; int bb_depthlimit = 0; MYBOOL do_set_solutionlimit = FALSE; int solutionlimit = 0; MYBOOL break_at_first = FALSE; int scaling = 0; double scaleloop = 0; MYBOOL tracing = FALSE; short filetype = filetypeLP; int anti_degen1 = -1; int anti_degen2 = -1; short print_timing = FALSE; short parse_only = FALSE; int do_presolve = -1; short objective = 0; short PRINT_SOLUTION = 2; int improve = -1; int pivoting1 = -1; int pivoting2 = -1; int bb_rule1 = -1; int bb_rule2 = -1; int max_num_inv = -1; int scalemode1 = -1; int scalemode2 = -1; int crashmode = -1; char *guessbasis = NULL; /* short timeoutok = FALSE; */ long sectimeout = -1; int result; MYBOOL preferdual = AUTOMATIC; int simplextype = -1; MYBOOL do_set_obj_bound = FALSE; REAL obj_bound = 0; REAL mip_absgap = -1; REAL mip_relgap = -1; REAL epsperturb = -1; REAL epsint = -1; REAL epspivot = -1; REAL epsd = -1; REAL epsb = -1; REAL epsel = -1; MYBOOL do_set_break_at_value = FALSE; REAL break_at_value = 0; REAL accuracy_error0, accuracy_error = -1; FILE *fpin = stdin; char *bfp = NULL; char *rxliname = NULL, *rxli = NULL, *rxlidata = NULL, *rxlioptions = NULL, *wxliname = NULL, *wxlisol = NULL, *wxli = NULL, *wxlioptions = NULL, *wxlisoloptions = NULL; char *rbasname = NULL, *wbasname = NULL; char *debugdump_before = NULL; char *debugdump_after = NULL; char *rparname = NULL; char *rparoptions = NULL; char *wparname = NULL; char *wparoptions = NULL; char obj_in_basis = -1; char mps_ibm = FALSE; char mps_negobjconst = FALSE; char mps_free = FALSE; MYBOOL ok; # define SCALINGTHRESHOLD 0.03 /* read command line arguments */ # if defined FORTIFY Fortify_EnterScope(); # endif for(i = 1; i < argc; i++) { ok = FALSE; if(strncmp(argv[i], "-v", 2) == 0) { if (argv[i][2]) verbose = atoi(argv[i] + 2); else verbose = NORMAL; } else if(strcmp(argv[i], "-d") == 0) debug = TRUE; else if(strcmp(argv[i], "-R") == 0) report = TRUE; else if(strcmp(argv[i], "-i") == 0) print_sol = TRUE; else if(strcmp(argv[i], "-ia") == 0) print_sol = AUTOMATIC; else if(strcmp(argv[i], "-stat") == 0) print_stats = TRUE; else if(strcmp(argv[i], "-nonames") == 0) nonames = TRUE; else if(strcmp(argv[i], "-norownames") == 0) norownames = TRUE; else if(strcmp(argv[i], "-nocolnames") == 0) nocolnames = TRUE; else if((strcmp(argv[i], "-c") == 0) || (strcmp(argv[i], "-cc") == 0)) floor_first = BRANCH_CEILING; else if(strcmp(argv[i], "-cf") == 0) floor_first = BRANCH_FLOOR; else if(strcmp(argv[i], "-ca") == 0) floor_first = BRANCH_AUTOMATIC; else if((strcmp(argv[i], "-depth") == 0) && (i + 1 < argc)) { do_set_bb_depthlimit = TRUE; bb_depthlimit = atoi(argv[++i]); } else if(strcmp(argv[i], "-Bw") == 0) or_value(&bb_rule2, NODE_WEIGHTREVERSEMODE); else if(strcmp(argv[i], "-Bb") == 0) or_value(&bb_rule2, NODE_BRANCHREVERSEMODE); else if(strcmp(argv[i], "-Bg") == 0) or_value(&bb_rule2, NODE_GREEDYMODE); else if(strcmp(argv[i], "-Bp") == 0) or_value(&bb_rule2, NODE_PSEUDOCOSTMODE); else if(strcmp(argv[i], "-BR") == 0) or_value(&bb_rule2, NODE_PSEUDORATIOSELECT); else if(strcmp(argv[i], "-Bf") == 0) or_value(&bb_rule2, NODE_DEPTHFIRSTMODE); else if(strcmp(argv[i], "-Br") == 0) or_value(&bb_rule2, NODE_RANDOMIZEMODE); else if(strcmp(argv[i], "-BG") == 0) or_value(&bb_rule2, 0 /* NODE_GUBMODE */); /* doesn't work yet */ else if(strcmp(argv[i], "-Bd") == 0) or_value(&bb_rule2, NODE_DYNAMICMODE); else if(strcmp(argv[i], "-Bs") == 0) or_value(&bb_rule2, NODE_RESTARTMODE); else if(strcmp(argv[i], "-BB") == 0) or_value(&bb_rule2, NODE_BREADTHFIRSTMODE); else if(strcmp(argv[i], "-Bo") == 0) or_value(&bb_rule2, NODE_AUTOORDER); else if(strcmp(argv[i], "-Bc") == 0) or_value(&bb_rule2, NODE_RCOSTFIXING); else if(strcmp(argv[i], "-Bi") == 0) or_value(&bb_rule2, NODE_STRONGINIT); else if(strncmp(argv[i], "-B", 2) == 0) { if (argv[i][2]) set_value(&bb_rule1, atoi(argv[i] + 2)); else set_value(&bb_rule1, NODE_FIRSTSELECT); } else if((strcmp(argv[i], "-n") == 0) && (i + 1 < argc)) { do_set_solutionlimit = TRUE; solutionlimit = atoi(argv[++i]); } else if((strcmp(argv[i], "-b") == 0) && (i + 1 < argc)) { obj_bound = atof(argv[++i]); do_set_obj_bound = TRUE; } else if(((strcmp(argv[i], "-g") == 0) || (strcmp(argv[i], "-ga") == 0)) && (i + 1 < argc)) mip_absgap = atof(argv[++i]); else if((strcmp(argv[i], "-gr") == 0) && (i + 1 < argc)) mip_relgap = atof(argv[++i]); else if((strcmp(argv[i], "-e") == 0) && (i + 1 < argc)) { epsint = atof(argv[++i]); if((epsint <= 0.0) || (epsint >= 0.5)) { fprintf(stderr, "Invalid tolerance %g; 0 < epsilon < 0.5\n", (double)epsint); EndOfPgr(FORCED_EXIT); } } else if((strcmp(argv[i], "-r") == 0) && (i + 1 < argc)) max_num_inv = atoi(argv[++i]); else if((strcmp(argv[i], "-o") == 0) && (i + 1 < argc)) { break_at_value = atof(argv[++i]); do_set_break_at_value = TRUE; } else if(strcmp(argv[i], "-f") == 0) break_at_first = TRUE; else if(strcmp(argv[i], "-timeoutok") == 0) /* timeoutok = TRUE */; /* option no longer needed, but still accepted */ else if(strcmp(argv[i], "-h") == 0) { print_help(argv); EndOfPgr(EXIT_SUCCESS); } else if(strcmp(argv[i], "-prim") == 0) preferdual = FALSE; else if(strcmp(argv[i], "-dual") == 0) preferdual = TRUE; else if(strcmp(argv[i], "-simplexpp") == 0) simplextype = SIMPLEX_PRIMAL_PRIMAL; else if(strcmp(argv[i], "-simplexdp") == 0) simplextype = SIMPLEX_DUAL_PRIMAL; else if(strcmp(argv[i], "-simplexpd") == 0) simplextype = SIMPLEX_PRIMAL_DUAL; else if(strcmp(argv[i], "-simplexdd") == 0) simplextype = SIMPLEX_DUAL_DUAL; else if(strcmp(argv[i], "-sp") == 0) or_value(&scalemode2, SCALE_POWER2); else if(strcmp(argv[i], "-si") == 0) or_value(&scalemode2, SCALE_INTEGERS); else if(strcmp(argv[i], "-se") == 0) or_value(&scalemode2, SCALE_EQUILIBRATE); else if(strcmp(argv[i], "-sq") == 0) or_value(&scalemode2, SCALE_QUADRATIC); else if(strcmp(argv[i], "-sl") == 0) or_value(&scalemode2, SCALE_LOGARITHMIC); else if(strcmp(argv[i], "-sd") == 0) or_value(&scalemode2, SCALE_DYNUPDATE); else if(strcmp(argv[i], "-sr") == 0) or_value(&scalemode2, SCALE_ROWSONLY); else if(strcmp(argv[i], "-sc") == 0) or_value(&scalemode2, SCALE_COLSONLY); else if(strncmp(argv[i], "-s", 2) == 0) { set_value(&scalemode1, SCALE_NONE); scaling = SCALE_MEAN; if (argv[i][2]) { switch (atoi(argv[i] + 2)) { case 0: scaling = SCALE_NONE; break; case 1: set_value(&scalemode1, SCALE_GEOMETRIC); break; case 2: set_value(&scalemode1, SCALE_CURTISREID); break; case 3: set_value(&scalemode1, SCALE_EXTREME); break; case 4: set_value(&scalemode1, SCALE_MEAN); break; case 5: set_value(&scalemode1, SCALE_MEAN | SCALE_LOGARITHMIC); break; case 6: set_value(&scalemode1, SCALE_RANGE); break; case 7: set_value(&scalemode1, SCALE_MEAN | SCALE_QUADRATIC); break; } } else set_value(&scalemode1, SCALE_MEAN); if((i + 1 < argc) && (isNum(argv[i + 1]))) scaleloop = atoi(argv[++i]); } else if(strncmp(argv[i], "-C", 2) == 0) crashmode = atoi(argv[i] + 2); else if((strcmp(argv[i],"-gbas") == 0) && (i + 1 < argc)) guessbasis = argv[++i]; else if(strcmp(argv[i], "-t") == 0) tracing = TRUE; else if(strncmp(argv[i], "-S", 2) == 0) { if (argv[i][2]) PRINT_SOLUTION = (short) atoi(argv[i] + 2); else PRINT_SOLUTION = 2; } else if(strncmp(argv[i], "-improve", 8) == 0) { if (argv[i][8]) or_value(&improve, atoi(argv[i] + 8)); } else if(strcmp(argv[i], "-pivll") == 0) or_value(&pivoting2, PRICE_LOOPLEFT); else if(strcmp(argv[i], "-pivla") == 0) or_value(&pivoting2, PRICE_LOOPALTERNATE); #if defined EnablePartialOptimization else if(strcmp(argv[i], "-pivpc") == 0) or_value(&pivoting2, PRICE_AUTOPARTIALCOLS); else if(strcmp(argv[i], "-pivpr") == 0) or_value(&pivoting2, PRICE_AUTOPARTIALROWS); else if(strcmp(argv[i], "-pivp") == 0) or_value(&pivoting2, PRICE_AUTOPARTIAL); #endif else if(strcmp(argv[i], "-pivf") == 0) or_value(&pivoting2, PRICE_PRIMALFALLBACK); else if(strcmp(argv[i], "-pivm") == 0) or_value(&pivoting2, PRICE_MULTIPLE); else if(strcmp(argv[i], "-piva") == 0) or_value(&pivoting2, PRICE_ADAPTIVE); else if(strcmp(argv[i], "-pivr") == 0) or_value(&pivoting2, PRICE_RANDOMIZE); else if(strcmp(argv[i], "-pivh") == 0) or_value(&pivoting2, PRICE_HARRISTWOPASS); else if(strcmp(argv[i], "-pivt") == 0) or_value(&pivoting2, PRICE_TRUENORMINIT); else if(strncmp(argv[i], "-piv", 4) == 0) { if (argv[i][4]) set_value(&pivoting1, atoi(argv[i] + 4)); else set_value(&pivoting1, PRICER_DEVEX | PRICE_ADAPTIVE); } #if defined PARSER_LP else if(strcmp(argv[i],"-lp") == 0) filetype = filetypeLP; #endif else if((strcmp(argv[i],"-wlp") == 0) && (i + 1 < argc)) wlp = argv[++i]; else if(strcmp(argv[i],"-plp") == 0) plp = TRUE; else if(strcmp(argv[i],"-mps") == 0) filetype = filetypeMPS; else if(strcmp(argv[i],"-mps_ibm") == 0) mps_ibm = TRUE; else if(strcmp(argv[i],"-mps_negobjconst") == 0) mps_negobjconst = TRUE; else if(strcmp(argv[i],"-mps_free") == 0) mps_free = TRUE; else if(strcmp(argv[i],"-fmps") == 0) filetype = filetypeFREEMPS; else if((strcmp(argv[i],"-wmps") == 0) && (i + 1 < argc)) wmps = argv[++i]; else if((strcmp(argv[i],"-wfmps") == 0) && (i + 1 < argc)) wfmps = argv[++i]; else if(strcmp(argv[i],"-wafter") == 0) write_model_after = TRUE; else if(strcmp(argv[i],"-degen") == 0) set_value(&anti_degen1, ANTIDEGEN_DEFAULT); else if(strcmp(argv[i],"-degenf") == 0) or_value(&anti_degen2, ANTIDEGEN_FIXEDVARS); else if(strcmp(argv[i],"-degenc") == 0) or_value(&anti_degen2, ANTIDEGEN_COLUMNCHECK); else if(strcmp(argv[i],"-degens") == 0) or_value(&anti_degen2, ANTIDEGEN_STALLING); else if(strcmp(argv[i],"-degenn") == 0) or_value(&anti_degen2, ANTIDEGEN_NUMFAILURE); else if(strcmp(argv[i],"-degenl") == 0) or_value(&anti_degen2, ANTIDEGEN_LOSTFEAS); else if(strcmp(argv[i],"-degeni") == 0) or_value(&anti_degen2, ANTIDEGEN_INFEASIBLE); else if(strcmp(argv[i],"-degend") == 0) or_value(&anti_degen2, ANTIDEGEN_DYNAMIC); else if(strcmp(argv[i],"-degenb") == 0) or_value(&anti_degen2, ANTIDEGEN_DURINGBB); else if(strcmp(argv[i],"-degenr") == 0) or_value(&anti_degen2, ANTIDEGEN_RHSPERTURB); else if(strcmp(argv[i],"-degenp") == 0) or_value(&anti_degen2, ANTIDEGEN_BOUNDFLIP); else if(strcmp(argv[i],"-time") == 0) { if(clock() == -1) fprintf(stderr, "CPU times not available on this machine\n"); else print_timing = TRUE; } else if((strcmp(argv[i],"-bfp") == 0) && (i + 1 < argc)) bfp = argv[++i]; else if((strcmp(argv[i],"-rxli") == 0) && (i + 2 < argc)) { rxliname = argv[++i]; rxli = argv[++i]; fpin = NULL; filetype = filetypeXLI; } else if((strcmp(argv[i],"-rxlidata") == 0) && (i + 1 < argc)) rxlidata = argv[++i]; else if((strcmp(argv[i],"-rxliopt") == 0) && (i + 1 < argc)) rxlioptions = argv[++i]; else if((strcmp(argv[i],"-wxli") == 0) && (i + 2 < argc)) { wxliname = argv[++i]; wxli = argv[++i]; } else if((strcmp(argv[i],"-wxliopt") == 0) && (i + 1 < argc)) wxlioptions = argv[++i]; else if((strcmp(argv[i],"-wxlisol") == 0) && (i + 2 < argc)) { wxliname = argv[++i]; wxlisol = argv[++i]; } else if((strcmp(argv[i],"-wxlisolopt") == 0) && (i + 1 < argc)) wxlisoloptions = argv[++i]; else if((strcmp(argv[i],"-rbas") == 0) && (i + 1 < argc)) rbasname = argv[++i]; else if((strcmp(argv[i],"-wbas") == 0) && (i + 1 < argc)) wbasname = argv[++i]; else if((strcmp(argv[i],"-Db") == 0) && (i + 1 < argc)) debugdump_before = argv[++i]; else if((strcmp(argv[i],"-Da") == 0) && (i + 1 < argc)) debugdump_after = argv[++i]; else if((strcmp(argv[i],"-timeout") == 0) && (i + 1 < argc)) sectimeout = atol(argv[++i]); else if((strcmp(argv[i],"-trej") == 0) && (i + 1 < argc)) epspivot = atof(argv[++i]); else if((strcmp(argv[i],"-epsp") == 0) && (i + 1 < argc)) epsperturb = atof(argv[++i]); else if((strcmp(argv[i],"-epsd") == 0) && (i + 1 < argc)) epsd = atof(argv[++i]); else if((strcmp(argv[i],"-epsb") == 0) && (i + 1 < argc)) epsb = atof(argv[++i]); else if((strcmp(argv[i],"-epsel") == 0) && (i + 1 < argc)) epsel = atof(argv[++i]); else if(strcmp(argv[i],"-parse_only") == 0) parse_only = TRUE; else ok = TRUE; if(!ok) ; else if(strcmp(argv[i],"-presolverow") == 0) or_value(&do_presolve, PRESOLVE_ROWS); else if(strcmp(argv[i],"-presolvecol") == 0) or_value(&do_presolve, PRESOLVE_COLS); else if(strcmp(argv[i],"-presolve") == 0) or_value(&do_presolve, PRESOLVE_ROWS | PRESOLVE_COLS); else if(strcmp(argv[i],"-presolvel") == 0) or_value(&do_presolve, PRESOLVE_LINDEP); else if(strcmp(argv[i],"-presolves") == 0) or_value(&do_presolve, PRESOLVE_SOS); else if(strcmp(argv[i],"-presolver") == 0) or_value(&do_presolve, PRESOLVE_REDUCEMIP); else if(strcmp(argv[i],"-presolvek") == 0) or_value(&do_presolve, PRESOLVE_KNAPSACK); else if(strcmp(argv[i],"-presolveq") == 0) or_value(&do_presolve, PRESOLVE_ELIMEQ2); else if(strcmp(argv[i],"-presolvem") == 0) or_value(&do_presolve, PRESOLVE_MERGEROWS); else if(strcmp(argv[i],"-presolvefd") == 0) or_value(&do_presolve, PRESOLVE_COLFIXDUAL); else if(strcmp(argv[i],"-presolvebnd") == 0) or_value(&do_presolve, PRESOLVE_BOUNDS); else if(strcmp(argv[i],"-presolved") == 0) or_value(&do_presolve, PRESOLVE_DUALS); else if(strcmp(argv[i],"-presolvef") == 0) or_value(&do_presolve, PRESOLVE_IMPLIEDFREE); else if(strcmp(argv[i],"-presolveslk") == 0) or_value(&do_presolve, PRESOLVE_IMPLIEDSLK); else if(strcmp(argv[i],"-presolveg") == 0) or_value(&do_presolve, PRESOLVE_REDUCEGCD); else if(strcmp(argv[i],"-presolveb") == 0) or_value(&do_presolve, PRESOLVE_PROBEFIX); else if(strcmp(argv[i],"-presolvec") == 0) or_value(&do_presolve, PRESOLVE_PROBEREDUCE); else if(strcmp(argv[i],"-presolverowd") == 0) or_value(&do_presolve, PRESOLVE_ROWDOMINATE); else if(strcmp(argv[i],"-presolvecold") == 0) or_value(&do_presolve, PRESOLVE_COLDOMINATE); else if(strcmp(argv[i],"-min") == 0) objective = -1; else if(strcmp(argv[i],"-max") == 0) objective = 1; else if(strcmp(argv[i],"-noint") == 0) noint = TRUE; else if((strcmp(argv[i],"-rpar") == 0) && (i + 1 < argc)) i++; else if((strcmp(argv[i],"-rparopt") == 0) && (i + 1 < argc)) i++; else if((strcmp(argv[i],"-wpar") == 0) && (i + 1 < argc)) i++; else if((strcmp(argv[i],"-wparopt") == 0) && (i + 1 < argc)) i++; else if(strcmp(argv[i],"-o0") == 0) obj_in_basis = FALSE; else if(strcmp(argv[i],"-o1") == 0) obj_in_basis = TRUE; else if((strcmp(argv[i], "-ac") == 0) && (i + 1 < argc)) accuracy_error = atof(argv[++i]); else if(fpin == stdin) { filen = argv[i]; if(*filen == '<') filen++; if((fpin = fopen(filen, "r")) == NULL) { print_help(argv); fprintf(stderr,"\nError, Unable to open input file '%s'\n", argv[i]); EndOfPgr(FORCED_EXIT); } } else { filen = argv[i]; if(*filen != '>') { print_help(argv); fprintf(stderr, "\nError, Unrecognized command line argument '%s'\n", argv[i]); EndOfPgr(FORCED_EXIT); } } } signal(SIGABRT,/* (void (*) OF((int))) */ SIGABRT_func); if ((filetype != filetypeXLI) && (fpin == NULL)) { lp = NULL; fprintf(stderr, "Cannot combine -rxli option with -lp, -mps, -fmps.\n"); } else { switch(filetype) { #if defined PARSER_LP case filetypeLP: lp = read_lp(fpin, verbose, NULL); break; #endif case filetypeMPS: lp = read_mps(fpin, verbose | (mps_free ? MPS_FREE : 0) | (mps_ibm ? MPS_IBM : 0) | (mps_negobjconst ? MPS_NEGOBJCONST : 0)); break; case filetypeFREEMPS: lp = read_freemps(fpin, verbose | (mps_ibm ? MPS_IBM : 0) | (mps_negobjconst ? MPS_NEGOBJCONST : 0)); break; case filetypeXLI: lp = read_XLI(rxliname, rxli, rxlidata, rxlioptions, verbose); break; } } if((fpin != NULL) && (fpin != stdin)) fclose(fpin); if(print_timing) print_cpu_times("Parsing input"); if(lp == NULL) { fprintf(stderr, "Unable to read model.\n"); EndOfPgr(FORCED_EXIT); } for(i = 1; i < argc; i++) { if((strcmp(argv[i],"-rpar") == 0) && (i + 1 < argc)) { if(rparname != NULL) { if(!read_params(lp, rparname, rparoptions)) { fprintf(stderr, "Unable to read parameter file (%s)\n", rparname); delete_lp(lp); EndOfPgr(FORCED_EXIT); } } rparname = argv[++i]; } else if((strcmp(argv[i],"-rparopt") == 0) && (i + 1 < argc)) rparoptions = argv[++i]; else if((strcmp(argv[i],"-wpar") == 0) && (i + 1 < argc)) wparname = argv[++i]; else if((strcmp(argv[i],"-wparopt") == 0) && (i + 1 < argc)) wparoptions = argv[++i]; } if(rparname != NULL) if(!read_params(lp, rparname, rparoptions)) { fprintf(stderr, "Unable to read parameter file (%s)\n", rparname); delete_lp(lp); EndOfPgr(FORCED_EXIT); } if((nonames) || (nocolnames)) set_use_names(lp, FALSE, FALSE); if((nonames) || (norownames)) set_use_names(lp, TRUE, FALSE); if(objective != 0) { if(objective == 1) set_maxim(lp); else set_minim(lp); } if (obj_in_basis != -1) set_obj_in_basis(lp, obj_in_basis); if(noint) { /* remove integer conditions */ for(i = get_Ncolumns(lp); i >= 1; i--) { if(is_SOS_var(lp, i)) { fprintf(stderr, "Unable to remove integer conditions because there is at least one SOS constraint\n"); delete_lp(lp); EndOfPgr(FORCED_EXIT); } set_semicont(lp, i, FALSE); set_int(lp, i, FALSE); } } if(!write_model_after) write_model(lp, plp, wlp, wmps, wfmps, wxli, NULL, wxliname, wxlioptions); if(print_stats) print_statistics(lp); if(parse_only) { if(!write_model_after) { delete_lp(lp); EndOfPgr(0); } /* else if(!sectimeout) */ sectimeout = 1; } if(PRINT_SOLUTION >= 5) print_lp(lp); #if 0 put_abortfunc(lp,(abortfunc *) myabortfunc, NULL); #endif if(sectimeout > 0) set_timeout(lp, sectimeout); if(print_sol >= 0) set_print_sol(lp, print_sol); if(epsint >= 0) set_epsint(lp, epsint); if(epspivot >= 0) set_epspivot(lp, epspivot); if(epsperturb >= 0) set_epsperturb(lp, epsperturb); if(epsd >= 0) set_epsd(lp, epsd); if(epsb >= 0) set_epsb(lp, epsb); if(epsel >= 0) set_epsel(lp, epsel); if(debug >= 0) set_debug(lp, (MYBOOL) debug); if(floor_first != -1) set_bb_floorfirst(lp, floor_first); if(do_set_bb_depthlimit) set_bb_depthlimit(lp, bb_depthlimit); if(do_set_solutionlimit) set_solutionlimit(lp, solutionlimit); if(tracing) set_trace(lp, tracing); if(do_set_obj_bound) set_obj_bound(lp, obj_bound); if(do_set_break_at_value) set_break_at_value(lp, break_at_value); if(break_at_first) set_break_at_first(lp, break_at_first); if(mip_absgap >= 0) set_mip_gap(lp, TRUE, mip_absgap); if(mip_relgap >= 0) set_mip_gap(lp, FALSE, mip_relgap); if((anti_degen1 != -1) || (anti_degen2 != -1)) { if((anti_degen1 == -1) || (anti_degen2 != -1)) anti_degen1 = 0; if(anti_degen2 == -1) anti_degen2 = 0; set_anti_degen(lp, anti_degen1 | anti_degen2); } set_presolve(lp, ((do_presolve == -1) ? get_presolve(lp): do_presolve) | ((PRINT_SOLUTION >= 4) ? PRESOLVE_SENSDUALS : 0), get_presolveloops(lp)); if(improve != -1) set_improve(lp, improve); if(max_num_inv >= 0) set_maxpivot(lp, max_num_inv); if(preferdual != AUTOMATIC) set_preferdual(lp, preferdual); if((pivoting1 != -1) || (pivoting2 != -1)) { if(pivoting1 == -1) pivoting1 = get_pivoting(lp) & PRICER_LASTOPTION; if(pivoting2 == -1) pivoting2 = 0; set_pivoting(lp, pivoting1 | pivoting2); } if((scalemode1 != -1) || (scalemode2 != -1)) { if(scalemode1 == -1) scalemode1 = get_scaling(lp) & SCALE_CURTISREID; if(scalemode2 == -1) scalemode2 = 0; set_scaling(lp, scalemode1 | scalemode2); } if(crashmode != -1) set_basiscrash(lp, crashmode); if((bb_rule1 != -1) || (bb_rule2 != -1)) { if(bb_rule1 == -1) bb_rule1 = get_bb_rule(lp) & NODE_USERSELECT; if(bb_rule2 == -1) bb_rule2 = 0; set_bb_rule(lp, bb_rule1 | bb_rule2); } if(simplextype != -1) set_simplextype(lp, simplextype); if(bfp != NULL) if(!set_BFP(lp, bfp)) { fprintf(stderr, "Unable to set BFP package.\n"); delete_lp(lp); EndOfPgr(FORCED_EXIT); } if(debugdump_before != NULL) print_debugdump(lp, debugdump_before); if(report) put_msgfunc(lp, LPMessageCB, NULL, MSG_LPFEASIBLE | MSG_LPOPTIMAL | MSG_MILPFEASIBLE | MSG_MILPBETTER | MSG_PERFORMANCE); if(scaling) { if(scaleloop <= 0) scaleloop = 5; if(scaleloop - (int) scaleloop < SCALINGTHRESHOLD) scaleloop = (int) scaleloop + SCALINGTHRESHOLD; set_scalelimit(lp, scaleloop); } if (accuracy_error != -1) set_break_numeric_accuracy(lp, accuracy_error); if(guessbasis != NULL) { REAL *guessvector, a; int *basisvector; int Nrows = get_Nrows(lp); int Ncolumns = get_Ncolumns(lp); int col; char buf[50], *ptr; FILE *fp; if ((fp = fopen(guessbasis, "r")) != NULL) { guessvector = (REAL *) calloc(1+Ncolumns, sizeof(*guessvector)); basisvector = (int *) malloc((1+Nrows+Ncolumns)*sizeof(*basisvector)); if ((guessvector != NULL) && (basisvector != NULL)) { while ((!feof(fp)) && (fgets(buf, sizeof(buf), fp) != NULL)) { ptr = strrchr(buf, ':'); if (ptr == NULL) { printf("Mallformed line: %s\n", buf); } else { a = atof(ptr + 1); while ((ptr > buf) && (isspace(ptr[-1]))) ptr--; *ptr = 0; col = get_nameindex(lp, buf, FALSE); if (col < 1) printf("guess_basis: Unknown variable name %s\n", buf); else guessvector[col] = a; } } if (guess_basis(lp, guessvector, basisvector)) { if (!set_basis(lp, basisvector, TRUE)) printf("Unable to set guessed basis.\n"); } else printf("Unable to guess basis from provided variables.\n"); } else printf("guess_basis: Out of memory.\n"); if (basisvector != NULL) free(basisvector); if (guessvector != NULL) free(guessvector); fclose(fp); } else printf("Unable to open file %s\n", guessbasis); } if(rbasname != NULL) if(!read_basis(lp, rbasname, NULL)) { fprintf(stderr, "Unable to read basis file.\n"); delete_lp(lp); EndOfPgr(FORCED_EXIT); } result = solve(lp); if(wbasname != NULL) if(!write_basis(lp, wbasname)) fprintf(stderr, "Unable to write basis file.\n"); if(write_model_after) write_model(lp, plp, wlp, wmps, wfmps, wxli, NULL, wxliname, wxlioptions); write_model(lp, FALSE, NULL, NULL, NULL, NULL, wxlisol, wxliname, wxlisoloptions); if(PRINT_SOLUTION >= 6) print_scales(lp); if((print_timing) && (!parse_only)) print_cpu_times("solving"); if(debugdump_after != NULL) print_debugdump(lp, debugdump_after); if(wparname != NULL) if(!write_params(lp, wparname, wparoptions)) { fprintf(stderr, "Unable to write parameter file (%s)\n", wparname); delete_lp(lp); EndOfPgr(FORCED_EXIT); } if(parse_only) { delete_lp(lp); EndOfPgr(0); } /* if((timeoutok) && (result == TIMEOUT) && (get_solutioncount(lp) > 0)) result = OPTIMAL; */ switch(result) { case SUBOPTIMAL: case PRESOLVED: case OPTIMAL: case PROCBREAK: case FEASFOUND: if ((result == SUBOPTIMAL) && (PRINT_SOLUTION >= 1)) printf("Suboptimal solution\n"); if (result == PRESOLVED) printf("Presolved solution\n"); if (PRINT_SOLUTION >= 1) print_objective(lp); if (PRINT_SOLUTION >= 2) print_solution(lp, 1); if (PRINT_SOLUTION >= 3) print_constraints(lp, 1); if (PRINT_SOLUTION >= 4) print_duals(lp); if(tracing) fprintf(stderr, "Branch & Bound depth: %d\nNodes processed: %.0f\nSimplex pivots: %.0f\nNumber of equal solutions: %d\n", get_max_level(lp), (REAL) get_total_nodes(lp), (REAL) get_total_iter(lp), get_solutioncount(lp)); break; case NOMEMORY: if (PRINT_SOLUTION >= 1) printf("Out of memory\n"); break; case INFEASIBLE: if (PRINT_SOLUTION >= 1) printf("This problem is infeasible\n"); break; case UNBOUNDED: if (PRINT_SOLUTION >= 1) printf("This problem is unbounded\n"); break; case PROCFAIL: if (PRINT_SOLUTION >= 1) printf("The B&B routine failed\n"); break; case TIMEOUT: if (PRINT_SOLUTION >= 1) printf("Timeout\n"); break; case USERABORT: if (PRINT_SOLUTION >= 1) printf("User aborted\n"); break; case ACCURACYERROR: if (PRINT_SOLUTION >= 1) printf("Accuracy error\n"); break; default: if (PRINT_SOLUTION >= 1) printf("lp_solve failed\n"); break; } if (PRINT_SOLUTION >= 7) print_tableau(lp); delete_lp(lp); EndOfPgr(result); return(result); }
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; } }
void CLPLpsolve::setFunction(CLPFunction* function) { m_status = 0; m_lpFunction = function; const int nVars = function->getNumCoefficients(); // Creates an empty problem with getNumCoefficients variables m_env = make_lp(0, nVars); if(m_env == NULL) { m_status = 1; } //if(!set_add_rowmode(m_env, FALSE)) //{ // m_status = 1; //} //Allowing memory for rows //int * colno = new int[nVars]; REAL * row= new REAL[nVars + 1]; //set variables names for (int i = 0; i < nVars; ++i) { int lpIndex = i + 1; row[lpIndex] = function->getCoefficients().at(i); //colno[i] = lpIndex; //Determines the type switch(function->getIntegers().at(i)) { case 'C' : m_status = set_unbounded(m_env, lpIndex); break; case 'B' : m_status = set_binary(m_env, lpIndex, TRUE); break; case 'I' : m_status = set_int(m_env, lpIndex, TRUE); break; case 'S' : m_status = set_semicont(m_env, lpIndex, TRUE); break; default: assert(false); break; } //Sets upper bound and lower bound set_upbo(m_env, lpIndex, function->getUpperBounds().at(i)); set_lowbo(m_env, lpIndex, function->getLowerBounds().at(i)); set_col_name(m_env, lpIndex, const_cast<char*>(function->getVarNames().at(i).c_str())); } //set_obj_fnex(m_env, nVars, row, colno); set_obj_fn(m_env, row); // Set the type of the problem (Min or Max) switch (function->getType()) { case lpMinFunction: set_minim(m_env); break; case lpMaxFunction: set_maxim(m_env); break; } if(!set_add_rowmode(m_env, TRUE)) { m_status = 1; } delete [] row; }
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 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); }