示例#1
0
int wctlp_setbound(wctlp *lp, int col, char lb_or_ub, double bound) {
    int val = 0;

    if (lb_or_ub == 'L') {
        val = GRBsetdblattrelement(lp->model, GRB_DBL_ATTR_LB, col, bound);
    } else {
        val = GRBsetdblattrelement(lp->model, GRB_DBL_ATTR_UB, col, bound);
    }

    CHECK_VAL_GRB(val, "Failed to set bound", lp->env);
    val = GRBupdatemodel(lp->model);
    CHECK_VAL_GRB(val, "Failed to update model", lp->env);
    return val;
}
示例#2
0
int engine(int numassets, int numfactors, 
	     double *ub, double *lb, double *mu, double *sigma2, 
	   double *V, double *F, double lambda)
{
  int retcode = 0;
  GRBenv   *env = NULL;
  GRBmodel *model = NULL;
  int n, i, j, k;
  double *x;
  int *qrow, *qcol, Nq;
  double *qval;
  int *cind;
  double rhs;
  char sense;
  double *cval;
  int numnonz;
  char **names, bigname[100];
  double expectedreturnval;

  printf("running solver engine\n");

  n = numassets + numfactors;

  retcode = GRBloadenv(&env, "engine.log");
  if (retcode) goto BACK;

 /* Create initial model */
  retcode = GRBnewmodel(env, &model, "factors", n, 
                      NULL, NULL, NULL, NULL, NULL);
  if (retcode) goto BACK;

  names = (char **) calloc(n, sizeof(char *));

  /** next we create the remaining attributes for the n columns **/
  x     = (double *) calloc (n, sizeof(double));

  for(j = 0; j < numassets; j++){
    names[j] = (char *)calloc(3, sizeof(char));
    if(names[j] == NULL){
      retcode = 1; goto BACK;
    }
    sprintf(names[j],"x%d", j);
  }
  for(j = numassets; j < numassets + numfactors; j++){
    names[j] = (char *)calloc(3, sizeof(char));
    if(names[j] == NULL){
		  retcode = 1; goto BACK;
    }
    sprintf(names[j],"F%d", j - numassets);
  }


  /* initialize variables */
  for(j = 0; j < n; j++){
    retcode = GRBsetstrattrelement(model, "VarName", j, names[j]);
    if (retcode) goto BACK;

    retcode = GRBsetdblattrelement(model, "Obj", j, -mu[j]);
    if (retcode) goto BACK;

    retcode = GRBsetdblattrelement(model, "LB", j, lb[j]);
    if (retcode) goto BACK;

    retcode = GRBsetdblattrelement(model, "UB", j, ub[j]);
    if (retcode) goto BACK;

  }

  /** next, the quadratic -- there are numassets + numfactors*numfactors nonzeroes: 
      numassets residual variances plus the numfactors x numfactors
      factor covariance matrix**/

  Nq = numassets + numfactors*numfactors;
  qrow = (int *) calloc(Nq, sizeof(int));  /** row indices **/
  qcol = (int *) calloc(Nq, sizeof(int));  /** column indices **/
  qval = (double *) calloc(Nq, sizeof(double));  /** values **/

  if( ( qrow == NULL) || ( qcol == NULL) || (qval == NULL) ){
    printf("could not create quadratic\n");
    retcode = 1; goto BACK;
  }

  for (j = 0; j < numassets; j++){
    qval[j] = lambda*sigma2[j];
    qrow[j] = qcol[j] = j;
  }
  for (i = 0; i < numfactors; i++){
    for (j = 0; j < numfactors; j++){
      k = i*numfactors + j;
      qval[k + numassets] = lambda*F[k];
      qrow[k + numassets] = numassets + i;
      qcol[k + numassets] = numassets + j;
    }
  }
  retcode = GRBaddqpterms(model, Nq, qrow, qcol, qval);
  if (retcode) goto BACK;

  /** now we will add one constraint at a time **/
  /** we need to have a couple of auxiliary arrays **/

  cind = (int *)calloc(n, sizeof(int));  /** n is over the top since no constraint is totally dense;		     but it's not too bad here **/
  cval= (double *)calloc(n, sizeof(double));
  if(!cval){
    printf("cannot allocate cval\n"); retcode = 2; goto BACK;
  }
  for(i = 0; i < numfactors; i++){
    for(j = 0; j < numassets; j++){
      cval[j] = V[i*numassets + j];
      cind[j] = j;
    }
    cind[numassets] = /* j */ numassets + i;
    cval[numassets] = -1;
    numnonz = numassets + 1;
    rhs = 0;
    sense = GRB_EQUAL;

    sprintf(bigname,"factor%d",i);
    retcode = GRBaddconstr(model, numnonz, cind, cval, sense, rhs, bigname);
    if (retcode) goto BACK;

  }

  /** sum of x variables = 1 **/


  for (j = 0; j < numassets; j++){
    cval[j] = 1.0;  cind[j] = j;
  }

  numnonz = numassets;
  rhs = 1.0;
  sense = GRB_EQUAL;

  /* let's reuse some space */
  sprintf(bigname, "sum");

  retcode = GRBaddconstr(model, numnonz, cind, cval, sense, rhs, bigname);
  if (retcode) goto BACK;

  retcode = GRBupdatemodel(model);
  if (retcode) goto BACK;

  /** optional: write the problem **/

  retcode = GRBwrite(model, "engine.lp");
  if (retcode) goto BACK;


  retcode = GRBoptimize(model);
  if (retcode) goto BACK;


  /** get solution **/


  retcode = GRBgetdblattrarray(model,
                               GRB_DBL_ATTR_X, 0, n,
                               x);
  if(retcode) goto BACK;

  /** now let's see the values **/

  expectedreturnval = 0;
  for(j = 0; j < numassets; j++){
    if( x[j] > 1.0e-09){
      printf("%s = %g\n", names[j], x[j]);
      expectedreturnval += x[j]*mu[j];
    }
  }

  printf("\n*** expected portfolio return: %g\n", expectedreturnval);

  GRBfreemodel(model);
  GRBfreeenv(env);



 BACK:
  printf("engine exits with code %d\n", retcode);
  return retcode;
}
示例#3
0
int
main(int   argc,
     char *argv[])
{
  GRBenv   *env   = NULL, *modelenv = NULL;
  GRBmodel *model = NULL;
  int       error = 0;
  int       j, numfractional, iter, nfix;
  int       numintvars;
  int      *intvars = NULL;
  int       status;
  char      vtype, *vname;
  double    sol, obj, fixval;
  var_t    *fractional = NULL;

  if (argc < 2)
  {
    fprintf(stderr, "Usage: fixanddive_c filename\n");
    exit(1);
  }

  error = GRBloadenv(&env, "fixanddive.log");
  if (error || env == NULL)
  {
    fprintf(stderr, "Error: could not create environment\n");
    exit(1);
  }

  /* Read model */
  error = GRBreadmodel(env, argv[1], &model);
  if (error) goto QUIT;

  /* Collect integer variables and relax them */
  error = GRBgetintattr(model, "NumIntVars", &numintvars);
  if (error) goto QUIT;
  intvars = malloc(sizeof(int) * numintvars);
  if (!intvars) goto QUIT;
  fractional = malloc(sizeof(var_t) * numintvars);
  if (!fractional) goto QUIT;
  numfractional = 0;
  for (j = 0; j < numintvars; ++j)
  {
    error = GRBgetcharattrelement(model, "VType", j, &vtype);
    if (error) goto QUIT;
    if (vtype != GRB_CONTINUOUS)
    {
      intvars[numfractional++] = j;
      error = GRBsetcharattrelement(model, "VType", j, GRB_CONTINUOUS);
      if (error) goto QUIT;
    }
  }

  modelenv = GRBgetenv(model);
  if (!modelenv) goto QUIT;
  error = GRBsetintparam(modelenv, "OutputFlag", 0);
  if (error) goto QUIT;
  error = GRBoptimize(model);
  if (error) goto QUIT;

  /* Perform multiple iterations. In each iteration, identify the first
     quartile of integer variables that are closest to an integer value
     in the relaxation, fix them to the nearest integer, and repeat. */

  for (iter = 0; iter < 1000; ++iter)
  {

    /* create a list of fractional variables, sorted in order of
       increasing distance from the relaxation solution to the nearest
       integer value */

    numfractional = 0;
    for (j = 0; j < numintvars; ++j)
    {
      error = GRBgetdblattrelement(model, "X", intvars[j], &sol);
      if (error) goto QUIT;
      if (fabs(sol - floor(sol + 0.5)) > 1e-5)
      {
        fractional[numfractional].index = intvars[j];
        fractional[numfractional++].X = sol;
      }
    }

    error = GRBgetdblattr(model, "ObjVal", &obj);
    if (error) goto QUIT;
    printf("Iteration %i, obj %f, fractional %i\n",
           iter, obj, numfractional);

    if (numfractional == 0)
    {
      printf("Found feasible solution - objective %f\n", obj);
      break;
    }

    /* Fix the first quartile to the nearest integer value */
    qsort(fractional, numfractional, sizeof(var_t), vcomp);
    nfix = numfractional / 4;
    nfix = (nfix > 1) ? nfix : 1;
    for (j = 0; j < nfix; ++j)
    {
      fixval = floor(fractional[j].X + 0.5);
      error = GRBsetdblattrelement(model, "LB", fractional[j].index, fixval);
      if (error) goto QUIT;
      error = GRBsetdblattrelement(model, "UB", fractional[j].index, fixval);
      if (error) goto QUIT;
      error = GRBgetstrattrelement(model, "VarName",
                                   fractional[j].index, &vname);
      printf("  Fix %s to %f ( rel %f )\n", vname, fixval, fractional[j].X);
    }

    error = GRBoptimize(model);
    if (error) goto QUIT;

    /* Check optimization result */

    error = GRBgetintattr(model, "Status", &status);
    if (error) goto QUIT;
    if (status != GRB_OPTIMAL)
    {
      printf("Relaxation is infeasible\n");
      break;
    }
  }


QUIT:

  /* Error reporting */

  if (error)
  {
    printf("ERROR: %s\n", GRBgeterrormsg(env));
    exit(1);
  }

  /* Free data */

  free(intvars);
  free(fractional);

  /* Free model */

  GRBfreemodel(model);

  /* Free environment */

  GRBfreeenv(env);

  return 0;
}
示例#4
0
int
main(int   argc,
     char *argv[])
{
  GRBenv   *env   = NULL;
  GRBmodel *model = NULL;
  int       error = 0, status;
  int       s, w, col;
  int      *cbeg = NULL;
  int      *cind = NULL;
  int       idx;
  double   *cval = NULL;
  char     *sense = NULL;
  char      vname[MAXSTR];
  double    obj;
  int       i, iis, numconstrs;
  char     *cname;

  /* Sample data */
  const int nShifts = 14;
  const int nWorkers = 7;

  /* Sets of days and workers */
  char* Shifts[] =
    { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6",
      "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13",
      "Sun14" };
  char* Workers[] =
    { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" };

  /* Number of workers required for each shift */
  double shiftRequirements[] =
    { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 };

  /* Amount each worker is paid to work one shift */
  double pay[] = { 10, 12, 10, 8, 8, 9, 11 };

  /* Worker availability: 0 if the worker is unavailable for a shift */
  double availability[][14] =
    { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
      { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 },
      { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 },
      { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };

  /* Create environment */
  error = GRBloadenv(&env, "workforce1.log");
  if (error || env == NULL)
  {
    fprintf(stderr, "Error: could not create environment\n");
    exit(1);
  }

  /* Create initial model */
  error = GRBnewmodel(env, &model, "workforce1", nWorkers * nShifts,
                      NULL, NULL, NULL, NULL, NULL);
  if (error) goto QUIT;

  /* Initialize assignment decision variables:
     x[w][s] == 1 if worker w is assigned
     to shift s. Since an assignment model always produces integer
     solutions, we use continuous variables and solve as an LP. */
  for (w = 0; w < nWorkers; ++w)
  {
    for (s = 0; s < nShifts; ++s)
    {
      col = xcol(w, s);
      sprintf(vname, "%s.%s", Workers[w], Shifts[s]);
      error = GRBsetdblattrelement(model, "UB", col, availability[w][s]);
      if (error) goto QUIT;
      error = GRBsetdblattrelement(model, "Obj", col, pay[w]);
      if (error) goto QUIT;
      error = GRBsetstrattrelement(model, "VarName", col, vname);
      if (error) goto QUIT;
    }
  }

  /* The objective is to minimize the total pay costs */
  error = GRBsetintattr(model, "ModelSense", 1);
  if (error) goto QUIT;

  /* Make space for constraint data */
  cbeg = malloc(sizeof(int) * nShifts);
  if (!cbeg) goto QUIT;
  cind = malloc(sizeof(int) * nShifts * nWorkers);
  if (!cind) goto QUIT;
  cval = malloc(sizeof(double) * nShifts * nWorkers);
  if (!cval) goto QUIT;
  sense = malloc(sizeof(char) * nShifts);
  if (!sense) goto QUIT;

  /* Constraint: assign exactly shiftRequirements[s] workers
     to each shift s */
  idx = 0;
  for (s = 0; s < nShifts; ++s)
  {
    cbeg[s] = idx;
    sense[s] = GRB_EQUAL;
    for (w = 0; w < nWorkers; ++w)
    {
      cind[idx] = xcol(w, s);
      cval[idx++] = 1.0;
    }
  }
  error = GRBaddconstrs(model, nShifts, idx, cbeg, cind, cval, sense,
                        shiftRequirements, Shifts);
  if (error) goto QUIT;

  /* Optimize */
  error = GRBoptimize(model);
  if (error) goto QUIT;
  error = GRBgetintattr(model, "Status", &status);
  if (error) goto QUIT;
  if (status == GRB_UNBOUNDED)
  {
    printf("The model cannot be solved because it is unbounded\n");
    goto QUIT;
  }
  if (status == GRB_OPTIMAL)
  {
    error = GRBgetdblattr(model, "ObjVal", &obj);
    if (error) goto QUIT;
    printf("The optimal objective is %f\n", obj);
    goto QUIT;
  }
  if ((status != GRB_INF_OR_UNBD) && (status != GRB_INFEASIBLE))
  {
    printf("Optimization was stopped with status %i\n", status);
    goto QUIT;
  }

  /* do IIS */
  printf("The model is infeasible; computing IIS\n");
  error = GRBcomputeIIS(model);
  if (error) goto QUIT;
  printf("\nThe following constraint(s) cannot be satisfied:\n");
  error = GRBgetintattr(model, "NumConstrs", &numconstrs);
  if (error) goto QUIT;
  for (i = 0; i < numconstrs; ++i)
  {
    error = GRBgetintattrelement(model, "IISConstr", i, &iis);
    if (error) goto QUIT;
    if (iis)
    {
      error = GRBgetstrattrelement(model, "ConstrName", i, &cname);
      if (error) goto QUIT;
      printf("%s\n", cname);
    }
  }



QUIT:

  /* Error reporting */

  if (error)
  {
    printf("ERROR: %s\n", GRBgeterrormsg(env));
    exit(1);
  }

  /* Free data */

  free(cbeg);
  free(cind);
  free(cval);
  free(sense);

  /* Free model */

  GRBfreemodel(model);

  /* Free environment */

  GRBfreeenv(env);

  return 0;
}
示例#5
0
int
main(int   argc,
     char *argv[])
{
  GRBenv   *env = NULL, *aenv;
  GRBmodel *a = NULL, *b = NULL;
  int       error = 0;
  int       i, numvars, status;
  char      vtype, *vname;
  double    x, bnd, aobj, bobj, objchg;

  if (argc < 2)
  {
    fprintf(stderr, "Usage: sensitivity_c filename\n");
    exit(1);
  }

  error = GRBloadenv(&env, "sensitivity.log");
  if (error) goto QUIT;

  /* Read model */
  error = GRBreadmodel(env, argv[1], &a);
  if (error) goto QUIT;
  error = GRBoptimize(a);
  if (error) goto QUIT;
  error = GRBgetdblattr(a, "ObjVal", &aobj);
  if (error) goto QUIT;
  aenv = GRBgetenv(a);
  if (!aenv) goto QUIT;
  error = GRBsetintparam(aenv, "OutputFlag", 0);
  if (error) goto QUIT;

  /* Iterate over all variables */
  error = GRBgetintattr(a, "NumVars", &numvars);
  if (error) goto QUIT;
  for (i = 0; i < numvars; ++i)
  {
    error = GRBgetcharattrelement(a, "VType", i, &vtype);
    if (error) goto QUIT;

    if (vtype == GRB_BINARY)
    {

      /* Create clone and fix variable */
      b = GRBcopymodel(a);
      if (!b) goto QUIT;
      error = GRBgetstrattrelement(a, "VarName", i, &vname);
      if (error) goto QUIT;
      error = GRBgetdblattrelement(a, "X", i, &x);
      if (error) goto QUIT;
      error = GRBgetdblattrelement(a, "LB", i, &bnd);
      if (error) goto QUIT;
      if (x - bnd < 0.5)
      {
        error = GRBgetdblattrelement(b, "UB", i, &bnd);
        if (error) goto QUIT;
        error = GRBsetdblattrelement(b, "LB", i, bnd);
        if (error) goto QUIT;
      }
      else
      {
        error = GRBgetdblattrelement(b, "LB", i, &bnd);
        if (error) goto QUIT;
        error = GRBsetdblattrelement(b, "UB", i, bnd);
        if (error) goto QUIT;
      }

      error = GRBoptimize(b);
      if (error) goto QUIT;

      error = GRBgetintattr(b, "Status", &status);
      if (error) goto QUIT;
      if (status == GRB_OPTIMAL)
      {
        error = GRBgetdblattr(b, "ObjVal", &bobj);
        if (error) goto QUIT;
        objchg = bobj - aobj;
        if (objchg < 0)
        {
          objchg = 0;
        }
        printf("Objective sensitivity for variable %s is %f\n", vname, objchg);
      }
      else
      {
        printf("Objective sensitivity for variable %s is infinite\n", vname);
      }

      GRBfreemodel(b);
      b = NULL;
    }
  }


QUIT:

  /* Error reporting */

  if (error)
  {
    printf("ERROR: %s\n", GRBgeterrormsg(env));
    exit(1);
  }

  /* Free models */

  GRBfreemodel(a);
  GRBfreemodel(b);

  /* Free environment */

  GRBfreeenv(env);

  return 0;
}
示例#6
0
文件: tsp_c.c 项目: revisalo/cr2
int
main(int   argc,
     char *argv[])
{
  GRBenv   *env   = NULL;
  GRBmodel *model = NULL;
  int       i, j, len, n, solcount;
  int       error = 0;
  char      name[100];
  double   *x = NULL;
  double   *y = NULL;
  int      *ind = NULL;
  double   *val = NULL;
  struct callback_data mydata;

  if (argc < 2) {
    fprintf(stderr, "Usage: tsp_c size\n");
    exit(1);
  }

  n = atoi(argv[1]);
  if (n == 0) {
    fprintf(stderr, "Argument must be a positive integer.\n");
  } else if (n > 30) {
    printf("It will be a challenge to solve a TSP this large.\n");
  }

  x   = (double *) malloc(n*sizeof(double));
  y   = (double *) malloc(n*sizeof(double));
  ind = (int *)    malloc(n*sizeof(int));
  val = (double *) malloc(n*sizeof(double));

  if (x == NULL || y == NULL || ind == NULL || val == NULL) {
    fprintf(stderr, "Out of memory\n");
    exit(1);
  }

  /* Create random points */

  for (i = 0; i < n; i++) {
    x[i] = ((double) rand())/RAND_MAX;
    y[i] = ((double) rand())/RAND_MAX;
  }

  /* Create environment */

  error = GRBloadenv(&env, "tsp.log");
  if (error || env == NULL) {
    fprintf(stderr, "Error: could not create environment\n");
    exit(1);
  }

  /* Create an empty model */

  error = GRBnewmodel(env, &model, "tsp", 0, NULL, NULL, NULL, NULL, NULL);
  if (error) goto QUIT;


  /* Add variables - one for every pair of nodes */

  for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
      sprintf(name, "x_%d_%d", i, j);
      error = GRBaddvar(model, 0, NULL, NULL, distance(x, y, i, j),
                        0.0, 1.0, GRB_BINARY, name);
      if (error) goto QUIT;
    }
  }

  /* Integrate new variables */

  error = GRBupdatemodel(model);
  if (error) goto QUIT;

  /* Degree-2 constraints */

  for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
      ind[j] = i*n+j;
      val[j] = 1.0;
    }

    sprintf(name, "deg2_%d", i);

    error = GRBaddconstr(model, n, ind, val, GRB_EQUAL, 2, name);
    if (error) goto QUIT;
  }

  /* Forbid edge from node back to itself */

  for (i = 0; i < n; i++) {
    error = GRBsetdblattrelement(model, GRB_DBL_ATTR_UB, i*n+i, 0);
    if (error) goto QUIT;
  }

  /* Symmetric TSP */

  for (i = 0; i < n; i++) {
    for (j = 0; j < i; j++) {
      ind[0] = i*n+j;
      ind[1] = i+j*n;
      val[0] = 1;
      val[1] = -1;
      error = GRBaddconstr(model, 2, ind, val, GRB_EQUAL, 0, NULL);
      if (error) goto QUIT;
    }
  }

  /* Set callback function */

  mydata.n = n;

  error = GRBsetcallbackfunc(model, subtourelim, (void *) &mydata);
  if (error) goto QUIT;

  /* Turn off dual reductions - required when using lazy constraints */

  error = GRBsetintparam(GRBgetenv(model), GRB_INT_PAR_DUALREDUCTIONS, 0);
  if (error) goto QUIT;

  /* Optimize model */

  error = GRBoptimize(model);
  if (error) goto QUIT;

  /* Extract solution */

  error = GRBgetintattr(model, GRB_INT_ATTR_SOLCOUNT, &solcount);
  if (error) goto QUIT;

  if (solcount > 0) {
    int *tour = NULL;
    double *sol = NULL;

    sol = (double *) malloc(n*n*sizeof(double));
    tour = (int *) malloc(n*sizeof(int));
    if (sol == NULL || tour == NULL) {
      fprintf(stderr, "Out of memory\n");
      exit(1);
    }

    error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, n*n, sol);
    if (error) goto QUIT;

    /* Print tour */

    findsubtour(n, sol, &len, tour);

    printf("Tour: ");
    for (i = 0; i < len; i++)
      printf("%d ", tour[i]);
    printf("\n");

    free(tour);
    free(sol);
  }

