Beispiel #1
0
double GurobiSolver::get_value(void *ptr){
    int index = *(int*)(ptr);
    if(index >= 0 && index < variables->size()){
        GRBVar v = variables->at(index);
        return v.get(GRB_DoubleAttr_X);
    }
    return 0.0;
}
Beispiel #2
0
double GurobiSolver::get_value(void *ptr){
    int index = *(int*)(ptr);
    if(index >= 0 && index < variables->size()){
        try {
            GRBVar v = variables->at(index);
            return v.get(GRB_DoubleAttr_X);
        } catch (GRBException e) {
            std::cout << "Gurobi exception getting value: " << e.getErrorCode() << std::endl;
            std::cout << e.getMessage() << std::endl;
        }
    }
    return 0.0;
}
int
main(int   argc,
     char *argv[])
{
  try {
    GRBEnv env = GRBEnv();

    GRBModel model = GRBModel(env);

    // Create variables

    GRBVar x = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "x");
    GRBVar y = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "y");
    GRBVar z = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "z");

    // Integrate new variables

    model.update();

    // Set objective: maximize x + y + 2 z

    model.setObjective(x + y + 2 * z, GRB_MAXIMIZE);

    // Add constraint: x + 2 y + 3 z <= 4

    model.addConstr(x + 2 * y + 3 * z <= 4, "c0");

    // Add constraint: x + y >= 1

    model.addConstr(x + y >= 1, "c1");

    // Optimize model

    model.optimize();

    cout << x.get(GRB_StringAttr_VarName) << " "
         << x.get(GRB_DoubleAttr_X) << endl;
    cout << y.get(GRB_StringAttr_VarName) << " "
         << y.get(GRB_DoubleAttr_X) << endl;
    cout << z.get(GRB_StringAttr_VarName) << " "
         << z.get(GRB_DoubleAttr_X) << endl;

    cout << "Obj: " << model.get(GRB_DoubleAttr_ObjVal) << endl;

  } catch(GRBException e) {
    cout << "Error code = " << e.getErrorCode() << endl;
    cout << e.getMessage() << endl;
  } catch(...) {
    cout << "Exception during optimization" << endl;
  }

  return 0;
}
Beispiel #4
0
int solveAndPrint(GRBModel& model, GRBVar& totSlack,
                  int nWorkers, string* Workers,
                  GRBVar* totShifts) throw(GRBException)
{
  model.optimize();
  int status = model.get(GRB_IntAttr_Status);

  if ((status == GRB_INF_OR_UNBD) || (status == GRB_INFEASIBLE) ||
      (status == GRB_UNBOUNDED))
  {
    cout << "The model cannot be solved " <<
    "because it is infeasible or unbounded" << endl;
    return status;
  }
  if (status != GRB_OPTIMAL)
  {
    cout << "Optimization was stopped with status " << status << endl;
    return status;
  }

  // Print total slack and the number of shifts worked for each worker
  cout << endl << "Total slack required: " <<
    totSlack.get(GRB_DoubleAttr_X) << endl;
  for (int w = 0; w < nWorkers; ++w) {
    cout << Workers[w] << " worked " <<
    totShifts[w].get(GRB_DoubleAttr_X) << " shifts" << endl;
  }
  cout << endl;
  return status;
}
ChannelsFitness ILPChannelingGurobi(DataStructure *dataStructure, double const alpha) {
    try {
        unsigned int messageCount;
        double alphaCoef = alpha;
        GRBEnv env = GRBEnv();
        GRBModel model = GRBModel(env);
        //model.getEnv().set(GRB_DoubleParam_TimeLimit, 3600);
        ChannelsFitness cfResult;
        CAMessage *messages;
        messageCount = static_cast<unsigned int>(AggregateMessages(dataStructure, messages));

        vector<int> w(messageCount);
        transform(messages, messages + messageCount, w.begin(), [](CAMessage &message) { return message.payload; });
        int sumW = 0;
        for (int i = 0; i < messageCount; i++) {
            for (int j = 0; j < static_cast<int>(messages[i].nodes.size()); j++) {
                if (dataStructure->nodesOnBothChannels[messages[i].nodes[j]] != 1) {
                    sumW += messages[i].payload;
                    break;
                }
            }
        }
        if (alphaCoef < 0)
            alphaCoef = 1.0 / sumW;

        GRBVar z = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "z");
        GRBVar Pa = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "Pa");
        GRBVar Pb = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "Pb");
        GRBVar Pg = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "Pg");

        vector<GRBVar> Uea(messageCount);
        vector<GRBVar> Ueb(messageCount);
        vector<GRBVar> xi(static_cast<unsigned int>(dataStructure->nodeCount));

        generate_n(Uea.begin(), messageCount,
                   [&model]() { return model.addVar(0.0, 1.0, 0.0, GRB_CONTINUOUS, "Uea"); });
        generate_n(Ueb.begin(), messageCount,
                   [&model]() { return model.addVar(0.0, 1.0, 0.0, GRB_CONTINUOUS, "Ueb"); });
        generate_n(xi.begin(), dataStructure->nodeCount,
                   [&model]() { return model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "xi"); });

        model.update();

        model.setObjective(z + alphaCoef * Pg, GRB_MINIMIZE);

        model.addConstr(Pa <= z);
        model.addConstr(Pb <= z);
        model.addConstr(Pa + Pb - sumW == Pg);
        model.addConstr(expSum(Uea, w) == Pa);
        model.addConstr(expSum(Ueb, w) == Pb);
        for (int e = 0; e < messageCount; e++) {
            for (int i = 0; i < static_cast<int>(messages[e].nodes.size()); i++) // Problem!!!
            {
                if (dataStructure->nodesOnBothChannels[messages[e].nodes[i]] != 1) {
                    model.addConstr(xi[messages[e].nodes[i]] - Uea[e] <= 0);
                    model.addConstr(xi[messages[e].nodes[i]] + Ueb[e] >= 1);
                }
            }
        }

        model.addConstr(xi[0] == 1);
        model.optimize();
        switch (model.get(GRB_IntAttr_Status)) {
            case GRB_INFEASIBLE:
            case GRB_UNBOUNDED:
                cfResult.channelA = cfResult.channelB = cfResult.gateway = -1;
                return cfResult;
            case GRB_TIME_LIMIT:
                if (model.get(GRB_IntAttr_SolCount) <= 0) {
                    cfResult.channelA = cfResult.channelB = cfResult.gateway = -1;
                    return cfResult;
                }
            default:
                break;
        }


        for (int i = 0; i < dataStructure->nodeCount; i++)
            dataStructure->nodesChannel[i] = static_cast<char>(xi[i].get(GRB_DoubleAttr_X));

        /*for(i = 0; i < number_variables; i++)
        {
            printf("%d ", static_cast<int>(glp_mip_col_val(mip,i+1)));
        }*/
        cfResult.channelA = static_cast<int>(floor(Pa.get(GRB_DoubleAttr_X) + 0.5));
        cfResult.channelB = static_cast<int>(floor(Pb.get(GRB_DoubleAttr_X) + 0.5));
        cfResult.gateway = static_cast<int>(floor(Pg.get(GRB_DoubleAttr_X) + 0.5));
        for (int i = 0; i < dataStructure->nodeCount; i++) {
            printf("%d ", static_cast<int>(xi[i].get(GRB_DoubleAttr_X)));
        }
        printf("\n");
        printf("/ %d, %d, %d\n", cfResult.channelA, cfResult.channelB, cfResult.gateway);

        delete[] messages;
        return cfResult;
    } catch (GRBException e) {
        cout << e.getMessage() << "\n";
    }
}
Beispiel #6
0
int
main(int argc,
     char *argv[])
{
  GRBEnv* env = 0;
  GRBConstr* c = 0;
  GRBVar* v = 0;
  GRBVar** x = 0;
  GRBVar* slacks = 0;
  GRBVar* totShifts = 0;
  GRBVar* diffShifts = 0;
  int xCt = 0;
  try
  {

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

    // Sets of days and workers
    string Shifts[] =
      { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6",
        "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13",
        "Sun14" };
    string 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 };

    // Worker availability: 0 if the worker is unavailable for a shift
    double availability[][nShifts] =
      { { 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 } };

    // Model
    env = new GRBEnv();
    GRBModel model = GRBModel(*env);
    model.set(GRB_StringAttr_ModelName, "assignment");

    // Assignment variables: x[w][s] == 1 if worker w is assigned
    // to shift s. This is no longer a pure assignment model, so we must
    // use binary variables.
    x = new GRBVar*[nWorkers];
    for (int w = 0; w < nWorkers; ++w)
    {
      x[w] = model.addVars(nShifts);
      xCt++;
      model.update();
      for (int s = 0; s < nShifts; ++s)
      {
        ostringstream vname;
        vname << Workers[w] << "." << Shifts[s];
        x[w][s].set(GRB_DoubleAttr_UB, availability[w][s]);
        x[w][s].set(GRB_CharAttr_VType, GRB_BINARY);
        x[w][s].set(GRB_StringAttr_VarName, vname.str());
      }
    }

    // Slack variables for each shift constraint so that the shifts can
    // be satisfied
    slacks = model.addVars(nShifts);
    model.update();
    for (int s = 0; s < nShifts; ++s)
    {
      ostringstream vname;
      vname << Shifts[s] << "Slack";
      slacks[s].set(GRB_StringAttr_VarName, vname.str());
    }

    // Variable to represent the total slack
    GRBVar totSlack = model.addVar(0, GRB_INFINITY, 0, GRB_CONTINUOUS,
                                   "totSlack");

    // Variables to count the total shifts worked by each worker
    totShifts = model.addVars(nWorkers);
    model.update();
    for (int w = 0; w < nWorkers; ++w)
    {
      ostringstream vname;
      vname << Workers[w] << "TotShifts";
      totShifts[w].set(GRB_StringAttr_VarName, vname.str());
    }

    // Update model to integrate new variables
    model.update();

    GRBLinExpr lhs;

    // Constraint: assign exactly shiftRequirements[s] workers
    // to each shift s
    for (int s = 0; s < nShifts; ++s)
    {
      lhs = 0;
      lhs += slacks[s];
      for (int w = 0; w < nWorkers; ++w)
      {
        lhs += x[w][s];
      }
      model.addConstr(lhs == shiftRequirements[s], Shifts[s]);
    }

    // Constraint: set totSlack equal to the total slack
    lhs = 0;
    for (int s = 0; s < nShifts; ++s)
    {
      lhs += slacks[s];
    }
    model.addConstr(lhs == totSlack, "totSlack");

    // Constraint: compute the total number of shifts for each worker
    for (int w = 0; w < nWorkers; ++w) {
      lhs = 0;
      for (int s = 0; s < nShifts; ++s) {
        lhs += x[w][s];
      }
      ostringstream vname;
      vname << "totShifts" << Workers[w];
      model.addConstr(lhs == totShifts[w], vname.str());
    }

    // Objective: minimize the total slack
    GRBLinExpr obj = 0;
    obj += totSlack;
    model.setObjective(obj);

    // Optimize
    int status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts);
    if (status != GRB_OPTIMAL)
    {
      return 1;
    }

    // Constrain the slack by setting its upper and lower bounds
    totSlack.set(GRB_DoubleAttr_UB, totSlack.get(GRB_DoubleAttr_X));
    totSlack.set(GRB_DoubleAttr_LB, totSlack.get(GRB_DoubleAttr_X));

    // Variable to count the average number of shifts worked
    GRBVar avgShifts =
      model.addVar(0, GRB_INFINITY, 0, GRB_CONTINUOUS, "avgShifts");

    // Variables to count the difference from average for each worker;
    // note that these variables can take negative values.
    diffShifts = model.addVars(nWorkers);
    model.update();
    for (int w = 0; w < nWorkers; ++w) {
      ostringstream vname;
      vname << Workers[w] << "Diff";
      diffShifts[w].set(GRB_StringAttr_VarName, vname.str());
      diffShifts[w].set(GRB_DoubleAttr_LB, -GRB_INFINITY);
    }

    // Update model to integrate new variables
    model.update();

    // Constraint: compute the average number of shifts worked
    lhs = 0;
    for (int w = 0; w < nWorkers; ++w) {
      lhs += totShifts[w];
    }
    model.addConstr(lhs == nWorkers * avgShifts, "avgShifts");

    // Constraint: compute the difference from the average number of shifts
    for (int w = 0; w < nWorkers; ++w) {
      lhs = 0;
      lhs += totShifts[w];
      lhs -= avgShifts;
      ostringstream vname;
      vname << Workers[w] << "Diff";
      model.addConstr(lhs == diffShifts[w], vname.str());
    }

    // Objective: minimize the sum of the square of the difference from the
    // average number of shifts worked
    GRBQuadExpr qobj;
    for (int w = 0; w < nWorkers; ++w) {
      qobj += diffShifts[w] * diffShifts[w];
    }
    model.setObjective(qobj);

    // Optimize
    status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts);
    if (status != GRB_OPTIMAL)
    {
      return 1;
    }

  }
  catch (GRBException e)
  {
    cout << "Error code = " << e.getErrorCode() << endl;
    cout << e.getMessage() << endl;
  }
  catch (...)
  {
    cout << "Exception during optimization" << endl;
  }

  delete[] c;
  delete[] v;
  for (int i = 0; i < xCt; ++i) {
    delete[] x[i];
  }
  delete[] x;
  delete[] slacks;
  delete[] totShifts;
  delete[] diffShifts;
  delete env;
  return 0;
}