Esempio n. 1
0
File: windll.c Progetto: ks6g10/CA
/* Delete a column */
long __declspec(dllexport) WINAPI _del_column(lprec *lp, long column)
 {
  long ret;

  if (lp != NULL) {
   freebuferror();
   ret = del_column(lp, column);
  }
  else
   ret = 0;
  return(ret);
 }
Esempio n. 2
0
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);
}
Esempio n. 3
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);
}
Esempio n. 4
0
int main ( int argv, char * argc[] )
{

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

#if defined FORTIFY
  Fortify_EnterScope();
#endif

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

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

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

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

  write_lp(lp, "lp.lp");

  delete_lp(lp);

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

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

  delete_lp(lp);

#if defined FORTIFY
  Fortify_LeaveScope();
#endif

    return 0;
}
Esempio n. 5
0
STATIC int primloop(lprec *lp, MYBOOL feasible)
{
  int     i, j, k, ok = TRUE;
  LREAL  theta = 0.0;
  REAL   *prow = NULL, *drow = NULL, *pcol = NULL, prevobj, epsvalue;
  MYBOOL primal = TRUE, minit;
  MYBOOL pivdynamic, bfpfinal = FALSE;
  int    oldpivrule, oldpivmode, pivrule, Blandswitches,
         colnr, rownr, lastnr, minitcount = 0;
  int    Rcycle = 0, Ccycle = 0, Ncycle = 0, changedphase = FALSE;
  int    *nzdrow = NULL, *workINT = NULL;

 /* Add sufficent number of artificial variables to make the problem feasible
    through the first phase; delete when primal feasibility has been achieved */
  lp->Extrap = 0;
#ifdef EnablePrimalPhase1
  if(!feasible) {
#ifdef Paranoia
    if(!verifyBasis(lp))
      report(lp, SEVERE, "primloop: No valid basis for artificial variables\n");
#endif
#if 0
    /* First check if we can get away with a single artificial variable */
    if(lp->equalities == 0) {
      i = (int) feasibilityOffset(lp, !primal);
      add_artificial(lp, i);
    }
    else
#endif
    /* Otherwise add as many as is necessary to force basic feasibility */
      for(i = 1; i <= lp->rows; i++)
        add_artificial(lp, i);
  }
  if(lp->spx_trace)
    report(lp, DETAILED, "Extrap count = %d\n", lp->Extrap);
#endif

  if(lp->spx_trace)
    report(lp, DETAILED, "Entered primal simplex algorithm with feasibility %s\n",
                         my_boolstr(feasible));

 /* Create work arrays */
#ifdef UseSparseReducedCost
  allocINT(lp, &nzdrow, lp->sum + 1, FALSE);
#endif
  allocREAL(lp, &prow, lp->sum + 1, TRUE);
  allocREAL(lp, &drow, lp->sum + 1, TRUE);
  allocREAL(lp, &pcol, lp->rows + 1, TRUE);

 /* Refactorize the basis and set status variables */
  i = my_if(is_bb_action(lp, ACTION_REBASE), INITSOL_SHIFTZERO, INITSOL_USEZERO);
  if(((lp->spx_status == SWITCH_TO_PRIMAL) && !lp->justInverted) ||
     (lp->Extrap != 0) ||
     is_bb_action(lp, ACTION_REINVERT)) {
    simplexPricer(lp, (MYBOOL)!primal);

    /* Do basis crashing before refactorization, if specified */
    invert(lp, (MYBOOL) i, TRUE);
  }
  else {
    if(is_bb_action(lp, ACTION_RECOMPUTE))
      recompute_solution(lp, (MYBOOL) i);
    restartPricer(lp, (MYBOOL)!primal);
  }
  lp->bb_action = ACTION_NONE;

  lp->spx_status = RUNNING;
  lp->doIterate = FALSE;
  minit = ITERATE_MAJORMAJOR;
  prevobj = lp->rhs[0];
  oldpivmode = lp->piv_strategy;
  oldpivrule = get_piv_rule(lp);
  pivdynamic = ANTICYCLEBLAND && is_piv_mode(lp, PRICE_ADAPTIVE);
  epsvalue = lp->epspivot;
  Blandswitches = 0;
  rownr = 0;
  colnr = 0;
  lastnr = 0;
  lp->rejectpivot[0] = 0;
  if(feasible)
    lp->simplex_mode = SIMPLEX_Phase2_PRIMAL;
  else
    lp->simplex_mode = SIMPLEX_Phase1_PRIMAL;

 /* Iterate while we are successful; exit when the model is infeasible/unbounded,
    or we must terminate due to numeric instability or user-determined reasons */
  while(lp->spx_status == RUNNING) {

    if(lp->spx_trace)
      if(lastnr > 0)
      report(lp, NORMAL, "primloop: Objective at iteration %8d is " RESULTVALUEMASK " (%4d: %4d %s- %4d)\n",
                         get_total_iter(lp), lp->rhs[0], rownr, lastnr,
                         my_if(minit == ITERATE_MAJORMAJOR, "<","|"), colnr);

    pivrule = get_piv_rule(lp);
    if(pivdynamic && ((pivrule != PRICER_FIRSTINDEX) ||
                      (pivrule != oldpivrule))
#if PrimalPivotStickiness==2
       && (lp->fixedvars == 0)
#elif PrimalPivotStickiness==1
       && feasible
#endif
      ) {
      /* Check if we have a stationary solution */
      if((minit == ITERATE_MAJORMAJOR) && !lp->justInverted &&
         (fabs(my_reldiff(lp->rhs[0], prevobj)) < epsvalue)) {
        Ncycle++;
        /* Start to monitor for variable cycling if this is the initial stationarity */
        if(Ncycle <= 1) {
          Ccycle = colnr;
          Rcycle = rownr;
        }
        /* Check if we should change pivoting strategy due to stationary variable cycling */
        else if((pivrule == oldpivrule) && (((MAX_STALLCOUNT > 1) && (Ncycle > MAX_STALLCOUNT)) ||
                                            (Ccycle == rownr) || (Rcycle == colnr))) {
          /* First check if we should give up on Bland's rule and try perturbed bound
             relaxation instead */
#ifdef EnableStallAntiDegen
          if((MAX_BLANDSWITCH >= 0) && (Blandswitches >= MAX_BLANDSWITCH)) {
            lp->spx_status = DEGENERATE;
            break;
          }
#endif
          Blandswitches++;
          lp->piv_strategy = PRICER_FIRSTINDEX;  /* There is no advanced normalization for Bland's rule, restart at end */
          Ccycle = 0;
          Rcycle = 0;
          Ncycle = 0;
          if(lp->spx_trace)
            report(lp, DETAILED, "primloop: Detected cycling at iteration %d; changed to FIRST INDEX rule!\n",
                                 get_total_iter(lp));
        }
      }
#if 0
      /* Handle cycling or stationary situations by switching to the dual simplex */
      else if((pivrule == oldpivrule) && feasible && (lp->simplex_strategy & SIMPLEX_DYNAMIC)) {
        lp->spx_status = SWITCH_TO_DUAL;
        if(lp->total_iter == 0)
          report(lp, NORMAL, "Start dual simplex for finalization at iteration  %8d\n",
                             get_total_iter(lp));
        break;
      }
#endif
      /* Change back to original selection strategy as soon as possible */
      else if((minit == ITERATE_MAJORMAJOR) && (pivrule != oldpivrule)) {
        lp->piv_strategy = oldpivmode;
        restartPricer(lp, AUTOMATIC);    /* Pricer restart following Bland's rule */
        Ccycle = 0;
        Rcycle = 0;
        Ncycle = 0;
        if(lp->spx_trace)
          report(lp, DETAILED, "...returned to original pivot selection rule at iteration %d.\n",
                               get_total_iter(lp));
      }
    }

   /* Store current LP value for reference at next iteration */
    prevobj = lp->rhs[0];

    lp->doIterate = FALSE;
    lp->doInvert = FALSE;

   /* Find best column to enter the basis */
RetryCol:
    if(!changedphase) {
      i = 0;
      do {
        if(partial_countBlocks(lp, (MYBOOL) !primal) > 1)
          partial_blockStep(lp, (MYBOOL) !primal);
        colnr = colprim(lp, (MYBOOL) (minit == ITERATE_MINORRETRY), drow, nzdrow);
        i++;
      } while ((colnr == 0) && (i < partial_countBlocks(lp, (MYBOOL) !primal)));

#ifdef FinalOptimalErrorLimitation
      /* Do additional checking that we have a correct identification of optimality */
      if((colnr == 0) && !lp->justInverted) {
        lp->doInvert = TRUE;
        i = invert(lp, INITSOL_USEZERO, TRUE);
        colnr = colprim(lp, FALSE, drow, nzdrow);
      }
#endif
    }

    if(colnr > 0) {
      changedphase = FALSE;
      fsolve(lp, colnr, pcol, workINT, lp->epsmachine, 1.0, TRUE);   /* Solve entering column for Pi */
#ifdef UseRejectionList
      if(is_anti_degen(lp, ANTIDEGEN_COLUMNCHECK) && !check_degeneracy(lp, pcol, NULL)) {
        if(lp->rejectpivot[0] < DEF_MAXPIVOTRETRY/3) {
          i = ++lp->rejectpivot[0];
          lp->rejectpivot[i] = colnr;
          report(lp, DETAILED, "Entering column %d found to be non-improving due to degeneracy!\n",
                     colnr);
          goto RetryCol;
        }
        else {
          lp->rejectpivot[0] = 0;
          report(lp, DETAILED, "Gave up trying to find a strictly improving entering column!\n");
        }
      }
#endif

      /* Find the leaving variable that gives the most stringent bound on the entering variable */
      theta = drow[colnr];
      rownr = rowprim(lp, colnr, &theta, pcol);
#if 0
      report(lp, NORMAL, "Iteration %d: Enter %d, Leave %d\n", lp->current_iter, colnr, rownr);
#endif

      /* See if we can do a straight artificial<->slack replacement (when "colnr" is a slack) */
      if((lp->Extrap != 0) && (rownr == 0) && (colnr <= lp->rows))
        rownr = findAnti_artificial(lp, colnr);

      if(rownr > 0) {
        lp->rejectpivot[0] = 0;
        lp->bfp_prepareupdate(lp, rownr, colnr, pcol);
      }
      else if(lp->spx_status == UNBOUNDED) {
        report(lp, DETAILED, "primloop: The model is primal unbounded.\n");
        break;
      }
#ifdef UseRejectionList
      else if(lp->rejectpivot[0] < DEF_MAXPIVOTRETRY) {
        lp->spx_status = RUNNING;
        if(lp->justInverted) {
          lp->rejectpivot[0]++;
          lp->rejectpivot[lp->rejectpivot[0]] = colnr;
          report(lp, DETAILED, "...trying to recover via another pivot column!\n");
        }
        else {
          lp->doInvert = TRUE;
          invert(lp, INITSOL_USEZERO, TRUE);
        }
        goto RetryCol;
      }
#endif
      else {

        /* Assume failure if we are still unsuccessful and the model is not unbounded */
        if((rownr == 0) && (lp->spx_status == RUNNING)) {
          report(lp, IMPORTANT, "primloop: Could not find a leaving variable for entering %d (iteration %d)\n",
                                 colnr, get_total_iter(lp));
          lp->spx_status = NUMFAILURE;
        }
      }
    }
#ifdef EnablePrimalPhase1
    else if(!feasible || isPhase1(lp)) {

      if(feasiblePhase1(lp, epsvalue)) {
        lp->spx_status = RUNNING;
        if(lp->bb_totalnodes == 0) {
          report(lp, NORMAL, "Found feasibility by primal simplex at iteration  %8d\n",
                              get_total_iter(lp));
          if((lp->usermessage != NULL) && (lp->msgmask & MSG_LPFEASIBLE))
            lp->usermessage(lp, lp->msghandle, MSG_LPFEASIBLE);
        }
        changedphase = FALSE;
        feasible = TRUE;
        lp->simplex_mode = SIMPLEX_Phase2_PRIMAL;

       /* We can do two things now;
          1) delete the rows belonging to those variables, since they are redundant, OR
          2) drive out the existing artificial variables via pivoting. */
        if(lp->Extrap > 0) {

#ifdef Phase1EliminateRedundant
         /* If it is not a MIP model we can try to delete redundant rows */
          if((lp->bb_totalnodes == 0) && (MIP_count(lp) == 0)) {
            while(lp->Extrap > 0) {
              i = lp->rows;
              while((i > 0) && (lp->var_basic[i] <= lp->sum-lp->Extrap))
                i--;
#ifdef Paranoia
              if(i <= 0) {
                report(lp, SEVERE, "primloop: Could not find redundant artificial.\n");
                break;
              }
#endif
              /* Obtain column and row indeces */
              j = lp->var_basic[i]-lp->rows;
              k = get_artificialRow(lp, j);

              /* Delete row before column due to basis "compensation logic" */
              if(lp->is_basic[k]) {
                lp->is_basic[lp->rows+j] = FALSE;
                del_constraint(lp, k);
              }
              else
                setBasisVar(lp, i, k);
              del_column(lp, j);
              lp->Extrap--;
            }
            lp->basis_valid = TRUE;
          }
         /* Otherwise we drive out the artificials by elimination pivoting */
          else {
            eliminate_artificials(lp, prow);
            lp->doIterate = FALSE;
          }
#else
          lp->Extrap = my_flipsign(lp->Extrap);
#endif
        }
        lp->doInvert = TRUE;
        prevobj = lp->infinite;
      }
      else {
        lp->spx_status = INFEASIBLE;
        minit = ITERATE_MAJORMAJOR;
        if(lp->spx_trace)
          report(lp, NORMAL, "Model infeasible by primal simplex at iteration   %8d\n",
                             get_total_iter(lp));
      }
    }
#endif

    /* Pivot row/col and update the inverse */
    if(lp->doIterate) {
      lastnr = lp->var_basic[rownr];

      if(lp->justInverted)
        minitcount = 0;
      else if(minitcount > MAX_MINITUPDATES) {
        recompute_solution(lp, INITSOL_USEZERO);
        minitcount = 0;
      }
      minit = performiteration(lp, rownr, colnr, theta, primal, NULL, NULL,
                                                                pcol, NULL);
      if(minit != ITERATE_MAJORMAJOR)
        minitcount++;

      if((lp->spx_status == USERABORT) || (lp->spx_status == TIMEOUT))
        break;
      else if(minit == ITERATE_MINORMAJOR)
        continue;
#ifdef UsePrimalReducedCostUpdate
      /* Do a fast update of the reduced costs in preparation for the next iteration */
      if(minit == ITERATE_MAJORMAJOR)
        update_reducedcosts(lp, primal, lastnr, colnr, pcol, drow);
#endif

#ifdef EnablePrimalPhase1
      /* Detect if an auxiliary variable has left the basis and delete it; if
         the non-basic variable only changed bound (a "minor iteration"), the
         basic artificial variable did not leave and there is nothing to do */
      if((minit == ITERATE_MAJORMAJOR) && (lastnr > lp->sum - abs(lp->Extrap))) {
#ifdef Paranoia
        if(lp->is_basic[lastnr] || !lp->is_basic[colnr])
          report(lp, SEVERE, "primloop: Invalid basis indicator for variable %d at iteration %d\n",
                              lastnr, get_total_iter(lp));
#endif
        del_column(lp, lastnr-lp->rows);
        if(lp->Extrap > 0)
          lp->Extrap--;
        else
          lp->Extrap++;
        if(lp->Extrap == 0) {
          colnr = 0;
          prevobj = lp->infinite;
          changedphase = TRUE;
        }
      }

#endif
    }

    if(lp->spx_status == SWITCH_TO_DUAL)
      ;
    else if(!changedphase && lp->bfp_mustrefactorize(lp)) {
      i = invert(lp, INITSOL_USEZERO, FALSE);
#ifdef ResetMinitOnReinvert
      minit = ITERATE_MAJORMAJOR;
#endif

      if((lp->spx_status == USERABORT) || (lp->spx_status == TIMEOUT))
        break;
      else if(!i) {
        lp->spx_status = SINGULAR_BASIS;
        break;
      }
      /* Check whether we are still feasible or not... */
      if(!isPrimalFeasible(lp, lp->epspivot)) {
        lp->spx_status = LOSTFEAS;
      }
    }
    userabort(lp, -1);

  }
  if (lp->piv_strategy != oldpivmode)
    lp->piv_strategy = oldpivmode;

#ifdef EnablePrimalPhase1

  /* Remove any remaining artificial variables (feasible or infeasible model) */
  lp->Extrap = abs(lp->Extrap);
  if(lp->Extrap > 0) {
    clear_artificials(lp);
    if(lp->spx_status != OPTIMAL)
      restore_basis(lp);
    i = invert(lp, INITSOL_USEZERO, TRUE);
  }
#ifdef Paranoia
  if(!verifyBasis(lp))
    report(lp, SEVERE, "primloop: Invalid basis detected due to internal error\n");
#endif

  /* Switch to dual phase 1 simplex for MIP models during B&B phases */
  if((lp->bb_totalnodes == 0) && (MIP_count(lp) > 0) &&
     ((lp->simplex_strategy & SIMPLEX_Phase1_DUAL) == 0)) {
    lp->simplex_strategy &= !SIMPLEX_Phase1_PRIMAL;
    lp->simplex_strategy += SIMPLEX_Phase1_DUAL;
  }

#endif

  FREE(nzdrow);
  FREE(drow);
  FREE(prow);
  FREE(pcol);

  return(ok);
} /* primloop */