Пример #1
0
int main(int argc, char *argv[])
{     LPX *lp;
      MPL *mpl = NULL;
      int ret;
      double start;
      /* parse command line parameters */
      parse_cmdline(argc, argv);
      /* remove all output files specified in the command line */
      if (display != NULL) remove(display);
      if (out_sol != NULL) remove(out_sol);
      if (out_bnds != NULL) remove(out_bnds);
      if (out_mps != NULL) remove(out_mps);
      if (out_lpt != NULL) remove(out_lpt);
      if (out_txt != NULL) remove(out_txt);
      if (out_glp != NULL) remove(out_glp);
      /* read problem from the input file */
      if (in_file == NULL)
      {  print("No input file specified; try %s --help", argv[0]);
         exit(EXIT_FAILURE);
      }
      switch (format)
      {  case 0:
            lp = lpx_read_mps(in_file);
            if (lp == NULL)
            {  print("MPS file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         case 1:
            lp = lpx_read_lpt(in_file);
            if (lp == NULL)
            {  print("CPLEX LP file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         case 2:
#if 0 /* 01/VIII-2004 */
            lp = lpx_read_model(in_file, in_data, display);
            if (lp == NULL)
            {  print("Model processing error");
               exit(EXIT_FAILURE);
            }
#else
            /* initialize the translator database */
            mpl = mpl_initialize();
            /* read model section and optional data section */
            ret = mpl_read_model(mpl, in_file, in_data != NULL);
            if (ret == 4)
err:        {  print("Model processing error");
               exit(EXIT_FAILURE);
            }
            insist(ret == 1 || ret == 2);
            /* read data section, if necessary */
            if (in_data != NULL)
            {  insist(ret == 1);
               ret = mpl_read_data(mpl, in_data);
               if (ret == 4) goto err;
               insist(ret == 2);
            }
            /* generate model */
            ret = mpl_generate(mpl, display);
            if (ret == 4) goto err;
            /* extract problem instance */
            lp = lpx_extract_prob(mpl);
            insist(lp != NULL);
#endif
            if (lpx_get_num_rows(lp) == 0)
            {  print("Problem has no rows");
               exit(EXIT_FAILURE);
            }
            if (lpx_get_num_cols(lp) == 0)
            {  print("Problem has no columns");
               exit(EXIT_FAILURE);
            }
            break;
         case 3:
            lp = lpx_read_prob(in_file);
            if (lp == NULL)
            {  print("GNU LP file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         default:
            insist(format != format);
      }
      /* change problem name (if required) */
      if (newname != NULL) lpx_set_prob_name(lp, newname);
      /* change optimization direction (if required) */
      if (dir != 0) lpx_set_obj_dir(lp, dir);
      /* write problem in MPS format (if required) */
      if (out_mps != NULL)
      {  lpx_set_int_parm(lp, LPX_K_MPSORIG, orig);
         ret = lpx_write_mps(lp, out_mps);
         if (ret != 0)
         {  print("Unable to write problem in MPS format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in CPLEX LP format (if required) */
      if (out_lpt != NULL)
      {  lpx_set_int_parm(lp, LPX_K_LPTORIG, orig);
         ret = lpx_write_lpt(lp, out_lpt);
         if (ret != 0)
         {  print("Unable to write problem in CPLEX LP format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in plain text format (if required) */
      if (out_txt != NULL)
      {  lpx_set_int_parm(lp, LPX_K_LPTORIG, orig);
         ret = lpx_print_prob(lp, out_txt);
         if (ret != 0)
         {  print("Unable to write problem in plain text format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in GNU LP format (if required) */
      if (out_glp != NULL)
      {  ret = lpx_write_prob(lp, out_glp);
         if (ret != 0)
         {  print("Unable to write problem in GNU LP format");
            exit(EXIT_FAILURE);
         }
      }
      /* if only data check is required, skip computations */
      if (check) goto skip;
      /* scale the problem data (if required) */
      if (scale && (!presol || method == 1)) lpx_scale_prob(lp);
      /* build advanced initial basis (if required) */
      if (method == 0 && basis && !presol) lpx_adv_basis(lp);
      /* set some control parameters, which might be changed in the
         command line */
      lpx_set_int_parm(lp, LPX_K_PRICE, price);
      if (!relax) lpx_set_real_parm(lp, LPX_K_RELAX, 0.0);
      lpx_set_int_parm(lp, LPX_K_PRESOL, presol);
      lpx_set_int_parm(lp, LPX_K_BRANCH, branch);
      lpx_set_int_parm(lp, LPX_K_BTRACK, btrack);
      lpx_set_real_parm(lp, LPX_K_TMLIM, (double)tmlim);
      /* solve the problem */
      start = utime();
      switch (method)
      {  case 0:
            if (nomip || lpx_get_class(lp) == LPX_LP)
            {  ret = lpx_simplex(lp);
               if (presol && ret != LPX_E_OK && out_sol != NULL)
                  print("If you need actual output for non-optimal solu"
                     "tion, use --nopresol");
            }
            else
            {  method = 2;
               lpx_simplex(lp);
               if (!intopt)
                  lpx_integer(lp);
               else
                  lpx_intopt(lp);
            }
            break;
         case 1:
            if (nomip || lpx_get_class(lp) == LPX_LP)
               lpx_interior(lp);
            else
            {  print("Interior point method is not able to solve MIP pr"
                  "oblem; use --simplex");
               exit(EXIT_FAILURE);
            }
            break;
         default:
            insist(method != method);
      }
      /* display statistics */
      print("Time used:   %.1f secs", utime() - start);
      print("Memory used: %.1fM (%d bytes)",
         (double)lib_env_ptr()->mem_tpeak / (double)(1024 * 1024),
         lib_env_ptr()->mem_tpeak);
#if 1 /* 01/VIII-2004 */
      if (mpl != NULL && mpl_has_solve_stmt(mpl))
      {  int n, j, round;
         /* store the solution to the translator database */
         n = lpx_get_num_cols(lp);
         round = lpx_get_int_parm(lp, LPX_K_ROUND);
         lpx_set_int_parm(lp, LPX_K_ROUND, 1);
         switch (method)
         {  case 0:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_get_col_prim(lp, j));
               break;
            case 1:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_ipt_col_prim(lp, j));
               break;
            case 2:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_mip_col_val(lp, j));
               break;
            default:
               insist(method != method);
         }
         lpx_set_int_parm(lp, LPX_K_ROUND, round);
         /* perform postsolving */
         ret = mpl_postsolve(mpl, display);
         if (ret == 4)
         {  print("Model postsolving error");
            exit(EXIT_FAILURE);
         }
         insist(ret == 3);
      }
#endif
      /* write problem solution found by the solver (if required) */
      if (out_sol != NULL)
      {  switch (method)
         {  case 0:
               ret = lpx_print_sol(lp, out_sol);
               break;
            case 1:
               ret = lpx_print_ips(lp, out_sol);
               break;
            case 2:
               ret = lpx_print_mip(lp, out_sol);
               break;
            default:
               insist(method != method);
         }
         if (ret != 0)
         {  print("Unable to write problem solution");
            exit(EXIT_FAILURE);
         }
      }
      /* write sensitivity bounds information (if required) */
      if (out_bnds != NULL)
      {  if (method != 0)
         {  print("Cannot write sensitivity bounds information for inte"
               "rior-point or MIP solution");
            exit(EXIT_FAILURE);
         }
         ret = lpx_print_sens_bnds(lp, out_bnds);
         if (ret != 0)
         {  print("Unable to write sensitivity bounds information");
            exit(EXIT_FAILURE);
         }
      }
skip: /* delete the problem object */
      lpx_delete_prob(lp);
#if 1 /* 01/VIII-2004 */
      /* if the translator database exists, destroy it */
      if (mpl != NULL) mpl_terminate(mpl);
#endif
      /* check that no memory blocks are still allocated */
      insist(lib_env_ptr()->mem_total == 0);
      insist(lib_env_ptr()->mem_count == 0);
      /* return to the control program */
      return 0;
}
Пример #2
0
int glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
      	 double *a, double *b, char *ctype, int *freeLB, double *lb,
      	 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
      	 int save_pb, char *save_filename, char *filetype, 
         double *xmin, double *fmin, double *status,
      	 double *lambda, double *redcosts, double *time, double *mem)
{
  int typx = 0;
  int method;

  clock_t t_start = clock();

  // Obsolete
  //lib_set_fault_hook (NULL, glpk_fault_hook);

  //Redirect standard output
  if (glpIntParam[0] > 1) glp_term_hook (glpk_print_hook, NULL);
  else glp_term_hook (NULL, NULL);

  //-- Create an empty LP/MILP object
  glp_prob *lp = glp_create_prob ();

  //-- Set the sense of optimization
  if (sense == 1)
    glp_set_obj_dir (lp, GLP_MIN);
  else
    glp_set_obj_dir (lp, GLP_MAX);

  //-- Define the number of unknowns and their domains.
  glp_add_cols (lp, n);
  for (int i = 0; i < n; i++)
  {
    //-- Define type of the structural variables
    if (! freeLB[i] && ! freeUB[i])
      glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]);
    else
	  {
      if (! freeLB[i] && freeUB[i])
        glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]);
      else
      {
        if (freeLB[i] && ! freeUB[i])
		      glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]);
	      else
		      glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]);
	    }
	  }
  
  // -- Set the objective coefficient of the corresponding
  // -- structural variable. No constant term is assumed.
  glp_set_obj_coef(lp,i+1,c[i]);

  if (isMIP)
    glp_set_col_kind (lp, i+1, vartype[i]);
  }

  glp_add_rows (lp, m);

  for (int i = 0; i < m; i++)
  {
    /*  If the i-th row has no lower bound (types F,U), the
        corrispondent parameter will be ignored.
        If the i-th row has no upper bound (types F,L), the corrispondent
        parameter will be ignored.
        If the i-th row is of S type, the i-th LB is used, but
        the i-th UB is ignored.
    */

    switch (ctype[i])
    {
      case 'F': typx = GLP_FR; break;
      // upper bound
	    case 'U': typx = GLP_UP; break;
      // lower bound
	    case 'L': typx = GLP_LO; break;
      // fixed constraint
	    case 'S': typx = GLP_FX; break;
      // double-bounded variable
      case 'D': typx = GLP_DB; break;
	  }
      
    glp_set_row_bnds (lp, i+1, typx, b[i], b[i]);

  }
  // Load constraint matrix A
  glp_load_matrix (lp, nz, rn, cn, a);

  // Save problem
  if (save_pb) {
    if (!strcmp(filetype,"cplex")){
      if (lpx_write_cpxlp (lp, save_filename) != 0) {
	        mexErrMsgTxt("glpkcc: unable to write the problem");
	        longjmp (mark, -1);
      }
    }else{
      if (!strcmp(filetype,"fixedmps")){
        if (lpx_write_mps (lp, save_filename) != 0) {
          mexErrMsgTxt("glpkcc: unable to write the problem");
	        longjmp (mark, -1);  
        }
      }else{
        if (!strcmp(filetype,"freemps")){
          if (lpx_write_freemps (lp, save_filename) != 0) {
            mexErrMsgTxt("glpkcc: unable to write the problem");
	          longjmp (mark, -1);
          }
        }else{// plain text
          if (lpx_print_prob (lp, save_filename) != 0) {
            mexErrMsgTxt("glpkcc: unable to write the problem");
	          longjmp (mark, -1);
          } 
        } 
      }    
    } 
  }
  //-- scale the problem data (if required)
  if (glpIntParam[1] && (! glpIntParam[16] || lpsolver != 1))
    lpx_scale_prob (lp);

  //-- build advanced initial basis (if required)
  if (lpsolver == 1 && ! glpIntParam[16])
    lpx_adv_basis (lp);

  glp_smcp sParam;
  glp_init_smcp(&sParam);
  
  //-- set control parameters
  if (lpsolver==1){
    //remap of control parameters for simplex method
    sParam.msg_lev=glpIntParam[0];	// message level
    // simplex method: primal/dual
    if (glpIntParam[2]==0) sParam.meth=GLP_PRIMAL;		
    else sParam.meth=GLP_DUALP;
    // pricing technique
    if (glpIntParam[3]==0) sParam.pricing=GLP_PT_STD;
    else sParam.pricing=GLP_PT_PSE;
    //sParam.r_test not available
    sParam.tol_bnd=glpRealParam[1];	// primal feasible tollerance
    sParam.tol_dj=glpRealParam[2];	// dual feasible tollerance
    sParam.tol_piv=glpRealParam[3];	// pivot tollerance
    sParam.obj_ll=glpRealParam[4];	// lower limit
    sParam.obj_ul=glpRealParam[5];	// upper limit
    // iteration limit
    if (glpIntParam[5]==-1) sParam.it_lim=INT_MAX;
    else sParam.it_lim=glpIntParam[5];   
    // time limit
    if (glpRealParam[6]==-1) sParam.tm_lim=INT_MAX;
    else sParam.tm_lim=(int) glpRealParam[6];	
    sParam.out_frq=glpIntParam[7];	// output frequency
    sParam.out_dly=(int) glpRealParam[7];	// output delay
    // presolver
    if (glpIntParam[16]) sParam.presolve=GLP_ON;
    else sParam.presolve=GLP_OFF;
  }else{
	for(int i = 0; i < NIntP; i++)
		lpx_set_int_parm (lp, IParam[i], glpIntParam[i]);
		
	for (int i = 0; i < NRealP; i++)
		lpx_set_real_parm (lp, RParam[i], glpRealParam[i]);
  }
  

  // Choose simplex method ('S') or interior point method ('T') to solve the problem
  if (lpsolver == 1)
    method = 'S';
  else
    method = 'T';
	
  int errnum;

  switch (method){
    case 'S': {
      if (isMIP){
	    method = 'I';
	    errnum = lpx_intopt (lp);
      }
      else{
		errnum = glp_simplex(lp, &sParam);
		errnum += 100; //this is to avoid ambiguity in the return codes.
	  }
    }
    break;

    case 'T': errnum = lpx_interior(lp); break;

    default:  xassert (method != method);
  }

  /*  errnum assumes the following results:
      errnum = 0 <=> No errors
      errnum = 1 <=> Iteration limit exceeded.
      errnum = 2 <=> Numerical problems with basis matrix.
  */
  if (errnum == LPX_E_OK || errnum==100){
    // Get status and object value
    if (isMIP)
    {
      *status = glp_mip_status (lp);
      *fmin = glp_mip_obj_val (lp);
    }
    else
    {
      if (lpsolver == 1)
      {
        *status = glp_get_status (lp);
        *fmin = glp_get_obj_val (lp);
	    }
      else
      {
        *status = glp_ipt_status (lp);
        *fmin = glp_ipt_obj_val (lp);
	    }
    }
    // Get optimal solution (if exists)
    if (isMIP)
    {
      for (int i = 0; i < n; i++)
        xmin[i] = glp_mip_col_val (lp, i+1);
    }
    else
    {
      /* Primal values */
      for (int i = 0; i < n; i++)
      {
        if (lpsolver == 1)
          xmin[i] = glp_get_col_prim (lp, i+1);
        else
		      xmin[i] = glp_ipt_col_prim (lp, i+1);
      }
      /* Dual values */
      for (int i = 0; i < m; i++)
      {
        if (lpsolver == 1) lambda[i] = glp_get_row_dual (lp, i+1);
	     else lambda[i] = glp_ipt_row_dual (lp, i+1);
      }
      /* Reduced costs */
      for (int i = 0; i < glp_get_num_cols (lp); i++)
      {
        if (lpsolver == 1) redcosts[i] = glp_get_col_dual (lp, i+1);
        else redcosts[i] = glp_ipt_col_dual (lp, i+1);
      }
    }

    *time = (clock () - t_start) / CLOCKS_PER_SEC;
    
   	glp_ulong tpeak;
    lib_mem_usage(NULL, NULL, NULL, &tpeak);
    *mem=(double)(4294967296.0 * tpeak.hi + tpeak.lo) / (1024);
       
	  glp_delete_prob (lp);
    return 0;
  }

  glp_delete_prob (lp);

  *status = errnum;

  return errnum;
}
Пример #3
0
int main(int argc, char *argv[])
{     LPX *lp;
      MPL *mpl = NULL;
      int ret;
      ulong_t start;
      /* parse command line parameters */
      parse_cmdline(argc, argv);
      /* set available memory limit */
      if (memlim >= 0)
         lib_mem_limit(ulmul(ulset(0, 1048576), ulset(0, memlim)));
      /* remove all output files specified in the command line */
      if (display != NULL) remove(display);
      if (out_bas != NULL) remove(out_bas);
      if (out_sol != NULL) remove(out_sol);
      if (out_bnds != NULL) remove(out_bnds);
      if (out_mps != NULL) remove(out_mps);
      if (out_freemps != NULL) remove(out_freemps);
      if (out_cpxlp != NULL) remove(out_cpxlp);
      if (out_txt != NULL) remove(out_txt);
      if (out_glp != NULL) remove(out_glp);
      if (log_file != NULL) remove(log_file);
      /* open hardcopy file, if necessary */
      if (log_file != NULL)
      {  if (lib_open_log(log_file))
         {  print("Unable to create log file");
            exit(EXIT_FAILURE);
         }
      }
      /* read problem data from the input file */
      if (in_file == NULL)
      {  print("No input file specified; try %s --help", argv[0]);
         exit(EXIT_FAILURE);
      }
      switch (format)
      {  case 0:
            lp = lpx_read_mps(in_file);
            if (lp == NULL)
            {  print("MPS file processing error");
               exit(EXIT_FAILURE);
            }
            orig = 1;
            break;
         case 1:
            lp = lpx_read_cpxlp(in_file);
            if (lp == NULL)
            {  print("CPLEX LP file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         case 2:
            /* initialize the translator database */
            mpl = mpl_initialize();
            /* read model section and optional data section */
            ret = mpl_read_model(mpl, in_file, in_data != NULL);
            if (ret == 4)
err:        {  print("Model processing error");
               exit(EXIT_FAILURE);
            }
            xassert(ret == 1 || ret == 2);
            /* read data section, if necessary */
            if (in_data != NULL)
            {  xassert(ret == 1);
               ret = mpl_read_data(mpl, in_data);
               if (ret == 4) goto err;
               xassert(ret == 2);
            }
            /* generate model */
            ret = mpl_generate(mpl, display);
            if (ret == 4) goto err;
            /* extract problem instance */
            lp = lpx_extract_prob(mpl);
            xassert(lp != NULL);
            break;
         case 3:
            lp = lpx_read_prob(in_file);
            if (lp == NULL)
            {  print("GNU LP file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         case 4:
            lp = lpx_read_freemps(in_file);
            if (lp == NULL)
            {  print("MPS file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         default:
            xassert(format != format);
      }
      /* order rows and columns of the constraint matrix */
      lpx_order_matrix(lp);
      /* change problem name (if required) */
      if (newname != NULL) lpx_set_prob_name(lp, newname);
      /* change optimization direction (if required) */
      if (dir != 0) lpx_set_obj_dir(lp, dir);
      /* write problem in fixed MPS format (if required) */
      if (out_mps != NULL)
      {  lpx_set_int_parm(lp, LPX_K_MPSORIG, orig);
         ret = lpx_write_mps(lp, out_mps);
         if (ret != 0)
         {  print("Unable to write problem in fixed MPS format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in free MPS format (if required) */
      if (out_freemps != NULL)
      {  ret = lpx_write_freemps(lp, out_freemps);
         if (ret != 0)
         {  print("Unable to write problem in free MPS format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in CPLEX LP format (if required) */
      if (out_cpxlp != NULL)
      {  ret = lpx_write_cpxlp(lp, out_cpxlp);
         if (ret != 0)
         {  print("Unable to write problem in CPLEX LP format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in plain text format (if required) */
      if (out_txt != NULL)
      {  lpx_set_int_parm(lp, LPX_K_LPTORIG, orig);
         ret = lpx_print_prob(lp, out_txt);
         if (ret != 0)
         {  print("Unable to write problem in plain text format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in GNU LP format (if required) */
      if (out_glp != NULL)
      {  ret = lpx_write_prob(lp, out_glp);
         if (ret != 0)
         {  print("Unable to write problem in GNU LP format");
            exit(EXIT_FAILURE);
         }
      }
      /* if only data check is required, skip computations */
      if (check) goto skip;
      /* scale the problem data (if required) */
      if (scale && (!presol || method == 1)) lpx_scale_prob(lp);
      /* build initial LP basis */
      if (method == 0 && !presol && in_bas == NULL)
      {  switch (basis)
         {  case 0:
               lpx_std_basis(lp);
               break;
            case 1:
               if (lpx_get_num_rows(lp) > 0 && lpx_get_num_cols(lp) > 0)
                  lpx_adv_basis(lp);
               break;
            case 2:
               if (lpx_get_num_rows(lp) > 0 && lpx_get_num_cols(lp) > 0)
                  lpx_cpx_basis(lp);
               break;
            default:
               xassert(basis != basis);
         }
      }
      /* or read initial basis from input text file in MPS format */
      if (in_bas != NULL)
      {  if (method != 0)
         {  print("Initial LP basis is useless for interior-point solve"
               "r and therefore ignored");
            goto nobs;
         }
         lpx_set_int_parm(lp, LPX_K_MPSORIG, orig);
         ret = lpx_read_bas(lp, in_bas);
         if (ret != 0)
         {  print("Unable to read initial LP basis");
            exit(EXIT_FAILURE);
         }
         if (presol)
         {  presol = 0;
            print("LP presolver disabled because initial LP basis has b"
               "een provided");
         }
nobs:    ;
      }
      /* set some control parameters, which might be changed in the
         command line */
      lpx_set_int_parm(lp, LPX_K_BFTYPE, bf_type);
      lpx_set_int_parm(lp, LPX_K_PRICE, price);
      if (!relax) lpx_set_real_parm(lp, LPX_K_RELAX, 0.0);
      lpx_set_int_parm(lp, LPX_K_PRESOL, presol);
      lpx_set_int_parm(lp, LPX_K_BRANCH, branch);
      lpx_set_int_parm(lp, LPX_K_BTRACK, btrack);
      lpx_set_real_parm(lp, LPX_K_TMLIM, (double)tmlim);
      lpx_set_int_parm(lp, LPX_K_BINARIZE, binarize);
      lpx_set_int_parm(lp, LPX_K_USECUTS, use_cuts);
      /* solve the problem */
      start = xtime();
      switch (method)
      {  case 0:
            if (nomip || lpx_get_class(lp) == LPX_LP)
            {  ret = (!exact ? lpx_simplex(lp) : lpx_exact(lp));
               if (xcheck)
               {  if (!presol || ret == LPX_E_OK)
                     lpx_exact(lp);
                  else
                     print("If you need checking final basis for non-op"
                        "timal solution, use --nopresol");
               }
               if (presol && ret != LPX_E_OK && (out_bas != NULL ||
                  out_sol != NULL))
                  print("If you need actual output for non-optimal solu"
                     "tion, use --nopresol");
            }
            else
            {  method = 2;
               if (!intopt)
               {  ret = (!exact ? lpx_simplex(lp) : lpx_exact(lp));
                  if (xcheck && (!presol || ret == LPX_E_OK))
                     lpx_exact(lp);
                  lpx_integer(lp);
               }
               else
                  lpx_intopt(lp);
            }
            break;
         case 1:
            if (nomip || lpx_get_class(lp) == LPX_LP)
               lpx_interior(lp);
            else
            {  print("Interior-point method is not able to solve MIP pr"
                  "oblem; use --simplex");
               exit(EXIT_FAILURE);
            }
            break;
         default:
            xassert(method != method);
      }
      /* display statistics */
      print("Time used:   %.1f secs", xdifftime(xtime(), start));
      {  ulong_t tpeak;
         char buf[50];
         lib_mem_usage(NULL, NULL, NULL, &tpeak);
         print("Memory used: %.1f Mb (%s bytes)",
            (4294967296.0 * tpeak.hi + tpeak.lo) / 1048576.0,
            ultoa(tpeak, buf, 10));
      }
      if (mpl != NULL && mpl_has_solve_stmt(mpl))
      {  int n, j, round;
         /* store the solution to the translator database */
         n = lpx_get_num_cols(lp);
         round = lpx_get_int_parm(lp, LPX_K_ROUND);
         lpx_set_int_parm(lp, LPX_K_ROUND, 1);
         switch (method)
         {  case 0:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_get_col_prim(lp, j));
               break;
            case 1:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_ipt_col_prim(lp, j));
               break;
            case 2:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_mip_col_val(lp, j));
               break;
            default:
               xassert(method != method);
         }
         lpx_set_int_parm(lp, LPX_K_ROUND, round);
         /* perform postsolving */
         ret = mpl_postsolve(mpl);
         if (ret == 4)
         {  print("Model postsolving error");
            exit(EXIT_FAILURE);
         }
         xassert(ret == 3);
      }
      /* write final LP basis (if required) */
      if (out_bas != NULL)
      {  lpx_set_int_parm(lp, LPX_K_MPSORIG, orig);
         ret = lpx_write_bas(lp, out_bas);
         if (ret != 0)
         {  print("Unable to write final LP basis");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem solution found by the solver (if required) */
      if (out_sol != NULL)
      {  switch (method)
         {  case 0:
               ret = lpx_print_sol(lp, out_sol);
               break;
            case 1:
               ret = lpx_print_ips(lp, out_sol);
               break;
            case 2:
               ret = lpx_print_mip(lp, out_sol);
               break;
            default:
               xassert(method != method);
         }
         if (ret != 0)
         {  print("Unable to write problem solution");
            exit(EXIT_FAILURE);
         }
      }
      /* write sensitivity bounds information (if required) */
      if (out_bnds != NULL)
      {  if (method != 0)
         {  print("Cannot write sensitivity bounds information for inte"
               "rior-point or MIP solution");
            exit(EXIT_FAILURE);
         }
         ret = lpx_print_sens_bnds(lp, out_bnds);
         if (ret != 0)
         {  print("Unable to write sensitivity bounds information");
            exit(EXIT_FAILURE);
         }
      }
skip: /* delete the problem object */
      lpx_delete_prob(lp);
      /* if the translator database exists, destroy it */
      if (mpl != NULL) mpl_terminate(mpl);
      xassert(gmp_pool_count() == 0);
      gmp_free_mem();
      /* close the hardcopy file */
      if (log_file != NULL) lib_close_log();
      /* check that no memory blocks are still allocated */
      {  int count;
         ulong_t total;
         lib_mem_usage(&count, NULL, &total, NULL);
         xassert(count == 0);
         xassert(total.lo == 0 && total.hi == 0);
      }
      /* free the library environment */
      lib_free_env();
      /* return to the control program */
      return 0;
}
Пример #4
0
int glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
      	 double *a, double *b, char *ctype, int *freeLB, double *lb,
      	 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
      	 int save_pb, char *save_filename, char *filetype,
         double *xmin, double *fmin, double *status,
      	 double *lambda, double *redcosts, double *time, double *mem)
{
  int typx = 0;
  int method;

  clock_t t_start = clock();

  //Redirect standard output
  if (glpIntParam[0] > 1) glp_term_hook (glpk_print_hook, NULL);
  else glp_term_hook (NULL, NULL);

  //-- Create an empty LP/MILP object
  LPX *lp = lpx_create_prob ();

  //-- Set the sense of optimization
  if (sense == 1)
    glp_set_obj_dir (lp, GLP_MIN);
  else
    glp_set_obj_dir (lp, GLP_MAX);

  //-- Define the number of unknowns and their domains.
  glp_add_cols (lp, n);
  for (int i = 0; i < n; i++)
  {
    //-- Define type of the structural variables
    if (! freeLB[i] && ! freeUB[i]) {
      if ( lb[i] == ub[i] )
        glp_set_col_bnds (lp, i+1, GLP_FX, lb[i], ub[i]);
      else
        glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]);
    }
    else
	  {
      if (! freeLB[i] && freeUB[i])
        glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]);
      else
      {
        if (freeLB[i] && ! freeUB[i])
		      glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]);
	      else
		      glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]);
	    }
	  }

  // -- Set the objective coefficient of the corresponding
  // -- structural variable. No constant term is assumed.
  glp_set_obj_coef(lp,i+1,c[i]);

  if (isMIP)
    glp_set_col_kind (lp, i+1, vartype[i]);
  }

  glp_add_rows (lp, m);

  for (int i = 0; i < m; i++)
  {
    /*  If the i-th row has no lower bound (types F,U), the
        corrispondent parameter will be ignored.
        If the i-th row has no upper bound (types F,L), the corrispondent
        parameter will be ignored.
        If the i-th row is of S type, the i-th LB is used, but
        the i-th UB is ignored.
    */

    switch (ctype[i])
    {
      case 'F': typx = GLP_FR; break;
      // upper bound
	  case 'U': typx = GLP_UP; break;
      // lower bound
	  case 'L': typx = GLP_LO; break;
      // fixed constraint
	  case 'S': typx = GLP_FX; break;
      // double-bounded variable
      case 'D': typx = GLP_DB; break;
	}

    if ( typx == GLP_DB && -b[i] < b[i]) {
        glp_set_row_bnds (lp, i+1, typx, -b[i], b[i]);
    }
    else if(typx == GLP_DB && -b[i] == b[i]) {
        glp_set_row_bnds (lp, i+1, GLP_FX, b[i], b[i]);
    }
    else {
    // this should be glp_set_row_bnds (lp, i+1, typx, -b[i], b[i]);
        glp_set_row_bnds (lp, i+1, typx, b[i], b[i]);
    }

  }
  // Load constraint matrix A
  glp_load_matrix (lp, nz, rn, cn, a);

  // Save problem
  if (save_pb) {
    if (!strcmp(filetype,"cplex")){
      if (glp_write_lp (lp, NULL, save_filename) != 0) {
	        mexErrMsgTxt("glpk: unable to write the problem");
	        longjmp (mark, -1);
      }
    }else{
      if (!strcmp(filetype,"fixedmps")){
        if (glp_write_mps (lp, GLP_MPS_DECK, NULL, save_filename) != 0) {
            mexErrMsgTxt("glpk: unable to write the problem");
	        longjmp (mark, -1);
        }
      }else{
        if (!strcmp(filetype,"freemps")){
          if (glp_write_mps (lp, GLP_MPS_FILE, NULL, save_filename) != 0) {
              mexErrMsgTxt("glpk: unable to write the problem");
	          longjmp (mark, -1);
          }
        }else{// plain text
          if (lpx_print_prob (lp, save_filename) != 0) {
              mexErrMsgTxt("glpk: unable to write the problem");
	          longjmp (mark, -1);
          }
        }
      }
    }
  }
  //-- scale the problem data (if required)
  if (! glpIntParam[16] || lpsolver != 1) {
    switch ( glpIntParam[1] ) {
        case ( 0 ): glp_scale_prob( lp, GLP_SF_SKIP ); break;
        case ( 1 ): glp_scale_prob( lp, GLP_SF_GM ); break;
        case ( 2 ): glp_scale_prob( lp, GLP_SF_EQ ); break;
        case ( 3 ): glp_scale_prob( lp, GLP_SF_AUTO  ); break;
        case ( 4 ): glp_scale_prob( lp, GLP_SF_2N ); break;
        default :
            mexErrMsgTxt("glpk: unrecognized scaling option");
            longjmp (mark, -1);
    }
  }
  else {
    /* do nothing? or unscale?
        glp_unscale_prob( lp );
    */
  }

  //-- build advanced initial basis (if required)
  if (lpsolver == 1 && ! glpIntParam[16])
    glp_adv_basis (lp, 0);

  glp_smcp sParam;
  glp_init_smcp(&sParam);

  //-- set control parameters for simplex/exact method
  if (lpsolver == 1 || lpsolver == 3){
    //remap of control parameters for simplex method
    sParam.msg_lev=glpIntParam[0];	// message level

    // simplex method: primal/dual
    switch ( glpIntParam[2] ) {
        case 0: sParam.meth=GLP_PRIMAL; break;
        case 1: sParam.meth=GLP_DUAL;   break;
        case 2: sParam.meth=GLP_DUALP;  break;
        default:
            mexErrMsgTxt("glpk: unrecognized primal/dual method");
            longjmp (mark, -1);
    }

    // pricing technique
    if (glpIntParam[3]==0) sParam.pricing=GLP_PT_STD;
    else sParam.pricing=GLP_PT_PSE;

    // ratio test
    if (glpIntParam[20]==0) sParam.r_test = GLP_RT_STD;
    else sParam.r_test=GLP_RT_HAR;

    //tollerances
    sParam.tol_bnd=glpRealParam[1];	// primal feasible tollerance
    sParam.tol_dj=glpRealParam[2];	// dual feasible tollerance
    sParam.tol_piv=glpRealParam[3];	// pivot tollerance
    sParam.obj_ll=glpRealParam[4];	// lower limit
    sParam.obj_ul=glpRealParam[5];	// upper limit

    // iteration limit
    if (glpIntParam[5]==-1) sParam.it_lim=INT_MAX;
    else sParam.it_lim=glpIntParam[5];

    // time limit
    if (glpRealParam[6]==-1) sParam.tm_lim=INT_MAX;
    else sParam.tm_lim=(int) glpRealParam[6];
    sParam.out_frq=glpIntParam[7];	// output frequency
    sParam.out_dly=(int) glpRealParam[7];	// output delay
    // presolver
    if (glpIntParam[16]) sParam.presolve=GLP_ON;
    else sParam.presolve=GLP_OFF;
  }else{
	for(int i = 0; i < NIntP; i++) {
        // skip assinging ratio test or
        if ( i == 18 || i == 20) continue;
		lpx_set_int_parm (lp, IParam[i], glpIntParam[i]);
    }

	for (int i = 0; i < NRealP; i++) {
		lpx_set_real_parm (lp, RParam[i], glpRealParam[i]);
    }
  }

  //set MIP params if MIP....
  glp_iocp iParam;
  glp_init_iocp(&iParam);

  if ( isMIP ){
    method = 'I';

    switch (glpIntParam[0]) { //message level
         case 0:  iParam.msg_lev = GLP_MSG_OFF;   break;
         case 1:  iParam.msg_lev = GLP_MSG_ERR;   break;
         case 2:  iParam.msg_lev = GLP_MSG_ON;    break;
         case 3:  iParam.msg_lev = GLP_MSG_ALL;   break;
         default:  mexErrMsgTxt("glpk: msg_lev bad param");
    }
    switch (glpIntParam[14]) { //branching param
         case 0:  iParam.br_tech = GLP_BR_FFV;    break;
         case 1:  iParam.br_tech = GLP_BR_LFV;    break;
         case 2:  iParam.br_tech = GLP_BR_MFV;    break;
         case 3:  iParam.br_tech = GLP_BR_DTH;    break;
         default: mexErrMsgTxt("glpk: branch bad param");
    }
    switch (glpIntParam[15]) { //backtracking heuristic
        case 0:  iParam.bt_tech = GLP_BT_DFS;    break;
        case 1:  iParam.bt_tech = GLP_BT_BFS;    break;
        case 2:  iParam.bt_tech = GLP_BT_BLB;    break;
        case 3:  iParam.bt_tech = GLP_BT_BPH;    break;
        default: mexErrMsgTxt("glpk: backtrack bad param");
    }

    if (  glpRealParam[8] > 0.0 && glpRealParam[8] < 1.0 )
        iParam.tol_int = glpRealParam[8];  // absolute tolorence
    else
        mexErrMsgTxt("glpk: tolint must be between 0 and 1");

    iParam.tol_obj = glpRealParam[9];  // relative tolarence
    iParam.mip_gap = glpRealParam[10]; // realative gap tolerance

    // set time limit for mip
    if ( glpRealParam[6] < 0.0 || glpRealParam[6] > 1e6 )
       iParam.tm_lim = INT_MAX;
    else
       iParam.tm_lim = (int)(1000.0 * glpRealParam[6] );

    // Choose Cutsets for mip
    // shut all cuts off, then start over....
    iParam.gmi_cuts = GLP_OFF;
    iParam.mir_cuts = GLP_OFF;
    iParam.cov_cuts = GLP_OFF;
    iParam.clq_cuts = GLP_OFF;

    switch( glpIntParam[17] ) {
        case 0: break;
        case 1: iParam.gmi_cuts = GLP_ON; break;
        case 2: iParam.mir_cuts = GLP_ON; break;
        case 3: iParam.cov_cuts = GLP_ON; break;
        case 4: iParam.clq_cuts = GLP_ON; break;
        case 5: iParam.clq_cuts = GLP_ON;
                iParam.gmi_cuts = GLP_ON;
                iParam.mir_cuts = GLP_ON;
                iParam.cov_cuts = GLP_ON;
                iParam.clq_cuts = GLP_ON; break;
        default: mexErrMsgTxt("glpk: cutset bad param");
    }

    switch( glpIntParam[18] ) { // pre-processing for mip
        case 0: iParam.pp_tech = GLP_PP_NONE; break;
        case 1: iParam.pp_tech = GLP_PP_ROOT; break;
        case 2: iParam.pp_tech = GLP_PP_ALL;  break;
        default:  mexErrMsgTxt("glpk: pprocess bad param");
    }

    if (glpIntParam[16])  iParam.presolve=GLP_ON;
    else                  iParam.presolve=GLP_OFF;

    if (glpIntParam[19])  iParam.binarize = GLP_ON;
    else                  iParam.binarize = GLP_OFF;

  }
  else {
     /* Choose simplex method ('S')
     or interior point method ('T')
     or Exact method          ('E')
     to solve the problem  */
    switch (lpsolver) {
      case 1: method = 'S'; break;
      case 2: method = 'T'; break;
      case 3: method = 'E'; break;
      default:
            mexErrMsgTxt("glpk:  lpsolver != lpsolver");
            longjmp (mark, -1);
    }
  }

	// now run the problem...
	int errnum = 0;

	switch (method) {
	case 'I':
		errnum = glp_intopt( lp, &iParam );
		errnum += 200; //this is to avoid ambiguity in the return codes.
		break;

	case 'S':
		errnum = glp_simplex(lp, &sParam);
		errnum += 100; //this is to avoid ambiguity in the return codes.
		break;

	case 'T':
		errnum = glp_interior(lp, NULL );
		errnum += 300; //this is to avoid ambiguity in the return codes.
		break;

	case 'E':
		errnum = glp_exact(lp, &sParam);
		errnum += 100; //this is to avoid ambiguity in the return codes.
		break;

	default:  /*xassert (method != method); */
		mexErrMsgTxt("glpk: method != method");
		longjmp (mark, -1);
	}

    if (errnum==100 || errnum==200 || errnum==300 || errnum==106 || errnum==107 || errnum==108 || errnum==109 || errnum==209 || errnum==214 || errnum==308) {

    // Get status and object value
    if (isMIP) {
      *status = glp_mip_status (lp);
      *fmin = glp_mip_obj_val (lp);
    }
    else {

      if (lpsolver == 1 || lpsolver == 3) {
        *status = glp_get_status (lp);
        *fmin = glp_get_obj_val (lp);
	  }
      else {
        *status = glp_ipt_status (lp);
        *fmin = glp_ipt_obj_val (lp);
	  }
    }

    // Get optimal solution (if exists)
    if (isMIP) {

      for (int i = 0; i < n; i++)
        xmin[i] = glp_mip_col_val (lp, i+1);
    }
    else {

      /* Primal values */
      for (int i = 0; i < n; i++) {

        if (lpsolver == 1 || lpsolver == 3)
              xmin[i] = glp_get_col_prim (lp, i+1);
        else
		      xmin[i] = glp_ipt_col_prim (lp, i+1);
      }

      /* Dual values */
      for (int i = 0; i < m; i++) {

        if (lpsolver == 1 || lpsolver == 3)
            lambda[i] = glp_get_row_dual (lp, i+1);
	    else
            lambda[i] = glp_ipt_row_dual (lp, i+1);
      }

      /* Reduced costs */
      for (int i = 0; i < glp_get_num_cols (lp); i++) {

        if (lpsolver == 1 || lpsolver == 3)
            redcosts[i] = glp_get_col_dual (lp, i+1);
        else
            redcosts[i] = glp_ipt_col_dual (lp, i+1);
      }

    }

    *time = (clock () - t_start) / CLOCKS_PER_SEC;

    size_t tpeak;
    glp_mem_usage(NULL, NULL, NULL, &tpeak);
    *mem=((double) tpeak) / (1024);

	lpx_delete_prob(lp);

    return 0;
  }
  else {
   // printf("errnum is %d\n", errnum);
  }

  lpx_delete_prob(lp);

  /* this shouldn't be nessiary with glp_deleted_prob, but try it
  if we have weird behavior again... */
  glp_free_env();


  *status = errnum;

  return errnum;
}