예제 #1
0
int main(int argc,char *argv[])
{
  MSKenv_t  env = NULL;
  MSKtask_t task = NULL;
  MSKintt r = MSK_RES_OK;
  
  /* Create mosek environment. */
  r = MSK_makeenv(&env,NULL); 

  if ( r==MSK_RES_OK )
    r = MSK_maketask(env,0,0,&task);
  
  if ( r==MSK_RES_OK )
    MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);

  if (r == MSK_RES_OK)
    r = MSK_readdata(task,argv[1]);

  MSK_putintparam(task,MSK_IPAR_OPTIMIZER,MSK_OPTIMIZER_CONCURRENT);
  MSK_putintparam(task,MSK_IPAR_CONCURRENT_NUM_OPTIMIZERS,2);

  if (r == MSK_RES_OK)
    r = MSK_optimize(task);

  MSK_solutionsummary(task,MSK_STREAM_LOG);

   
  MSK_deletetask(&task);
  MSK_deleteenv(&env);

  printf("Return code: %d (0 means no error occured.)\n",r);

  return ( r );
} /* main */
예제 #2
0
int mosekNNSolverWrapper(const Matrix &Q, const Matrix &Eq, const Matrix &b,
                         const Matrix &InEq, const Matrix &ib,
                         const Matrix &lowerBounds, const Matrix &upperBounds,
                         Matrix &sol, double *objVal, MosekObjectiveType objType)
{
  DBGP("Mosek QP Wrapper started");
  MSKrescodee  r;
  MSKtask_t task = NULL;

  // Get the only instance of the mosek environment.
  MSKenv_t     env  = getMosekEnv();
  // Create the optimization task.
  r = MSK_maketask(env, 0, 0, &task);
  if (r != MSK_RES_OK) {
    DBGA("Failed to create optimization task");
    return -1;
  }
  MSK_linkfunctotaskstream(task, MSK_STREAM_LOG, NULL, printstr);

  //---------------------------------------
  //start inputing the problem
  //prespecify number of variables to make inputting faster
  r = MSK_putmaxnumvar(task, sol.rows());
  //number of constraints (both equality and inequality)
  if (r == MSK_RES_OK) {
    r = MSK_putmaxnumcon(task, Eq.rows() + InEq.rows());
  }
  //make sure default value is 0 for sparse matrices
  assert(Q.getDefault() == 0.0);
  assert(Eq.getDefault() == 0.0);
  assert(InEq.getDefault() == 0.0);
  //number of non-zero entries in A
  if (r == MSK_RES_OK) {
    r = MSK_putmaxnumanz(task, Eq.numElements() + InEq.numElements());
  }
  if (r != MSK_RES_OK) {
    DBGA("Failed to input variables");
    MSK_deletetask(&task);
    return -1;
  }

  //solver is sensitive to numerical problems. Scale the problem down
  //we will use this value to scale down the right hand side of equality
  //and inequality constraints and lower and upper bounds
  //after solving, we must scale back up the solution and the value of the
  //objective
  double scale = b.absMax();
  if (scale < 1.0e2) {
    scale = 1.0;
  } else {
    DBGP("Mosek solver: scaling problem down by " << scale);
  }

  //---------------------------------------
  //insert the actual variables and constraints

  //append the variables
  MSK_append(task, MSK_ACC_VAR, sol.rows());
  //append the constraints.
  MSK_append(task, MSK_ACC_CON, Eq.rows() + InEq.rows());

  int i, j;
  double value;
  if (objType == MOSEK_OBJ_QP) {
    //quadratic optimization objective
    //the quadratic term
    Q.sequentialReset();
    while (Q.nextSequentialElement(i, j, value)) {
      MSK_putqobjij(task, i, j, 2.0 * value);
    }
  } else if (objType == MOSEK_OBJ_LP) {
    //linear objective
    for (j = 0; j < Q.cols(); j++) {
      if (fabs(Q.elem(0, j)) > 1.0e-5) {
        MSK_putcj(task, j, Q.elem(0, j));
      }
    }
  } else {
    assert(0);
  }

  //variable bounds
  assert(sol.rows() == lowerBounds.rows());
  assert(sol.rows() == upperBounds.rows());
  for (i = 0; i < sol.rows(); i++) {
    if (lowerBounds.elem(i, 0) >= upperBounds.elem(i, 0)) {
      if (lowerBounds.elem(i, 0) > upperBounds.elem(i, 0)) {
        assert(0);
      }
      if (lowerBounds.elem(i, 0) == -std::numeric_limits<double>::max()) {
        assert(0);
      }
      if (upperBounds.elem(i, 0) == std::numeric_limits<double>::max()) {
        assert(0);
      }
      //fixed variable
      DBGP(i << ": fixed " << lowerBounds.elem(i, 0) / scale);
      MSK_putbound(task, MSK_ACC_VAR, i, MSK_BK_FX,
                   lowerBounds.elem(i, 0) / scale, upperBounds.elem(i, 0) / scale);
    } else if (lowerBounds.elem(i, 0) != -std::numeric_limits<double>::max()) {
      //finite lower bound
      if (upperBounds.elem(i, 0) != std::numeric_limits<double>::max()) {
        //two finite bounds
        DBGP(i << ": finite bounds " << lowerBounds.elem(i, 0) / scale
             << " " << upperBounds.elem(i, 0) / scale);
        MSK_putbound(task, MSK_ACC_VAR, i, MSK_BK_RA,
                     lowerBounds.elem(i, 0) / scale, upperBounds.elem(i, 0) / scale);
      } else {
        //lower bound
        DBGP(i << ": lower bound " << lowerBounds.elem(i, 0) / scale);
        MSK_putbound(task, MSK_ACC_VAR, i, MSK_BK_LO,
                     lowerBounds.elem(i, 0) / scale, +MSK_INFINITY);

      }
    } else {
      //infinite lower bound
      if (upperBounds.elem(i, 0) != std::numeric_limits<double>::max()) {
        //upper bound
        DBGP(i << ": upper bound " << upperBounds.elem(i, 0) / scale);
        MSK_putbound(task, MSK_ACC_VAR, i, MSK_BK_UP,
                     -MSK_INFINITY, upperBounds.elem(i, 0) / scale);
      } else {
        //unbounded
        DBGP(i << ": unbounded");
        MSK_putbound(task, MSK_ACC_VAR, i, MSK_BK_FR,
                     -MSK_INFINITY, +MSK_INFINITY);

      }
    }
  }

  //constraints and constraint bounds
  //equality constraints
  Eq.sequentialReset();
  while (Eq.nextSequentialElement(i, j, value)) {
    MSK_putaij(task, i, j, value);
  }
  for (i = 0; i < Eq.rows(); i++) {
    MSK_putbound(task, MSK_ACC_CON, i, MSK_BK_FX, b.elem(i, 0) / scale, b.elem(i, 0) / scale);
  }
  //inequality constraints, <=
  InEq.sequentialReset();
  while (InEq.nextSequentialElement(i, j, value)) {
    int eqi = i + Eq.rows();
    MSK_putaij(task, eqi, j, value);
  }
  for (i = 0; i < InEq.rows(); i++) {
    int eqi = i + Eq.rows();
    MSK_putbound(task, MSK_ACC_CON, eqi, MSK_BK_UP, -MSK_INFINITY, ib.elem(i, 0) / scale);
  }
  //specify objective: minimize
  MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MINIMIZE);

  //give it 800 iterations, twice the default.
  MSK_putintparam(task, MSK_IPAR_INTPNT_MAX_ITERATIONS, 800);

  //----------------------------------

  //solve the thing
  DBGP("Optimization started");
  r = MSK_optimize(task);
  DBGP("Optimization returns");

  //write problem to file
  /*
  static int fileNum = 0;
  if (r != MSK_RES_OK) {
    char filename[50];
    sprintf(filename,"mosek_error_%d_%d.opf",fileNum++, r);
    MSK_writedata(task, filename);
    FILE *fp = fopen(filename,"a");
    fprintf(fp,"\n\nEquality matrix:\n");
    Eq.print(fp);
    fclose(fp);
  }
  */

  if (r != MSK_RES_OK) {
    DBGA("Mosek optimization call failed, error code " << r);
    MSK_deletetask(&task);
    return -1;
  }
  DBGP("Optimization complete");
  //debug code, find out number of iterations used
  //int iter;
  //MSK_getintinf(task, MSK_IINF_INTPNT_ITER, &iter);
  //DBGA("Iterations used: " << iter);

  //find out what kind of solution we have
  MSKprostae pst;
  MSKsolstae sst;
  MSK_getsolutionstatus(task, MSK_SOL_ITR, &pst, &sst);
  int result;
  if (sst == MSK_SOL_STA_OPTIMAL || sst == MSK_SOL_STA_NEAR_OPTIMAL) {
    //success, we have an optimal problem
    if (sst == MSK_SOL_STA_OPTIMAL) {DBGP("QP solution is optimal");}
    else {DBGA("QP solution is *nearly* optimal");}
    result = 0;
  } else if (sst == MSK_SOL_STA_PRIM_INFEAS_CER) {
    //unfeasible problem
    DBGP("Mosek optimization: primal infeasible");
    result = 1;
  } else if (sst == MSK_SOL_STA_DUAL_INFEAS_CER) {
    //unfeasible problem
    DBGA("Mosek optimization: dual infeasible (primal unbounded?)");
    result = 1;
  } else if (sst == MSK_SOL_STA_PRIM_AND_DUAL_FEAS) {
    //i think this means feasible problem, but unbounded solution
    //this shouldn't happen as our Q is positive semidefinite
    DBGA("QP solution is prim and dual feasible, but not optimal");
    DBGA("Is Q positive semidefinite?");
    result = -1;
  } else {
    //unknown return status
    DBGA("QP fails with solution status " << sst << " and problem status " << pst);
    result = -1;
  }

  //MSK_SOL_STA_DUAL_FEAS;

  //retrieve the solutions
  if (!result) {
    //get the value of the objective function
    MSKrealt obj, foo;
    MSK_getsolutioninf(task, MSK_SOL_ITR, &pst, &sst, &obj,
                       &foo, &foo, &foo, &foo, &foo, &foo, &foo, &foo);
    if (objType == MOSEK_OBJ_QP) {
      *objVal = obj * scale * scale;
    } else if (objType == MOSEK_OBJ_LP) {
      *objVal = obj * scale;
    } else {
      assert(0);
    }
    double *xx = new double[sol.rows()];
    MSK_getsolutionslice(task, MSK_SOL_ITR, MSK_SOL_ITEM_XX,
                         0, sol.rows(), xx);
    for (i = 0; i < sol.rows(); i++) {
      sol.elem(i, 0) = scale * xx[i];
      DBGP("x" << i << ": " << xx[i]);
    }
    delete [] xx;
  }
  MSK_deletetask(&task);
  return result;
}
int main(int argc,char *argv[])
{
  const MSKint32t numvar = 3, 
                  numcon = 3;
  MSKint32t       i,j;
  double          c[]    = {1.5, 2.5, 3.0};
  MSKint32t       ptrb[] = {0, 3, 6},
                  ptre[] = {3, 6, 9},
                  asub[] = { 0, 1, 2,
                             0, 1, 2,
                             0, 1, 2};
  
  double          aval[] = { 2.0, 3.0, 2.0,
                             4.0, 2.0, 3.0,
                             3.0, 3.0, 2.0};
 
  MSKboundkeye    bkc[]  = {MSK_BK_UP, MSK_BK_UP, MSK_BK_UP    };
  double          blc[]  = {-MSK_INFINITY, -MSK_INFINITY, -MSK_INFINITY};
  double          buc[]  = {100000, 50000, 60000};
  
  MSKboundkeye    bkx[]  = {MSK_BK_LO,     MSK_BK_LO,    MSK_BK_LO};
  double          blx[]  = {0.0,           0.0,          0.0,};
  double          bux[]  = {+MSK_INFINITY, +MSK_INFINITY,+MSK_INFINITY};
  
  double          *xx=NULL;               
  MSKenv_t        env;
  MSKtask_t       task;
  MSKint32t       varidx,conidx; 
  MSKrescodee     r;

  /* Create the mosek environment. */
  r = MSK_makeenv(&env,NULL);

  if ( r==MSK_RES_OK )
  {
    /* Create the optimization task. */
    r = MSK_maketask(env,numcon,numvar,&task);

    /* Directs the log task stream to the 
       'printstr' function. */

    MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
          
    /* Append the constraints. */
    if (r == MSK_RES_OK)
      r = MSK_appendcons(task,numcon);

    /* Append the variables. */
    if (r == MSK_RES_OK)
      r = MSK_appendvars(task,numvar);

    /* Put C. */
    if (r == MSK_RES_OK)
      r = MSK_putcfix(task, 0.0);

    if (r == MSK_RES_OK)
      for(j=0; j<numvar; ++j)
        r = MSK_putcj(task,j,c[j]);

    /* Put constraint bounds. */
    if (r == MSK_RES_OK)
      for(i=0; i<numcon; ++i)
        r = MSK_putconbound(task,i,bkc[i],blc[i],buc[i]);

    /* Put variable bounds. */
    if (r == MSK_RES_OK)
      for(j=0; j<numvar; ++j)
        r = MSK_putvarbound(task,j,bkx[j],blx[j],bux[j]);
                    
    /* Put A. */
    if (r == MSK_RES_OK)
      if ( numcon>0 )
        for(j=0; j<numvar; ++j)
          r = MSK_putacol(task,
                          j,
                          ptre[j]-ptrb[j],
                          asub+ptrb[j],
                          aval+ptrb[j]);
           
    if (r == MSK_RES_OK)
      r = MSK_putobjsense(task,
                          MSK_OBJECTIVE_SENSE_MAXIMIZE);

    if (r == MSK_RES_OK)
      r = MSK_optimizetrm(task,NULL);

    if (r == MSK_RES_OK)
    {
      xx = calloc(numvar,sizeof(double));
      if ( !xx )
        r = MSK_RES_ERR_SPACE;
    }

    if (r == MSK_RES_OK)
      r = MSK_getxx(task,
                    MSK_SOL_BAS,       /* Basic solution.       */
                    xx);
    
/* Make a change to the A matrix */
    if (r == MSK_RES_OK)
      r = MSK_putaij(task, 0, 0, 3.0);
    if (r == MSK_RES_OK)
      r = MSK_optimizetrm(task,NULL);

    /* Get index of new variable, this should be 3 */
    if (r == MSK_RES_OK)
      r = MSK_getnumvar(task,&varidx);

    /* Append a new variable x_3 to the problem */
    if (r == MSK_RES_OK)
      r = MSK_appendvars(task,1);
    
    /* Set bounds on new variable */
    if (r == MSK_RES_OK)
      r = MSK_putvarbound(task,
                          varidx,
                          MSK_BK_LO,
                          0,
                          +MSK_INFINITY);
    
    /* Change objective */
    if (r == MSK_RES_OK)
      r = MSK_putcj(task,varidx,1.0);
    
    /* Put new values in the A matrix */
    if (r == MSK_RES_OK)
    {
      MSKint32t acolsub[] = {0,   2};
      double    acolval[] =  {4.0, 1.0};
      
       r = MSK_putacol(task,
                       varidx, /* column index */
                       2, /* num nz in column*/
                       acolsub,
                       acolval);
    }
    
    /* Change optimizer to free simplex and reoptimize */
    if (r == MSK_RES_OK)
      r = MSK_putintparam(task,MSK_IPAR_OPTIMIZER,MSK_OPTIMIZER_FREE_SIMPLEX);
    
    if (r == MSK_RES_OK)
      r = MSK_optimizetrm(task,NULL);

    /* Get index of new constraint*/
    if (r == MSK_RES_OK)
      r = MSK_getnumcon(task,&conidx);

    /* Append a new constraint */
    if (r == MSK_RES_OK)
      r = MSK_appendcons(task,1);
    
    /* Set bounds on new constraint */
    if (r == MSK_RES_OK)
      r = MSK_putconbound(task,
                          conidx,
                          MSK_BK_UP,
                          -MSK_INFINITY,
                          30000);

    /* Put new values in the A matrix */
    if (r == MSK_RES_OK)
    {
      MSKidxt arowsub[] = {0,   1,   2,   3  };
      double arowval[] =  {1.0, 2.0, 1.0, 1.0};
      
      r = MSK_putarow(task,
                      conidx, /* row index */
                      4,      /* num nz in row*/
                      arowsub,
                      arowval);
    }
    if (r == MSK_RES_OK)
      r = MSK_optimizetrm(task,NULL);

    if ( xx )
      free(xx);
    
    MSK_deletetask(&task);
  }
  MSK_deleteenv(&env);

  printf("Return code: %d (0 means no error occured.)\n",r);

  return ( r );
} /* main */
예제 #4
0
int main(int argc,char **argv)
{
  MSKintt   r=MSK_RES_OK,i;
  MSKenv_t  env = NULL;
  MSKtask_t task = NULL;
  MSKtask_t task_list[NUMTASKS];

  /* Ensure that we can delete tasks even if they are not allocated */
  task_list[0] = NULL;

  /* Create mosek environment. */
  r = MSK_makeenv(&env,NULL); 
  
  /* Create a task for each concurrent optimization.
     The 'task' is the master task that will hold the problem data.
  */ 

  if ( r==MSK_RES_OK )
    r = MSK_maketask(env,0,0,&task);

  if (r == MSK_RES_OK)
    r = MSK_maketask(env,0,0,&task_list[0]); 
     
  /* Assign call-back functions to each task */

  if (r == MSK_RES_OK)
    MSK_linkfunctotaskstream(task,
                             MSK_STREAM_LOG,
                             NULL,
                             printstr1);

  if (r == MSK_RES_OK)
    MSK_linkfunctotaskstream(task_list[0],
                             MSK_STREAM_LOG,
                             NULL,
                             printstr2);

  if (r == MSK_RES_OK)
     r = MSK_linkfiletotaskstream(task,
                                  MSK_STREAM_LOG,
                                  "simplex.log",
                                  0);

   if (r == MSK_RES_OK)
     r = MSK_linkfiletotaskstream(task_list[0],
                                  MSK_STREAM_LOG,
                                  "intpnt.log",
                                  0);


  if (r == MSK_RES_OK)
    r = MSK_readdata(task,argv[1]);

  /* Assign different parameter values to each task.
     In this case different optimizers. */

  if (r == MSK_RES_OK)
    r = MSK_putintparam(task,
                        MSK_IPAR_OPTIMIZER,
                        MSK_OPTIMIZER_PRIMAL_SIMPLEX);

  if (r == MSK_RES_OK)
    r = MSK_putintparam(task_list[0],
                        MSK_IPAR_OPTIMIZER,
                        MSK_OPTIMIZER_INTPNT);


  /* Optimize task and task_list[0] in parallel.
     The problem data i.e. C, A, etc.
     is copied from task to task_list[0].
   */

  if (r == MSK_RES_OK)
    r = MSK_optimizeconcurrent (task,
                                task_list,
                                NUMTASKS);

  printf ("Return Code = %d\n",r);

  MSK_solutionsummary(task,
                      MSK_STREAM_LOG);

  MSK_deletetask(&task);
  MSK_deletetask(&task_list[0]);
  MSK_deleteenv(&env);

  return r;
}
예제 #5
0
template <typename _Scalar> typename MosekOpt<_Scalar>::ReturnType
MosekOpt<_Scalar>::
update( bool verbose )
{
    if ( _task != NULL )
    {
        std::cerr << "[" << __func__ << "]: " << "update can only be called once! returning." << std::endl;
        return MSK_RES_ERR_UNKNOWN;
    }

    /* Create the optimization task. */
    if ( MSK_RES_OK == _r )
    {
        _r = MSK_maketask( _env, this->getConstraintCount(), this->getVarCount(), &_task );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not create task with " << this->getVarCount() << " vars, and " << this->getConstraintCount() << " constraints" << std::endl;
    }

    // redirect output
    if ( MSK_RES_OK == _r )
    {
        _r = MSK_linkfunctotaskstream( _task, MSK_STREAM_LOG, NULL, mosekPrintStr );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not create rewire output to mosekPrintStr(), continuing though..." << std::endl;
    }

    // Append _numCon empty constraints. The constraints will initially have no bounds.
    if ( MSK_RES_OK == _r )
    {
        if ( verbose ) std::cout << "my: MSK_appendcons(_task,"<< this->getConstraintCount() <<");" << std::endl;
        _r = MSK_appendcons( _task, this->getConstraintCount() );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not append " << this->getConstraintCount() << " constraints" << std::endl;
    }

    // Append _numVar variables. The variables will initially be fixed at zero (x=0).
    if ( MSK_RES_OK == _r )
    {
        if ( verbose ) std::cout << "my: MSK_appendvars(_task," << this->getVarCount() <<");" << std::endl;
        _r = MSK_appendvars( _task, this->getVarCount() );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not append " << this->getVarCount() << " variables" << std::endl;
    }

    // Optionally add a constant term to the objective.
    if ( MSK_RES_OK == _r )
    {
        if ( verbose ) std::cout << "my: MSK_putcfix(_task," << this->getObjectiveBias() << ");" << std::endl;
        _r = MSK_putcfix( _task, this->getObjectiveBias() );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not add constant " << this->getObjectiveBias() << " to objective function" << std::endl;
    }

    // set Variables
    for ( size_t j = 0; (j < this->getVarCount()) && (MSK_RES_OK == _r); ++j )
    {
        // set Variable j's Bounds // blx[j] <= x_j <= bux[j]
        if ( MSK_RES_OK == _r )
        {
            _r = MSK_putvarbound( _task,
                                  j,                                                     /* Index of variable.*/
                                  MosekOpt<Scalar>::getBoundTypeCustom( this->getVarBoundType(j) ), /* Bound key.*/
                                  this->getVarLowerBound(j),                             /* Numerical value of lower bound.*/
                                  this->getVarUpperBound(j) );                           /* Numerical value of upper bound.*/

            if ( verbose ) std::cout << "my: MSK_putvarbound(_task," << j << "," << this->getVarBoundType(j) << "," << this->getVarLowerBound(j) << "," << this->getVarUpperBound(j) << ");" << std::endl;
        }

        // set Variable j's Type
        if ( MSK_RES_OK == _r )
        {
            _r = MSK_putvartype( _task, j, MosekOpt<Scalar>::getVarTypeCustom(this->getVarType(j)) );
        }

        // set Variable j's linear coefficient in the objective function
        if ( MSK_RES_OK == _r )
        {
            if ( verbose ) std::cout << "my: putcj(_task," << j << "," << this->getLinObjectives()[j] << ")" << std::endl;
            _r = MSK_putcj( _task, j, this->getLinObjectives()[j] );
        }
    }

    // set Quadratic Objectives
    if ( MSK_RES_OK == _r )
    {
        const int numNonZeros = this->getQuadraticObjectives().size();
        MSKint32t *qsubi = new MSKint32t[numNonZeros],
                  *qsubj = new MSKint32t[numNonZeros];
        double    *qval  = new double[numNonZeros];

        for ( size_t qi = 0; qi != this->getQuadraticObjectives().size(); ++qi )
        {
            qsubi[qi] = this->getQuadraticObjectives()[qi].row();
            qsubj[qi] = this->getQuadraticObjectives()[qi].col();
            qval [qi] = this->getQuadraticObjectives()[qi].value();
        }

        if ( verbose ) std::cout<<"my: putqobj( _task, " << numNonZeros << ",\n";
        for ( size_t vi = 0; vi != numNonZeros; ++vi )
        {
            if ( verbose ) std::cout << qsubi[vi] << "," << qsubj[vi] << ", " << qval[vi] << std::endl;
        }
        if ( verbose ) std::cout << ");" << std::endl;

        _r = MSK_putqobj( _task, numNonZeros, qsubi, qsubj, qval );

        if ( qsubi ) { delete[] qsubi; qsubi = NULL; }
        if ( qsubj ) { delete[] qsubj; qsubj = NULL; }
        if ( qval  ) { delete[] qval ; qval  = NULL; }

        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "Setting Quadratic Objectives caused error code " << (int)_r << std::endl;
    } // ...Quadratic objective

    // set Linear Constraints
    {
        typename ParentType::SparseMatrix A( this->getLinConstraintsMatrix() );
//        ( this->getConstraintCount(), this->getVarCount() );
//        A.setFromTriplets( this->getLinConstraints().begin(), this->getLinConstraints().end() );
        std::vector<double>         aval;                // Linear constraints coeff matrix (sparse)
        std::vector<int>            asub;                // Linear constraints coeff matrix indices
        std::vector<int>            aptrb, aptre;
        for ( int row = 0; (row < A.outerSize()) && (MSK_RES_OK == _r); ++row )
        {
            // set Constraint Bounds for row
            if ( MSK_RES_OK == _r )
            {
                if ( verbose ) std::cout << "my: MSK_putconbound( _task, " << row << ", "
                                         << MosekOpt<Scalar>::getBoundTypeCustom( this->getConstraintBoundType(row) ) << ", "
                                         << this->getConstraintLowerBound( row ) << ", "
                                         << this->getConstraintUpperBound( row ) << ")"
                                         << std::endl; fflush( stdout );

                _r = MSK_putconbound( _task,
                                      row,                                                          /* Index of constraint.*/
                                      MosekOpt<Scalar>::getBoundTypeCustom(this->getConstraintBoundType(row)), /* Bound key.*/
                                      this->getConstraintLowerBound(row),                           /* Numerical value of lower bound.*/
                                      this->getConstraintUpperBound(row) );                         /* Numerical value of upper bound.*/
            }

            // set Linear Constraint row
            if ( MSK_RES_OK == _r )
            {
                // new line starts at index == current size
                aptrb.push_back( aval.size() );
                // add coeffs from new line
                for ( typename ParentType::SparseMatrix::InnerIterator it(A,row); it; ++it )
                {
                    if ( row != it.row() ) std::cerr << "[" << __func__ << "]: " << "this shouldn't happen" << std::endl;
                    // coeff value
                    aval.push_back( it.value() );  // TODO: A should be a matrix, not a vector...
                    // coeff subscript
                    asub.push_back( it.col() );
                }
                // new line ends at index == new size
                aptre.push_back( aval.size() );

                if ( verbose ) {
                    std::cout << "my: MSK_putarow( _task, "
                              << row << ", "
                              << aptre[row] - aptrb[row] << ", "
                              << *(asub.data() + aptrb[row]) << ", "
                              << *(aval.data() + aptrb[row]) << ");"
                              << std::endl; fflush( stdout );
                }

                _r = MSK_putarow( _task,
                                  row,                 /* Row index.*/
                                  aptre[row] - aptrb[row], /* Number of non-zeros in row i.*/
                                  asub.data() + aptrb[row],     /* Pointer to column indexes of row i.*/
                                  aval.data() + aptrb[row]);    /* Pointer to values of row i.*/
            }
        } // ... for A.rows

        // report error
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "Setting Lin constraints caused error code " << (int)_r << std::endl;
    } // ...set Linear Constraints

    // set Quadratic constraints
    if ( verbose ) std::cout << "[" << __func__ << "]: " << "adding q constraints" << std::endl;
    for ( size_t constr_id = 0; (constr_id != this->getQuadraticConstraints().size()) && (MSK_RES_OK == _r); ++constr_id )
    {
        const int numNonZeros = this->getQuadraticConstraints(constr_id).size();

        MSKint32t *qsubi = new MSKint32t[numNonZeros],
                  *qsubj = new MSKint32t[numNonZeros];
        double    *qval  = new double[numNonZeros];

        for ( size_t qi = 0; qi != this->getQuadraticConstraints(constr_id).size(); ++qi )
        {
            qsubi[qi] = this->getQuadraticConstraints(constr_id)[qi].row();
            qsubj[qi] = this->getQuadraticConstraints(constr_id)[qi].col();
            qval [qi] = this->getQuadraticConstraints(constr_id)[qi].value();
        }

        if ( verbose ) std::cout<<"my: MSK_putqonk( _task, " << constr_id << ", " << numNonZeros << ",\n";
        for(size_t vi=0;vi!=numNonZeros;++vi)
        {
            if ( verbose ) std::cout << qsubi[vi] << "," << qsubj[vi] << ", " << qval[vi] << std::endl;
        }
        if ( verbose ) std::cout << "); " << std::endl;

        _r = MSK_putqconk(_task,
                          constr_id,
                          numNonZeros,
                          qsubi,
                          qsubj,
                          qval);

        if ( qsubi ) { delete[] qsubi; qsubi = NULL; }
        if ( qsubj ) { delete[] qsubj; qsubj = NULL; }
        if ( qval  ) { delete[] qval ; qval  = NULL; }

        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "Setting Quad constraints caused error code " << (int)_r << std::endl;
    } // ...set Quadratic Constraints

    // save to file
    {
        if ( _r == MSK_RES_OK )
        {
            _r = MSK_putintparam( _task, MSK_IPAR_WRITE_DATA_FORMAT, MSK_DATA_FORMAT_LP );
            if ( _r == MSK_RES_OK )
            {
                _r = MSK_writedata( _task, "mosek.lp" );
                if ( _r != MSK_RES_OK )
                {
                    std::cerr << "[" << __func__ << "]: " << "Writedata did not work" << (int)_r << std::endl;
                }
            }
        }
    }

    if ( _r == MSK_RES_OK )
    {
        this->_x.setZero();
        this->_updated = true;
    }

    // return error code
    return _r;
} // ...MosekOpt::update()
예제 #6
0
template <typename _Scalar> typename MosekOpt<_Scalar>::ReturnType
MosekOpt<_Scalar>::optimize( std::vector<_Scalar> *x_out, OBJ_SENSE objective_sense )
{
    if ( !this->_updated )
    {
        std::cerr << "[" << __func__ << "]: " << "Please call update() first!" << std::endl;
        return MSK_RES_ERR_UNKNOWN;
    }

    // cache problem size
    const int numvar = this->getVarCount();

    // determine problem type
    MSKobjsense_enum objsense = (objective_sense == OBJ_SENSE::MINIMIZE) ? MSK_OBJECTIVE_SENSE_MINIMIZE
                                                                         : MSK_OBJECTIVE_SENSE_MAXIMIZE;
    if ( MSK_RES_OK == _r )
        _r = MSK_putobjsense( _task, objsense );

    if ( MSK_RES_OK == _r  )
    {
        // set termination sensitivity
        MSKrescodee trmcode;
        if ( (_r == MSK_RES_OK) && (this->getTolRelGap() > Scalar(0)) )
        {
            _r = MSK_putdouparam( _task, MSK_DPAR_MIO_TOL_REL_GAP, this->getTolRelGap() /*1e-10f*/ );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_DPAR_MIO_DISABLE_TERM_TIME to " << this->getTimeLimit() << " did NOT work!" << std::endl;
            }
        }


        if ( (_r == MSK_RES_OK) && (this->getTimeLimit() > Scalar(0)) )
        {
            _r = MSK_putdouparam(_task, MSK_DPAR_MIO_DISABLE_TERM_TIME, this->getTimeLimit() );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_DPAR_MIO_DISABLE_TERM_TIME to " << this->getTimeLimit() << " did NOT work!" << std::endl;
            }
            _r = MSK_putdouparam(_task, MSK_DPAR_MIO_MAX_TIME, this->getTimeLimit()+Scalar(5) );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_DPAR_MIO_MAX_TIME to " << this->getTimeLimit()+Scalar(5) << " did NOT work!" << std::endl;
            }
        }

        if (_r == MSK_RES_OK)
        {
            //_r = MSK_putintparam(_task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_MIXED_INT_CONIC );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_OPTIMIZER_MIXED_INT_CONIC did not work!" << std::endl;
            }
        }

        if ( _r == MSK_RES_OK )
        {
            _r = MSK_putintparam( _task, MSK_IPAR_MIO_PRESOLVE_USE, MSK_ON );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_IPAR_MIO_PRESOLVE_USE did not work!" << std::endl;
            }
        }

        if ( _r == MSK_RES_OK )
        {
            _r = MSK_putintparam( _task, MSK_IPAR_MIO_HEURISTIC_LEVEL, 5 );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_IPAR_MIO_HEURISTIC_LEVEL did not work!" << std::endl;
            }
        }

        // Run optimizer
        _r = MSK_optimizetrm( _task, &trmcode );

        // Print a summary containing information about the solution for debugging purposes.
        MSK_solutionsummary( _task, MSK_STREAM_LOG );

        // save solution
        double *xx = (double*) calloc(numvar,sizeof(double));
        if ( _r == MSK_RES_OK )
        {
            MSKsolstae solsta;

            if ( _r == MSK_RES_OK )
            {
                _r = MSK_getsolsta( _task, MSK_SOL_ITR, &solsta );
                if ( _r != MSK_RES_OK )
                {
                    _r = MSK_getsolsta( _task, MSK_SOL_ITG, &solsta );
                }
                if ( _r != MSK_RES_OK )
                {
                    std::cerr << "[" << __func__ << "]: " << "neithter MSK_SOL_ITR, nor MSK_SOL_ITR worked" << std::endl;
                }
            }

            switch ( solsta )
            {
                case MSK_SOL_STA_OPTIMAL:
                case MSK_SOL_STA_NEAR_OPTIMAL:
                {
                    if ( xx )
                    {
                        MSK_getxx(_task,
                                  MSK_SOL_ITR,    /* Request the basic solution. */
                                  xx);

                        _storeSolution( xx, numvar );
                        printf("Optimal primal solution\n");
                    }
                    else
                    {
                        _r = MSK_RES_ERR_SPACE;
                    }
                    break;
                }

                case MSK_SOL_STA_DUAL_INFEAS_CER:
                case MSK_SOL_STA_PRIM_INFEAS_CER:
                case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
                case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
                    printf("Primal or dual infeasibility certificate found.\n");
                    break;
                case MSK_SOL_STA_UNKNOWN:
                {
                    MSKprostae prosta;
                    MSK_getprosta(_task,MSK_SOL_ITG,&prosta);
                    switch (prosta)
                    {
                        case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
                            printf("Problem status Infeasible or unbounded\n");
                            break;
                        case MSK_PRO_STA_PRIM_INFEAS:
                            printf("Problem status Infeasible.\n");
                            break;
                        case MSK_PRO_STA_UNKNOWN:
                            printf("Problem status unknown.\n");
                            break;
                        default:
                            printf("Other problem status.");
                            break;
                    }
                    char symname[MSK_MAX_STR_LEN];
                    char desc[MSK_MAX_STR_LEN];

                    /* If the solutions status is unknown, print the termination code
               indicating why the optimizer terminated prematurely. */

                    MSK_getcodedesc(trmcode,
                                    symname,
                                    desc);

                    printf("The solutuion status is unknown.\n");
                    printf("The optimizer terminitated with code: %s\n",symname);
                    break;
                }
                    // ITG
                    //asdf todo: consolidate this last part:
                case MSK_SOL_STA_INTEGER_OPTIMAL:
                case MSK_SOL_STA_NEAR_INTEGER_OPTIMAL :
                    MSK_getxx(_task,
                              MSK_SOL_ITG,    /* Request the integer solution. */
                              xx);
                    _storeSolution( xx, numvar );
                    printf("Optimal integer solution.\n");

                    break;

                case MSK_SOL_STA_PRIM_FEAS:
                    /* A feasible but not necessarily optimal solution was located. */
                    MSK_getxx(_task,MSK_SOL_ITG,xx);
                    _storeSolution( xx, numvar );
                    printf("Feasible solution.\n");
                    break;

                default:
                    std::cerr << "[" << __func__ << "]: " << "unknown code " << (int)solsta << std::endl;
                    break;
            }

            if ( xx ) { free(xx); xx = NULL; }
        }
    }

    if ( MSK_RES_OK != _r )
    {
        /* In case of an error print error code and description. */
        char symname[MSK_MAX_STR_LEN];
        char desc[MSK_MAX_STR_LEN];

        printf("An error occurred while optimizing.\n");
        MSK_getcodedesc( _r,
                         symname,
                         desc);
        printf("Error %s - '%s'\n",symname,desc);
    }
    else
    {
        // output
        if ( x_out )
        {
            x_out->clear();
            x_out->reserve( this->_x.size() );
            for ( int j=0; j < this->_x.size(); ++j )
            {
                x_out->push_back( this->_x[j] );
            }
        }
    }

    return _r;
} // ...MosekOpt::optimize()
예제 #7
0
int main(int argc,char *argv[])
{
  MSKrescodee
    r;
  MSKboundkeye
    bkc[NUMCON],bkx[NUMVAR];
  int 
    j,i,
    ptrb[NUMVAR],ptre[NUMVAR],sub[NUMANZ];
  double
    blc[NUMCON],buc[NUMCON],
    c[NUMVAR],blx[NUMVAR],bux[NUMVAR],val[NUMANZ],
    xx[NUMVAR];
  MSKenv_t  env;
  MSKtask_t task;

  /* Make mosek environment. */
  r = MSK_makeenv(&env,NULL,NULL,NULL,NULL); 

  /* Check is return code is ok. */
  if ( r==MSK_RES_OK )
  {
    /* Directs the env log stream to the user
       specified procedure 'printstr'. */
       
    MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,printstr);
  }

  /* Initialize the environment. */   
  r = MSK_initenv(env);

  if ( r==MSK_RES_OK )
  {  
    /* Send a message to the MOSEK Message stream. */
    MSK_echoenv(env,
                MSK_STREAM_MSG,
                "\nMaking the MOSEK optimization task\n");

    /* Make the optimization task. */
    r = MSK_maketask(env,NUMCON,NUMVAR,&task);

    if ( r==MSK_RES_OK )
    {
      /* Directs the log task stream to the user
         specified procedure 'printstr'. */

      MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);

      MSK_echotask(task,
                   MSK_STREAM_MSG,
                   "\nDefining the problem data.\n");

      /* Define bounds for the constraints. */

      /* Constraint: 0 */
      bkc[0] = MSK_BK_FX;  /* Type of bound. */
      blc[0] = 30.0;       /* Lower bound on the
                              constraint. */
      buc[0] = 30.0;       /* Upper bound on the
                              constraint. */

      /* Constraint: 1 */
      bkc[1] = MSK_BK_LO;
      blc[1] = 15.0;
      buc[1] = MSK_INFINITY;

      /* Constraint: 2 */
      bkc[2] = MSK_BK_UP;
      blc[2] = -MSK_INFINITY;
      buc[2] = 25.0;

      /* Define information for the variables. */

      /* Variable: x0 */
      c[0]    = 3.0;              /* The objective function. */

      ptrb[0] = 0;  ptre[0] = 2;  /* First column in
                                     the constraint matrix. */
      sub[0]  = 0;  val[0]  = 3.0;
      sub[1]  = 1;  val[1]  = 2.0;

      bkx[0]  = MSK_BK_LO;        /* Type of bound. */
      blx[0]  = 0.0;              /* Lower bound on the
                                     variables. */
      bux[0]  = MSK_INFINITY;     /* Upper bound on the
                                     variables.  */

      /* Variable: x1 */
      c[1]    = 1.0;

      ptrb[1] = 2;  ptre[1] = 5;
      sub[2]  = 0;  val[2]  = 1.0;
      sub[3]  = 1;  val[3]  = 1.0;
      sub[4]  = 2;  val[4]  = 2.0;

      bkx[1]  = MSK_BK_RA;
      blx[1]  = 0.0;
      bux[1]  = 10;


      /* Variable: x2 */
      c[2]    = 5.0;

      ptrb[2] = 5;  ptre[2] = 7;
      sub[5]  = 0;  val[5]  = 2.0;
      sub[6]  = 1;  val[6]  = 3.0;

      bkx[2]  = MSK_BK_LO;
      blx[2]  = 0.0;
      bux[2]  = MSK_INFINITY;

      /* Variable: x3 */
      c[3]    = 1.0;

      ptrb[3] = 7;  ptre[3] = 9;
      sub[7]  = 1;  val[7]  = 1.0;
      sub[8]  = 2;  val[8]  = 3.0;

      bkx[3]  = MSK_BK_LO;
      blx[3]  = 0.0;
      bux[3]  = MSK_INFINITY;

      MSK_putobjsense(task,
                      MSK_OBJECTIVE_SENSE_MAXIMIZE);

      /* Use the primal simplex optimizer. */
      MSK_putintparam(task,
                      MSK_IPAR_OPTIMIZER,
                      MSK_OPTIMIZER_PRIMAL_SIMPLEX);


      MSK_echotask(task,
                   MSK_STREAM_MSG,
                   "\nAdding constraints\n");
    
      r = MSK_append(task,
                     MSK_ACC_CON,
                     NUMCON);
   
      /* Adding bounds on empty constraints */
      for(i=0; r==MSK_RES_OK && i<NUMCON; ++i)
      {
        r = MSK_putbound(task,
                         MSK_ACC_CON,
                         i,
                         bkc[i], 
                         blc[i], 
                         buc[i]);
                         
      }

      /* Dynamically adding columns */
      for(j= 0; r==MSK_RES_OK && j<NUMVAR; ++j)
      {
        MSK_echotask(task,
                     MSK_STREAM_MSG,
                     "\nAdding a new variable.\n");

        r = MSK_append(task,MSK_ACC_VAR,1);

        if ( r==MSK_RES_OK )
          r = MSK_putcj(task,j,c[j]); 
                   
        if ( r==MSK_RES_OK )
          r = MSK_putavec(task,
                          MSK_ACC_VAR,
                          j,
                          ptre[j]-ptrb[j],
                          sub+ptrb[j],
                          val+ptrb[j]); 

        if ( r==MSK_RES_OK )
          r = MSK_putbound(task,
                           MSK_ACC_VAR,
                           j,
                           bkx[j], 
                           blx[j], 
                           bux[j]);
                             
        if(  r == MSK_RES_OK )
        {                            
          MSK_echotask(task,
                       MSK_STREAM_MSG,
                      "\nOptimizing\n");
                                                                        
          r = MSK_optimize(task);

          MSK_solutionsummary(task,MSK_STREAM_MSG);        
        }
      }

      MSK_deletetask(&task);
    }
  }
  MSK_deleteenv(&env);

  printf("Return code: %d (0 means no error occured.)\n",r);

  return ( r );
} /* main */