QUIT:

  /* Free data */

  free(x);
  free(y);
  free(ind);
  free(val);

  /* Error reporting */

  if (error) {
    printf("ERROR: %s\n", GRBgeterrormsg(env));
    exit(1);
  }

  /* Free model */

  GRBfreemodel(model);

  /* Free environment */

  GRBfreeenv(env);

  return 0;
}
示例#7
0
int
main(int   argc,
     char *argv[])
{
  GRBenv   *env = NULL;
  GRBmodel *model = NULL;
  int       error = 0, status;
  int       s, w, col;
  int      *cbeg = NULL;
  int      *cind = NULL;
  int       idx;
  double   *cval = NULL;
  char     *sense = NULL;
  char      vname[MAXSTR];
  double    obj;
  int       i, j, numvars, numconstrs;
  int      *vbeg = NULL;
  int      *vind = NULL;
  double   *vval = NULL;
  double   *vobj = NULL;
  double    sol;
  char     *cname, *sname;
  int       varnamesct = 0;
  char    **varnames = NULL;

  /* Sample data */
  const int nShifts = 14;
  const int nWorkers = 7;

  /* Sets of days and workers */
  char* Shifts[] =
    { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6",
      "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13",
      "Sun14" };
  char* Workers[] =
    { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" };

  /* Number of workers required for each shift */
  double shiftRequirements[] =
    { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 };

  /* Amount each worker is paid to work one shift */
  double pay[] = { 10, 12, 10, 8, 8, 9, 11 };

  /* Worker availability: 0 if the worker is unavailable for a shift */
  double availability[][14] =
    { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
      { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
      { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
      { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 },
      { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 },
      { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };

  /* Create environment */
  error = GRBloadenv(&env, "workforce3.log");
  if (error || env == NULL)
  {
    fprintf(stderr, "Error: could not create environment\n");
    exit(1);
  }

  /* Create initial model */
  error = GRBnewmodel(env, &model, "workforce3", nWorkers * nShifts,
                      NULL, NULL, NULL, NULL, NULL);
  if (error) goto QUIT;

  /* Initialize assignment decision variables:
     x[w][s] == 1 if worker w is assigned
     to shift s. Since an assignment model always produces integer
     solutions, we use continuous variables and solve as an LP. */
  for (w = 0; w < nWorkers; ++w)
  {
    for (s = 0; s < nShifts; ++s)
    {
      col = xcol(w, s);
      sprintf(vname, "%s.%s", Workers[w], Shifts[s]);
      error = GRBsetdblattrelement(model, "UB", col, availability[w][s]);
      if (error) goto QUIT;
      error = GRBsetdblattrelement(model, "Obj", col, pay[w]);
      if (error) goto QUIT;
      error = GRBsetstrattrelement(model, "VarName", col, vname);
      if (error) goto QUIT;
    }
  }

  /* The objective is to minimize the total pay costs */
  error = GRBsetintattr(model, "ModelSense", 1);
  if (error) goto QUIT;

  /* Make space for constraint data */
  cbeg = malloc(sizeof(int) * nShifts);
  if (!cbeg) goto QUIT;
  cind = malloc(sizeof(int) * nShifts * nWorkers);
  if (!cind) goto QUIT;
  cval = malloc(sizeof(double) * nShifts * nWorkers);
  if (!cval) goto QUIT;
  sense = malloc(sizeof(char) * nShifts);
  if (!sense) goto QUIT;

  /* Constraint: assign exactly shiftRequirements[s] workers
     to each shift s */
  idx = 0;
  for (s = 0; s < nShifts; ++s)
  {
    cbeg[s] = idx;
    sense[s] = GRB_EQUAL;
    for (w = 0; w < nWorkers; ++w)
    {
      cind[idx] = xcol(w, s);
      cval[idx++] = 1.0;
    }
  }
  error = GRBaddconstrs(model, nShifts, idx, cbeg, cind, cval, sense,
                        shiftRequirements, Shifts);
  if (error) goto QUIT;

  /* Optimize */
  error = GRBoptimize(model);
  if (error) goto QUIT;
  error = GRBgetintattr(model, "Status", &status);
  if (error) goto QUIT;
  if (status == GRB_UNBOUNDED)
  {
    printf("The model cannot be solved because it is unbounded\n");
    goto QUIT;
  }
  if (status == GRB_OPTIMAL)
  {
    error = GRBgetdblattr(model, "ObjVal", &obj);
    if (error) goto QUIT;
    printf("The optimal objective is %f\n", obj);
    goto QUIT;
  }
  if ((status != GRB_INF_OR_UNBD) && (status != GRB_INFEASIBLE))
  {
    printf("Optimization was stopped with status %i\n", status);
    goto QUIT;
  }

  /* Add slack variables to make the model feasible */
  printf("The model is infeasible; adding slack variables\n");

  /* Determine the matrix size before adding the slacks */
  error = GRBgetintattr(model, "NumVars", &numvars);
  if (error) goto QUIT;
  error = GRBgetintattr(model, "NumConstrs", &numconstrs);
  if (error) goto QUIT;

  /* Set original objective coefficients to zero */
  for (j = 0; j < numvars; ++j)
  {
    error = GRBsetdblattrelement(model, "Obj", j, 0.0);
    if (error) goto QUIT;
  }

  /* Add a new slack variable to each shift constraint so that the shifts
     can be satisfied */
  vbeg = malloc(sizeof(int) * numconstrs);
  if (!vbeg) goto QUIT;
  vind = malloc(sizeof(int) * numconstrs);
  if (!vind) goto QUIT;
  vval = malloc(sizeof(double) * numconstrs);
  if (!vval) goto QUIT;
  vobj = malloc(sizeof(double) * numconstrs);
  if (!vobj) goto QUIT;
  varnames = calloc(numconstrs, sizeof(char*));
  if (!varnames) goto QUIT;
  for (i = 0; i < numconstrs; ++i)
  {
    vbeg[i] = i;
    vind[i] = i;
    vval[i] = 1.0;
    vobj[i] = 1.0;
    error = GRBgetstrattrelement(model, "ConstrName", i, &cname);
    if (error) goto QUIT;
    varnames[i] = malloc(sizeof(char*) * (6 + strlen(cname)));
    if (!varnames[i]) goto QUIT;
    varnamesct++;
    strcpy(varnames[i], cname);
    strcat(varnames[i], "Slack");
  }
  error = GRBaddvars(model, numconstrs, numconstrs,
                     vbeg, vind, vval, vobj, NULL, NULL, NULL, varnames);
  if (error) goto QUIT;

  error = GRBupdatemodel(model);
  if (error) goto QUIT;

  /* Solve the model with slacks */
  error = GRBoptimize(model);
  if (error) goto QUIT;
  error = GRBgetintattr(model, "Status", &status);
  if (error) goto QUIT;
  if ((status == GRB_INF_OR_UNBD) || (status == GRB_INFEASIBLE) ||
      (status == GRB_UNBOUNDED))
  {
    printf("The model with slacks cannot be solved "
           "because it is infeasible or unbounded\n");
    goto QUIT;
  }
  if (status != GRB_OPTIMAL)
  {
    printf("Optimization was stopped with status %i\n", status);
    goto QUIT;
  }

  printf("\nSlack values:\n");
  for (j = numvars; j < numvars + numconstrs; ++j)
  {
    error = GRBgetdblattrelement(model, "X", j, &sol);
    if (error) goto QUIT;
    if (sol > 1e-6)
    {
      error = GRBgetstrattrelement(model, "VarName", j, &sname);
      if (error) goto QUIT;
      printf("%s = %f\n", sname, sol);
    }
  }

QUIT:

  /* Error reporting */

  if (error)
  {
    printf("ERROR: %s\n", GRBgeterrormsg(env));
    exit(1);
  }

  /* Free data */

  free(cbeg);
  free(cind);
  free(cval);
  free(sense);
  free(vbeg);
  free(vind);
  free(vval);
  free(vobj);
  for (i = 0; i < varnamesct; ++i)
  {
    free(varnames[i]);
  }
  free(varnames);

  /* Free model */

  GRBfreemodel(model);

  /* Free environment */

  GRBfreeenv(env);

  return 0;
}
示例#8
0
int main(void)
{
  int retcode = 0;
  GRBenv   *env = NULL;
  GRBmodel *model = NULL;
  int n, j;
  double *obj      = NULL;
  double *lb       = NULL;
  double *ub       = NULL;
  double *x;
  int *qrow, *qcol, Nq;
  double *qval;
  int *cind;
  double rhs;
  char sense;
  double *cval;
  int numnonz;

  char **names;


  n = 9; /** 7 'x' variables, 2 factor variables **/


  retcode = GRBloadenv(&env, "factormodel.log");
  if (retcode) goto BACK;

 /* Create initial model */
  retcode = GRBnewmodel(env, &model, "second", n, 
                      NULL, NULL, NULL, NULL, NULL);
  if (retcode) goto BACK;

  names = (char **) calloc(n, sizeof(char *));

  /** next we create the remaining attributes for the n columns **/
  obj     = (double *) calloc (n, sizeof(double));
  ub     = (double *) calloc (n, sizeof(double));
  lb     = (double *) calloc (n, sizeof(double));
  x     = (double *) calloc (n, sizeof(double));


  for(j = 0; j < 7; j++){
    names[j] = (char *)calloc(3, sizeof(char));
    if(names[j] == NULL){
      retcode = 1; goto BACK;
    }
    sprintf(names[j],"x%d", j);
  }
  for(j = 7; j < 9; j++){
    names[j] = (char *)calloc(3, sizeof(char));
    if(names[j] == NULL){
		  retcode = 1; goto BACK;
    }
    sprintf(names[j],"y%d", j - 7);
  }
  obj[0] = -.233; obj[1] = -3.422; obj[2] = -.1904; obj[3] = -.5411;
  obj[4] = -.045; obj[5] = -1.271; obj[6] = -0.955;
  /** calloc initializes memory to zero, so all other obj[j] are zero **/

  /**next, the upper bounds on the x variables **/
  ub[0] = 0.6; ub[1] = 0.8; ub[2] = 0.8; ub[3] = 0.5;
  ub[4] = 0.5; ub[5] = 0.26; ub[6] = 0.99;
  
  /** the upper bounds on the two factor variables -- we make them large **/
  ub[7] = 100; ub[8] = 100;
  /** the lower bounds on the factor variables **/
  lb[7] = -100; lb[8] = -100;

  /* initialize variables */
  for(j = 0; j < n; j++){
    retcode = GRBsetstrattrelement(model, "VarName", j, names[j]);
    if (retcode) goto BACK;

    retcode = GRBsetdblattrelement(model, "Obj", j, obj[j]);
    if (retcode) goto BACK;

    retcode = GRBsetdblattrelement(model, "LB", j, lb[j]);
    if (retcode) goto BACK;

    retcode = GRBsetdblattrelement(model, "UB", j, ub[j]);
    if (retcode) goto BACK;
  }

  /** next, the quadratic -- there are 11 nonzeroes: 7 residual variances plus the 2x2
									factor covariance matrix**/

  Nq = 11; 
  qrow = (int *) calloc(Nq, sizeof(int));  /** row indices **/
  qcol = (int *) calloc(Nq, sizeof(int));  /** column indices **/
  qval = (double *) calloc(Nq, sizeof(double));  /** values **/

  if( ( qrow == NULL) || ( qcol == NULL) || (qval == NULL) ){
    printf("could not create quadratic\n");
    retcode = 1; goto BACK;
  }

  qval[0] = 10.0; qrow[0] = 0; qcol[0] = 0;
  qval[1] = 20.0; qrow[1] = 1; qcol[1] = 1;
  qval[2] = 30.0; qrow[2] = 2; qcol[2] = 2;
  qval[3] = 40.0; qrow[3] = 3; qcol[3] = 3;
  qval[4] = 50.0; qrow[4] = 4; qcol[4] = 4;
  qval[5] = 60.0; qrow[5] = 5; qcol[5] = 5;
  qval[6] = 70.0; qrow[6] = 6;   qcol[6] = 6;  

  qval[7] = 100.0; qrow[7] = 7; qcol[7] = 7;							
  qval[8] = 200.0; qrow[8] = 8; qcol[8] = 8;
  qval[9] = 0.1; qrow[9] = 7; qcol[9] = 8;
  qval[10] = 0.1; qrow[10] = 8; qcol[10] = 7;	 

  retcode = GRBaddqpterms(model, 11, qrow, qcol, qval);
  if (retcode) goto BACK;

  /** now we will add one constraint at a time **/
  /** we need to have a couple of auxiliary arrays **/

  cind = (int *)calloc(n, sizeof(int));  /** n is over the top since no constraint is totally dense;
					     but it's not too bad here **/
  cval= (double *)calloc(n, sizeof(double));

  /** two factor constraints, first one is next**/
  cval[0] = 1.508; cval[1] = .7802; cval[2] = 1.8796;
  cval[3] = 4.256;  cval[4] = 1.335; cval[5] = 2.026; cval[6] = 1.909;
  cval[7] = -1;

  for(j = 0; j < 7; j++) cind[j] = j;
  cind[7] = 7;

  numnonz = 8;
  rhs = 0;
  sense = GRB_EQUAL;

  retcode = GRBaddconstr(model, numnonz, cind, cval, sense, rhs, "first_constraint");
  if (retcode) goto BACK;

  /** second factor constraint **/

  cval[0] = 4.228; cval[1] = 1.2945; cval[2] = .827;
  cval[3] = 2.149;  
  cval[4] = 2.353; cval[5] = 0.3026; cval[6] = 1.487;
  
  cval[7] = -1;
  for(j = 0; j < 7; j++) cind[j] = j; /** redundant! but let's keep it here so that we know it 
					 will be used **/
  cind[7] = 7;

  numnonz = 8;
  rhs = 0;
  sense = GRB_EQUAL;

  retcode = GRBaddconstr(model, numnonz, cind, cval, sense, rhs, "second_constraint");
  if (retcode) goto BACK;


  /** sum of x variables = 1 **/
  cval[0] = 1.0; cval[1] = 1.0; cval[2] = 1.0;
  cval[3] = 1.0;  cval[4] = 1.0; cval[5] = 1.0; cval[6] = 1.0;

  for(j = 0; j < 7; j++) cind[j] = j;

  numnonz = 7;
  rhs = 1.0;
  sense = GRB_EQUAL;

  retcode = GRBaddconstr(model, numnonz, cind, cval, sense, rhs, "convexity");
  if (retcode) goto BACK;


  retcode = GRBupdatemodel(model);
  if (retcode) goto BACK;

  /** optional: write the problem **/

  retcode = GRBwrite(model, "factorqp.lp");
  if (retcode) goto BACK;


  retcode = GRBoptimize(model);
  if (retcode) goto BACK;


  /** get solution **/


  retcode = GRBgetdblattrarray(model,
                               GRB_DBL_ATTR_X, 0, n,
                               x);
  if(retcode) goto BACK;

  /** now let's see the values **/

  for(j = 0; j < n; j++){
    printf("%s = %g\n", names[j], x[j]);
  }

  GRBfreemodel(model);
  GRBfreeenv(env);


 BACK:
  printf("\nexiting with retcode %d\n", retcode);
  return retcode;
}