public static void main(String[] args) throws Exception {
    int status = 127;
    try {
      IloOplFactory.setDebugMode(true);
      IloOplFactory oplF = new IloOplFactory();

      // make master model
      IloOplErrorHandler errHandler = oplF.createOplErrorHandler();
      IloOplSettings settings = oplF.createOplSettings(errHandler);

      IloOplRunConfiguration masterRC =
          oplF.createOplRunConfiguration(
              DATADIR + "/cutstock_change.mod", DATADIR + "/cutstock_change.dat");
      masterRC.setErrorHandler(errHandler);
      IloCplex masterCplex = oplF.createCplex();
      masterCplex.setOut(null);

      masterRC.setCplex(masterCplex);
      IloOplModel masterOpl = masterRC.getOplModel();
      masterOpl.generate();
      IloOplDataElements masterDataElements = masterOpl.makeDataElements();

      int nWdth = masterDataElements.getElement("Amount").asIntMap().getSize();
      ArrayList<IloNumVar> masterVars = new ArrayList<IloNumVar>();
      IloNumVarMap cuts = masterOpl.getElement("Cut").asNumVarMap();
      for (int i = 1; i <= nWdth; i++) {
        masterVars.add(cuts.get(i));
      }

      // prepare sub model source, definition and engine
      IloOplModelSource subSource = oplF.createOplModelSource(DATADIR + "/cutstock-sub.mod");
      IloOplModelDefinition subDef = oplF.createOplModelDefinition(subSource, settings);
      IloCplex subCplex = oplF.createCplex();
      subCplex.setOut(null);

      double best;
      double curr = Double.MAX_VALUE;
      do {
        best = curr;

        // Make master model
        System.out.println("Solve master.");
        if (masterCplex.solve()) {
          curr = masterCplex.getObjValue();
          System.out.println("OBJECTIVE: " + curr);
          status = 0;
        } else {
          System.out.println("No solution!");
          status = 1;
        }

        // prepare data for sub model
        IloOplDataElements subDataElements = oplF.createOplDataElements();
        subDataElements.addElement(masterDataElements.getElement("RollWidth"));
        subDataElements.addElement(masterDataElements.getElement("Size"));
        subDataElements.addElement(masterDataElements.getElement("Duals"));
        // get reduced costs and set them in sub problem
        IloNumMap duals = subDataElements.getElement("Duals").asNumMap();
        for (int i = 1; i < nWdth + 1; i++) {
          IloForAllRange forAll =
              (IloForAllRange) masterOpl.getElement("ctFill").asConstraintMap().get(i);
          duals.set(i, masterCplex.getDual(forAll));
        }
        // make sub model
        IloOplModel subOpl = oplF.createOplModel(subDef, subCplex);
        subOpl.addDataSource(subDataElements);
        subOpl.generate();

        System.out.println("Solve sub.");
        if (subCplex.solve()) {
          System.out.println("OBJECTIVE: " + subCplex.getObjValue());
          status = 0;
        } else {
          System.out.println("No solution!");
          status = 1;
        }
        if (subCplex.getObjValue() > -RC_EPS) break;

        // Add variable in master model
        IloNumVar newVar = masterCplex.numVar(0, Double.MAX_VALUE);
        IloObjective masterObj = masterOpl.getObjective();
        masterCplex.setLinearCoef(masterObj, newVar, 1);
        for (int i = 1; i < nWdth + 1; i++) {
          double coef = subCplex.getValue(subOpl.getElement("Use").asIntVarMap().get(i));
          IloForAllRange forAll =
              (IloForAllRange) masterOpl.getElement("ctFill").asConstraintMap().get(i);
          masterCplex.setLinearCoef(forAll, newVar, coef);
        }
        masterVars.add(newVar);

        subOpl.end();
      } while (best != curr && status == 0);

      IloNumVar[] masterVarsA = new IloNumVar[masterVars.size()];
      masterVars.toArray(masterVarsA);
      masterCplex.add(masterCplex.conversion(masterVarsA, IloNumVarType.Int));
      if (masterCplex.solve()) {
        System.out.println("OBJECTIVE: " + masterCplex.getObjValue());
      }
      oplF.end();
    } catch (IloOplException ex) {
      System.err.println("### OPL exception: " + ex.getMessage());
      ex.printStackTrace();
      status = 2;
    } catch (IloException ex) {
      System.err.println("### CONCERT exception: " + ex.getMessage());
      ex.printStackTrace();
      status = 3;
    } catch (Exception ex) {
      System.err.println("### UNEXPECTED UNKNOWN ERROR ...");
      ex.printStackTrace();
      status = 4;
    }
    System.exit(status);
  }
Esempio n. 2
0
  public boolean solve(
      double[] Pmax,
      double[] PregMax,
      double[] Emin,
      double[] Emax,
      int quartersLeftInFirstBid,
      int[] bids,
      int bidSize,
      ArrayList<FlexGraph> flexGraphs) {
    double[] Pmin = new double[Pmax.length];
    // Pre-process data
    if ((Pmin.length - quartersLeftInFirstBid) % 4 != 0) {
      int extraQuarters = 4 - ((Pmin.length - quartersLeftInFirstBid) % 4);
      Pmin = concat(Pmin, new double[extraQuarters]);
      Pmax = concat(Pmax, new double[extraQuarters]);
      PregMax = concat(PregMax, new double[extraQuarters]);
      double[] endE = new double[extraQuarters];
      for (int i = 0; i < endE.length; i++) {
        endE[i] = Emin[Emin.length - 1];
      }
      Emin = concat(Emin, endE);
      Emax = concat(Emax, endE);
    }
    this.quartersLeftInFirstBid = quartersLeftInFirstBid;

    // Solve optimization problem
    try {
      IloCplex cplex = new IloCplex();

      // for all evs
      ArrayList<IloNumVar[]> flexpowers = new ArrayList<IloNumVar[]>();
      ArrayList<IloNumVar[]> flexenergies = new ArrayList<IloNumVar[]>();
      for (int i = 0; i < flexGraphs.size(); i++) {
        FlexGraph flexGraph = flexGraphs.get(i);
        double[] energyMin = convertToDoubles(flexGraph.getEnergyMin());
        double[] energyMax = convertToDoubles(flexGraph.getEnergyMax());
        double[] powerMax = convertToDoubles(flexGraph.getPowerMax());
        // charging power
        IloNumVar[] p = cplex.numVarArray(powerMax.length, new double[powerMax.length], powerMax);
        // path
        IloNumVar[] e = cplex.numVarArray(energyMin.length, energyMin, energyMax);
        for (int j = 0; j < p.length; j++) {
          cplex.addEq(cplex.diff(e[j + 1], e[j]), cplex.prod(1.0 / 4, p[j]));
        }
        flexpowers.add(p);
        flexenergies.add(e);
      }

      // total charging power
      IloNumVar[] p = cplex.numVarArray(Pmin.length, Pmin, Pmax);

      // individual bin constraints
      for (int t = 0; t < p.length; t++) {
        ArrayList<IloNumVar> tempVars = new ArrayList<IloNumVar>();
        for (IloNumVar[] var : flexpowers) {
          if (var.length >= t + 1) {
            tempVars.add(var[t]);
          }
        }
        IloNumVar[] tempVars_array = new IloNumVar[tempVars.size()];
        tempVars.toArray(tempVars_array);
        cplex.addEq(p[t], cplex.sum(tempVars_array));
      }

      // path
      IloNumVar[] e = cplex.numVarArray(Emin.length, Emin, Emax);
      for (int i = 0; i < p.length; i++) {
        cplex.addEq(cplex.diff(e[i + 1], e[i]), cplex.prod(1.0 / 4, p[i]));
      }

      // Emin < path < Emax
      for (int i = 0; i < e.length; i++) {
        cplex.addGe(e[i], Emin[i]);
        cplex.addLe(e[i], Emax[i]);
      }

      // regulation power in each optimziation interval
      IloNumVar[] regPowerQ = cplex.numVarArray(Pmin.length, Pmin, PregMax);

      // calculate regulation power in each optimization interval
      for (int i = 0; i < regPowerQ.length; i++) {
        cplex.addEq(regPowerQ[i], cplex.diff(PregMax[i], p[i]));
      }

      // regulation bids in each hour
      // 1. max nr of bids per houd
      int hours =
          (int) Math.ceil(quartersLeftInFirstBid / 4.0)
              + (int) Math.ceil((regPowerQ.length - quartersLeftInFirstBid) / 4.0);
      int[] maxNrOfBidsPerHour = new int[hours];
      // init with max nr of bids per hour
      for (int i = 0; i < maxNrOfBidsPerHour.length; i++) {
        maxNrOfBidsPerHour[i] = Integer.MAX_VALUE;
      }
      if (quartersLeftInFirstBid > 0) {
        maxNrOfBidsPerHour[0] = bids[0];
        try {
          maxNrOfBidsPerHour[1] = bids[1];
        } catch (IndexOutOfBoundsException ew) {
          System.out.print("Emin = ");
          printArray(Emin);

          System.out.print("Emax = ");
          printArray(Emax);

          System.out.print("Pmax = ");
          printArray(Pmax);

          System.out.println("FirstBidQuarter = " + quartersLeftInFirstBid);

          System.out.print("Bids = ");
          printArray(bids);

          System.out.println("Bidsize = " + bidSize);
        }
      } else {
        maxNrOfBidsPerHour[0] = bids[1];
      }
      // 2. bids per hour
      IloIntVar[] bidsH = cplex.intVarArray(hours, new int[hours], maxNrOfBidsPerHour);
      // limit bids by provided regulation power
      for (int i = 0; i < regPowerQ.length; i++) {
        // convert Q to H
        int h = (int) Math.ceil(((i + 1) - quartersLeftInFirstBid) / 4.0);
        if (quartersLeftInFirstBid == 0) {
          h--;
        }
        // bidsH*bidSize <= regPowerQ[i]
        if (i > 0) {
          // reserve some extra regulation power
          cplex.addLe(cplex.prod(bidsH[h], bidSize), cplex.prod(0.95, regPowerQ[i]));
        } else {
          cplex.addLe(cplex.prod(bidsH[h], bidSize), cplex.prod(1, regPowerQ[i]));
        }
        // System.out.println("h = " + h + ", i=" + i);
      }

      // create model and solve it
      // cplex.addMaximize(cplex.scalProd(p,prices));
      double[] rewards = new double[bidsH.length];
      // init to rewards = 1 for all, but two first hours
      for (int i = 0; i < rewards.length; i++) {
        rewards[i] = 1;
      }
      rewards[0] = 100;
      if (rewards.length > 1) {
        rewards[1] = 100;
      }
      IloLinearNumExpr maximization = cplex.scalProd(bidsH, rewards);
      IloObjective maxObjective = cplex.addMaximize(maximization);

      cplex.setOut(null);
      cplex.solve();
      //			if(cplex.solve()) {
      //				cplex.output().println("Solution status = " + cplex.getStatus());
      //				cplex.output().println("Solution value = " + cplex.getObjValue());
      //
      //				System.out.print("Emin = ");
      //				printArray(Emin);
      //
      //				System.out.print("Emax = ");
      //				printArray(Emax);
      //
      //				System.out.print("Pmax = ");
      //				printArray(Pmax);
      //
      //				powerPath = cplex.getValues(p);
      //				System.out.print("Power = ");
      //				printArray(powerPath);
      //
      //				energyPath = cplex.getValues(e);
      //				System.out.print("Energy = ");
      //				printArray(energyPath);
      //
      //				regPower = cplex.getValues(regPowerQ);
      //				System.out.print("RegPower = ");
      //				printArray(regPower);
      //
      //				bidsN = new int[bidsH.length];
      //				for(int i = 0; i < bidsN.length; i++) {
      //					bidsN[i] = (int) Math.round(cplex.getValue(bidsH[i]));
      //				}
      // shift bids right if no quarter left in current bid slot -- hack-ish
      if (quartersLeftInFirstBid == 0) {
        bidsN = concat(new int[1], bidsN);
      }
      //
      //				System.out.print("Bids = ");
      //				printArray(bidsN);
      //
      //				this.bidSize = bidSize;
      //			}

      // stage two

      // System.out.println((int) );
      //			System.out.println("sum = " + cplex.getValue(cplex.sum(bidsH)));
      //			System.out.println(bidsH[0].getUB());;
      //			System.out.println((int) Math.round(cplex.getValue(bidsH[0])));
      //			bidsH[0].setMin((int) Math.round(cplex.getValue(bidsH[0])));
      //			.setUB(cplex.getValue(bidsH[0]));
      // cplex.addEq(bidsH[1], (int) Math.round(cplex.getValue(bidsH[1])));
      // cplex.addGe(bidsH[1], (int) Math.round(cplex.getValue(bidsH[1])));
      double bid1 = cplex.getValue(bidsH[0]);
      double bid2 = 0;
      if (bidsH.length > 1) {
        bid2 = cplex.getValue(bidsH[1]);
      }
      int totalBids = 0;
      for (int i = 0; i < bidsH.length; i++) {
        totalBids = totalBids + (int) Math.round(cplex.getValue(bidsH[i]));
      }
      cplex.addGe(cplex.sum(bidsH), totalBids);
      cplex.addLe(bid1, bidsH[0]);
      // cplex.getValue(bidsH[1]);
      if (bidsH.length > 1) {
        cplex.addLe(bid2, bidsH[1]);
      }

      cplex.remove(maxObjective);
      IloQuadNumExpr minimization = cplex.quadNumExpr();
      double[] coeff = new double[p.length];
      for (int i = 0; i < p.length; i++) {
        coeff[i] = 1;
      }
      minimization.addTerms(coeff, p, p);
      cplex.addMinimize(minimization);

      cplex.setOut(null);
      if (cplex.solve()) {
        //				cplex.output().println("Solution status = " + cplex.getStatus());
        //				cplex.output().println("Solution value = " + cplex.getObjValue());
        //
        //				System.out.print("Emin = ");
        //				printArray(Emin);
        //
        //				System.out.print("Emax = ");
        //				printArray(Emax);
        //
        //				System.out.print("Pmax = ");
        //				printArray(Pmax);
        //
        powerPath = cplex.getValues(p);
        System.out.print("Power = ");
        printArray(powerPath);

        energyPath = cplex.getValues(e);
        //				System.out.print("Energy = ");
        //				printArray(energyPath);

        regPower = cplex.getValues(regPowerQ);
        System.out.print("RegPower = ");
        printArray(regPower);

        bidsN = new int[bidsH.length];
        for (int i = 0; i < bidsN.length; i++) {
          bidsN[i] = (int) Math.round(cplex.getValue(bidsH[i]));
        }
        // shift bids right if no quarter left in current bid slot -- hack-ish
        if (quartersLeftInFirstBid == 0) {
          bidsN = concat(new int[1], bidsN);
        }

        System.out.print("Bids = ");
        printArray(bidsN);

        this.bidSize = bidSize;
      }

      for (int i = 0; i < flexpowers.size(); i++) {
        flexGraphs.get(i).setSolutionPath(cplex.getValues(flexenergies.get(i)));
      }
      return true;
    } catch (IloException e) {
      System.err.println("Concert exception caught: " + e);
      e.printStackTrace();
      return false;
    }
  }