Search in sources :

Example 1 with IloCplex

use of ilog.cplex.IloCplex in project Stochastic-Inventory by RobinChen121.

the class MipCashConstraint method findsCSNewPenalty.

/**
 *  this mip model consider penalty cost for negative cash
 * @return s, C, S
 */
public double[][] findsCSNewPenalty(double penaltyCost) {
    double[] varx = null;
    double[] vars;
    double[] varI = null;
    double[] varB = null;
    try {
        int T = distributions.length;
        IloCplex cplex = new IloCplex();
        // no cplex logging information
        cplex.setOut(null);
        // parameter values in array
        double[] K = new double[T];
        double[] h = new double[T];
        double[] v = new double[T];
        double[] p = new double[T];
        Arrays.fill(K, fixOrderCost);
        Arrays.fill(h, holdingCost);
        Arrays.fill(v, variCost);
        Arrays.fill(p, price);
        // decision variables
        // whether ordering in period t
        IloIntVar[] x = cplex.boolVarArray(T);
        // whether it is lost sale in period t
        IloIntVar[] delta = cplex.boolVarArray(T);
        // whether it is negative cash in the end of period t
        IloIntVar[] delta2 = cplex.boolVarArray(T);
        // order-up-to level in period t
        IloNumVar[] s = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        IloNumVar[] I = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // end-of-period cash in each period
        IloNumVar[] B = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // objective function
        IloNumExpr finalCash = cplex.sum(cplex.prod(salvageValue, I[T - 1]), B[T - 1]);
        cplex.addMaximize(finalCash);
        // constraints
        // cash constraint: B_t >= Kx_t + v(s_t - I_{t-1})
        // cash flow: B_{t} = B_{t - 1} + p_t(s_t - I_t) - hI_t - v(s_t - I_{t-1}) - Kx_t
        // s_t >= I_{t-1}
        // s_t - I_{t-1} <= delta*M
        // s_t - d_t <= I_{t} + (1-delta_t)M
        // s_t - d_t >= I_{t} - (1-delta_t)M
        // I_t <= delta_t M
        IloNumExpr realDemand = cplex.numExpr();
        IloNumExpr tRevenue = cplex.numExpr();
        IloNumExpr tHoldCost = cplex.numExpr();
        IloNumExpr tPurchaseCost = cplex.numExpr();
        IloNumExpr tFixCost = cplex.numExpr();
        IloNumExpr tTotalCost = cplex.numExpr();
        IloNumExpr tTotalOrderCost = cplex.numExpr();
        for (int i = 0; i < T; i++) {
            realDemand = cplex.diff(s[i], I[i]);
            tRevenue = cplex.prod(p[i], realDemand);
            tHoldCost = cplex.prod(h[i], I[i]);
            tFixCost = cplex.prod(K[i], x[i]);
            cplex.addGe(cplex.diff(B[i], B[i]), cplex.prod(penaltyCost, cplex.diff(B[i], cplex.prod(1000000, cplex.diff(1, delta[i])))));
            cplex.addLe(cplex.diff(B[i], B[i]), cplex.prod(penaltyCost, cplex.diff(B[i], cplex.prod(1000000, cplex.diff(1, delta[i])))));
            cplex.addLe(B[i], cplex.prod(10000000, cplex.diff(1, delta[i])));
            if (i == 0) {
                tPurchaseCost = cplex.prod(v[i], cplex.diff(s[i], iniInventory));
                tTotalOrderCost = cplex.sum(tPurchaseCost, tFixCost);
                tTotalCost = cplex.sum(tHoldCost, cplex.sum(tTotalOrderCost, overheadCost));
                cplex.addLe(iniInventory, s[i]);
                cplex.addEq(cplex.diff(B[i], iniCash), cplex.diff(tRevenue, tTotalCost));
                cplex.addLe(cplex.sum(overheadCost, tTotalOrderCost), iniCash);
                cplex.addGe(distributions[i].getMean(), cplex.diff(s[i], I[i]));
                cplex.addLe(cplex.diff(s[i], iniInventory), cplex.prod(x[i], 10000));
                cplex.addGe(cplex.diff(s[i], iniInventory), 0);
            } else {
                tPurchaseCost = cplex.prod(v[i], cplex.diff(s[i], I[i - 1]));
                tTotalOrderCost = cplex.sum(tPurchaseCost, tFixCost);
                tTotalCost = cplex.sum(tHoldCost, cplex.sum(tTotalOrderCost, overheadCost));
                // s_t >= I_{t-1}
                cplex.addLe(I[i - 1], s[i]);
                // B_{t} = B_{t - 1} + p_t(s_t - I_t) - hI_t - v(s_t - I_{t-1}) - Kx_t
                cplex.addEq(cplex.diff(B[i], B[i - 1]), cplex.diff(tRevenue, tTotalCost));
                // B_t >= Kx_t + v(s_t - I_{t-1})
                cplex.addLe(cplex.sum(overheadCost, tTotalOrderCost), B[i - 1]);
                // s_t-I_t <= d_t
                cplex.addGe(distributions[i].getMean(), cplex.diff(s[i], I[i]));
                // s_t-I_{t-1} <= x_t*10000
                cplex.addLe(cplex.diff(s[i], I[i - 1]), cplex.prod(x[i], 10000));
                // s_t - I_{t-1} <= delta*M
                cplex.addGe(cplex.diff(s[i], I[i - 1]), 0);
                // I_t <= delta_t * M
                cplex.addLe(I[i], cplex.prod(delta[i], 10000));
                // s_t - d_t <= I_{t} + (1-delta_t)M
                cplex.addLe(cplex.diff(s[i], distributions[i].getMean()), cplex.sum(I[i], cplex.prod(10000, cplex.diff(1, delta[i]))));
                // s_t - d_t >= I_{t} - (1-delta_t)M
                cplex.addGe(cplex.diff(s[i], distributions[i].getMean()), cplex.diff(I[i], cplex.prod(10000, cplex.diff(1, delta[i]))));
            }
        }
        if (cplex.solve()) {
            cplex.output().println("Solution status = " + cplex.getStatus());
            cplex.output().println("Solution value = " + cplex.getObjValue());
            varx = cplex.getValues(x);
            vars = cplex.getValues(s);
            varI = cplex.getValues(I);
            varB = cplex.getValues(B);
            System.out.println("x = ");
            System.out.println(Arrays.toString(varx));
            System.out.println("order-up-to level = ");
            System.out.println(Arrays.toString(vars));
            System.out.println("I = ");
            System.out.println(Arrays.toString(varI));
            System.out.println("B = ");
            System.out.println(Arrays.toString(varB));
        }
        cplex.end();
    } catch (IloException e) {
        System.err.println("Concert exception '" + e + "' caught");
    }
    return heuristicFindsCS(varx, varI, varB);
}
Also used : IloCplex(ilog.cplex.IloCplex) IloIntVar(ilog.concert.IloIntVar) IloNumVar(ilog.concert.IloNumVar) IloException(ilog.concert.IloException) IloNumExpr(ilog.concert.IloNumExpr)

Example 2 with IloCplex

use of ilog.cplex.IloCplex in project Stochastic-Inventory by RobinChen121.

the class MipCashConstraint method findsCSPieceWise.

/**
 * this mip model is for lost sale, lost sale quantity is not a decision variable;
 * order-up-to level is a decision variable in this model.
 *
 * I^+ is represented by piecewise model
 *
 * revise the above model, but it seems the results of the two linear models are very similar
 *
 * @return s, C, S
 */
public double[][] findsCSPieceWise() {
    int T = distributions.length;
    double[] varz = null;
    double[] varS;
    double[] varx = null;
    double[] varxplus = null;
    double[] varR = null;
    int M = 1000000;
    try {
        IloCplex cplex = new IloCplex();
        // no cplex logging information
        cplex.setOut(null);
        // parameter values in array
        double[] K = new double[T];
        double[] h = new double[T];
        double[] v = new double[T];
        double[] p = new double[T];
        Arrays.fill(K, fixOrderCost);
        Arrays.fill(h, holdingCost);
        Arrays.fill(v, variCost);
        Arrays.fill(p, price);
        // decision variables
        // whether ordering in period t
        IloIntVar[] z = cplex.boolVarArray(T);
        // whether the ordering cycle is from period i to period j
        IloNumVar[][] P = new IloNumVar[T][T];
        for (int i = 0; i < P.length; i++) for (int j = 0; j < P.length; j++) P[i][j] = cplex.boolVar();
        // whether it is lost sale in period t
        IloIntVar[] delta = cplex.boolVarArray(T);
        // order-up-to level in period t
        IloNumVar[] S = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // inventory
        IloNumVar[] x = cplex.numVarArray(T, -Double.MAX_VALUE, Double.MAX_VALUE);
        IloNumVar[] xplus = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // may be useless
        IloNumVar[] xminus = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // end-of-period cash in each period
        IloNumVar[] R = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // objective function
        IloNumExpr finalCash = cplex.sum(cplex.prod(salvageValue, xplus[T - 1]), R[T - 1]);
        cplex.addMaximize(finalCash);
        IloNumExpr realDemand = cplex.numExpr();
        IloNumExpr tRevenue = cplex.numExpr();
        IloNumExpr tHoldCost = cplex.numExpr();
        IloNumExpr tPurchaseCost = cplex.numExpr();
        IloNumExpr tFixCost = cplex.numExpr();
        IloNumExpr tTotalCost = cplex.numExpr();
        IloNumExpr tTotalOrderCost = cplex.numExpr();
        int segmentNum = 5;
        double[] probs = new double[segmentNum];
        double segmentNumFloat = (float) segmentNum;
        double prob = (float) 1.0 / segmentNumFloat;
        Arrays.fill(probs, prob);
        int nbSamples = 10000;
        // sum lambdas from period i to period j
        double[][] sumLambdas = new double[T][T];
        for (int i = 0; i < T; i++) for (int j = 0; j < T; j++) {
            if (i > j)
                sumLambdas[i][j] = 0;
            else {
                for (int k = i; k <= j; k++) sumLambdas[i][j] += distributions[k].getMean();
            }
        }
        for (int t = 0; t < T; t++) {
            realDemand = cplex.diff(S[t], xplus[t]);
            tRevenue = cplex.prod(p[t], realDemand);
            tHoldCost = cplex.prod(h[t], xplus[t]);
            tFixCost = cplex.prod(K[t], z[t]);
            // sum Pjt == 1
            IloLinearNumExpr sumPjt;
            IloLinearNumExpr sumzjt;
            IloLinearNumExpr sumzjt2;
            sumPjt = cplex.linearNumExpr();
            for (int j = 0; j <= t; j++) sumPjt.addTerm(1, P[j][t]);
            // upper triangle
            cplex.addEq(sumPjt, 1);
            for (int j = t + 1; j < T; j++) // other Pjt = 0, or else cannot output values
            cplex.addEq(P[j][t], 0);
            // Pjt >= z_j - sum_{k = j+1}^{t}z_k
            // sum_{j=1}{t}z_j == 0 => P[0][t] == 1, this constraints are important for the extra piecewise constraints
            sumzjt2 = cplex.linearNumExpr();
            for (int j = 0; j <= t; j++) {
                sumzjt = cplex.linearNumExpr();
                for (int k = j + 1; k <= t; k++) sumzjt.addTerm(z[k], 1);
                cplex.addGe(P[j][t], cplex.diff(z[j], sumzjt));
                sumzjt2.addTerm(z[j], 1);
            }
            cplex.addGe(sumzjt2, cplex.diff(1, P[0][t]));
            // piecewise constraints
            // in each period t, get its conditional expectations for S_{jt}, j = 1, 2, ..., t
            long[] seed = { 1, 2, 3, 4, 5, 6 };
            double[][] conditionExpects = new double[t + 1][];
            IloLinearNumExpr sumdP = cplex.linearNumExpr();
            for (int j = 0; j <= t; j++) {
                Distribution[] distributions2 = new Distribution[1];
                distributions2[0] = new PoissonDist(sumLambdas[j][t]);
                PiecewiseComplementaryFirstOrderLossFunction pwcfolf = new PiecewiseComplementaryFirstOrderLossFunction(distributions2, seed);
                conditionExpects[j] = pwcfolf.getConditionalExpectations(probs, nbSamples);
                // System.out.println("max error is: " + pwcfolf.getMaxApproximationError(probs, nbSamples));
                sumdP.addTerm(P[j][t], sumLambdas[j][t]);
            }
            IloLinearNumExpr sumPrdP = cplex.linearNumExpr();
            IloNumExpr xsumdP = cplex.linearNumExpr();
            for (int i = 0; i < segmentNum; i++) {
                double slope = 0;
                double interval = 0;
                for (int k = 0; k <= i; k++) {
                    slope += probs[k];
                }
                xsumdP = cplex.prod(cplex.sum(x[t], sumdP), slope);
                for (int j = 0; j <= t; j++) {
                    for (int k = 0; k <= i; k++) {
                        interval -= probs[k] * conditionExpects[j][k];
                    }
                    sumPrdP.addTerm(interval, P[j][t]);
                }
                cplex.addGe(xplus[t], cplex.sum(xsumdP, sumPrdP));
            }
            // inventory flow: d_t = S_t - I_t
            cplex.addEq(distributions[t].getMean(), cplex.diff(S[t], x[t]));
            // relation of inventory: x_t = x_t^+ - x_t^-
            cplex.addEq(x[t], cplex.diff(xplus[t], xminus[t]));
            if (t == 0) {
                tPurchaseCost = cplex.prod(v[t], cplex.diff(S[t], iniInventory));
                tTotalOrderCost = cplex.sum(tPurchaseCost, tFixCost);
                tTotalCost = cplex.sum(tHoldCost, cplex.sum(tTotalOrderCost, overheadCost));
                // cash flow: R_{t} = R_{0} + p_t(S_t - x^+_t) - hx^+_t - v(S_t - x^+_{t-1}) - Kz_t
                cplex.addEq(cplex.diff(R[t], iniCash), cplex.diff(tRevenue, tTotalCost));
                // cash constraint: R_{0} >= Kz_t + v(S_t - x^+_{t-1})
                cplex.addLe(cplex.sum(overheadCost, tTotalOrderCost), iniCash);
                // z_t = 1 if S_1 - x^+_0 > 0
                // S_1 - x^+_0 >= 0
                // S_1 - x^+_0 <= z_t*M
                cplex.addGe(cplex.diff(S[t], iniInventory), 0);
                cplex.addLe(cplex.diff(S[t], iniInventory), cplex.prod(z[t], M));
            } else {
                tPurchaseCost = cplex.prod(v[t], cplex.diff(S[t], xplus[t - 1]));
                tTotalOrderCost = cplex.sum(tPurchaseCost, tFixCost);
                tTotalCost = cplex.sum(tHoldCost, cplex.sum(tTotalOrderCost, overheadCost));
                // cash flow: R_{t} = R_{0} + p_t(S_t - x^+_t) - hx^+_t - v(S_t - x^+_{t-1}) - Kz_t
                cplex.addEq(cplex.diff(R[t], R[t - 1]), cplex.diff(tRevenue, tTotalCost));
                // cash constraint: R_{0} >= Kz_t + v(S_t - x^+_{t-1})
                cplex.addLe(cplex.sum(overheadCost, tTotalOrderCost), R[t - 1]);
                // z_t = 1 if S_t - x^+_{t-1} > 0
                // S_t - x^+_{t-1} >= 0
                // S_t - x^+_{t-1} <= z_t*M
                cplex.addGe(cplex.diff(S[t], xplus[t - 1]), 0);
                cplex.addLe(cplex.diff(S[t], xplus[t - 1]), cplex.prod(z[t], 10000));
            }
            // x^+_t = max{S_t - d_t, 0}
            // x^+_t <= delta_t * M
            // S_t - d_t <= x^+_t + (1-delta_t)*M
            // S_t - d_t >= x^+_t - (1-delta_t)*M
            // s_t-I_{t-1} <= x_t*10000
            cplex.addLe(xplus[t], cplex.prod(delta[t], 10000));
            cplex.addLe(cplex.diff(S[t], distributions[t].getMean()), cplex.sum(xplus[t], cplex.prod(10000, cplex.diff(1, delta[t]))));
            cplex.addGe(cplex.diff(S[t], distributions[t].getMean()), cplex.diff(xplus[t], cplex.prod(10000, cplex.diff(1, delta[t]))));
        }
        if (cplex.solve()) {
            cplex.output().println("Solution status = " + cplex.getStatus());
            cplex.output().println("Solution value = " + cplex.getObjValue());
            System.out.println(cplex.getStatus());
            System.out.println("Solution value = " + cplex.getObjValue());
            varz = cplex.getValues(z);
            varS = cplex.getValues(S);
            varxplus = cplex.getValues(xplus);
            varx = cplex.getValues(x);
            varR = cplex.getValues(R);
            double[][] varP = new double[T][T];
            for (int i = 0; i < T; i++) for (int j = 0; j < T; j++) varP[i][j] = cplex.getValue(P[i][j]);
            System.out.println("z = ");
            System.out.println(Arrays.toString(varz));
            System.out.println("order-up-to level = ");
            System.out.println(Arrays.toString(varS));
            System.out.println("xplus = ");
            System.out.println(Arrays.toString(varxplus));
            System.out.println("x = ");
            System.out.println(Arrays.toString(varx));
            System.out.println("R = ");
            System.out.println(Arrays.toString(varR));
            System.out.println("P = ");
            System.out.println(Arrays.deepToString(varP));
        }
        cplex.end();
    } catch (IloException e) {
        System.err.println("Concert exception '" + e + "' caught");
    }
    return heuristicFindsCS(varz, varxplus, varR);
}
Also used : PoissonDist(umontreal.ssj.probdist.PoissonDist) IloCplex(ilog.cplex.IloCplex) IloIntVar(ilog.concert.IloIntVar) IloNumExpr(ilog.concert.IloNumExpr) ContinuousDistribution(umontreal.ssj.probdist.ContinuousDistribution) Distribution(umontreal.ssj.probdist.Distribution) IloLinearNumExpr(ilog.concert.IloLinearNumExpr) IloNumVar(ilog.concert.IloNumVar) IloException(ilog.concert.IloException)

Example 3 with IloCplex

use of ilog.cplex.IloCplex in project Stochastic-Inventory by RobinChen121.

the class MipCashConstraint method findsCSLostSale.

/**
 *  this mip model take lost sale as a decision variable
 * @return s, C, S
 */
public double[][] findsCSLostSale() {
    double[] varx = null;
    double[] vary;
    double[] varw;
    double[] varI = null;
    double[] varB = null;
    ;
    try {
        int T = distributions.length;
        IloCplex cplex = new IloCplex();
        // no cplex logging information
        cplex.setOut(null);
        // parameter values in array
        double[] S = new double[T];
        double[] h = new double[T];
        double[] v = new double[T];
        double[] p = new double[T];
        Arrays.fill(S, fixOrderCost);
        Arrays.fill(h, holdingCost);
        Arrays.fill(v, variCost);
        Arrays.fill(p, price);
        // decision variables
        // whether ordering in period t
        IloIntVar[] x = cplex.boolVarArray(T);
        // how much to order in period t
        IloNumVar[] y = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // how much lost sales in period t
        IloNumVar[] w = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        IloNumVar[] I = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // end-of-period cash in each period
        IloNumVar[] B = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // objective function
        IloNumExpr finalCash = cplex.sum(cplex.prod(salvageValue, I[T - 1]), B[T - 1]);
        cplex.addMaximize(finalCash);
        // constraints
        // inventory equality: I_t = I_{t-1} + y_t - (d_t - w_t)
        // cash flow: B_{t} = B_{t - 1} + p_t(d_t - w_t) - hI_t - vy_t - Sx_t
        // relationship between x_t and y_t
        // cash constraint
        IloNumExpr realDemand = cplex.numExpr();
        IloNumExpr tRevenue = cplex.numExpr();
        IloNumExpr tHoldCost = cplex.numExpr();
        IloNumExpr tPurchaseCost = cplex.numExpr();
        IloNumExpr tFixCost = cplex.numExpr();
        IloNumExpr tTotalCost = cplex.numExpr();
        IloNumExpr tTotalOrderCost = cplex.numExpr();
        for (int i = 0; i < T; i++) {
            realDemand = cplex.diff(distributions[i].getMean(), w[i]);
            tRevenue = cplex.prod(p[i], realDemand);
            tHoldCost = cplex.prod(h[i], I[i]);
            tPurchaseCost = cplex.prod(v[i], y[i]);
            tFixCost = cplex.prod(S[i], x[i]);
            tTotalOrderCost = cplex.sum(tPurchaseCost, tFixCost);
            tTotalCost = cplex.sum(tHoldCost, tTotalOrderCost);
            if (i == 0) {
                cplex.addEq(cplex.diff(I[i], iniInventory), cplex.diff(y[i], realDemand));
                cplex.addEq(cplex.diff(B[i], iniCash), cplex.diff(tRevenue, tTotalCost));
                cplex.addLe(tTotalOrderCost, iniCash);
            } else {
                cplex.addEq(cplex.diff(I[i], I[i - 1]), cplex.diff(cplex.sum(y[i], w[i]), distributions[i].getMean()));
                cplex.addEq(cplex.diff(B[i], B[i - 1]), cplex.diff(tRevenue, tTotalCost));
                cplex.addLe(tTotalOrderCost, B[i - 1]);
            }
            cplex.addLe(y[i], cplex.prod(x[i], 10000));
        }
        if (cplex.solve()) {
            cplex.output().println("Solution status = " + cplex.getStatus());
            cplex.output().println("Solution value = " + cplex.getObjValue());
            varx = cplex.getValues(x);
            vary = cplex.getValues(y);
            varw = cplex.getValues(w);
            varI = cplex.getValues(I);
            varB = cplex.getValues(B);
            System.out.println("x = ");
            System.out.println(Arrays.toString(varx));
            System.out.println("y = ");
            System.out.println(Arrays.toString(vary));
            System.out.println("w = ");
            System.out.println(Arrays.toString(varw));
            System.out.println("I = ");
            System.out.println(Arrays.toString(varI));
            System.out.println("B = ");
            System.out.println(Arrays.toString(varB));
        }
        cplex.end();
    } catch (IloException e) {
        System.err.println("Concert exception '" + e + "' caught");
    }
    return heuristicFindsCS(varx, varI, varB);
}
Also used : IloCplex(ilog.cplex.IloCplex) IloIntVar(ilog.concert.IloIntVar) IloNumVar(ilog.concert.IloNumVar) IloException(ilog.concert.IloException) IloNumExpr(ilog.concert.IloNumExpr)

Example 4 with IloCplex

use of ilog.cplex.IloCplex in project Stochastic-Inventory by RobinChen121.

the class MipRS method solveCPlex.

/**
 *****************************************************************
 * solve mip model by cplex, piecewise approximation
 * @note: MipRS class must be initialized before invoking this method
 */
public double solveCPlex() {
    // piecewise approximation values
    // H \approx aS+b, a = \sum_{i=1}^w prob[i], b = \sum_{i=1}^w prob[i]*mean[i], multiply sigma[i][j] for general norm
    // plus error for upper bound
    double[] prob;
    double[] means;
    double error;
    switch(partionNum) {
        case 4:
            prob = new double[] { 0.187555, 0.312445, 0.312445, 0.187555 };
            means = new double[] { -1.43535, -0.415223, 0.415223, 1.43535 };
            error = 0.0339052;
            break;
        case 10:
            prob = new double[] { 0.04206108420763477, 0.0836356495308449, 0.11074334596058821, 0.1276821455299152, 0.13587777477101692, 0.13587777477101692, 0.1276821455299152, 0.11074334596058821, 0.0836356495308449, 0.04206108420763477 };
            means = new double[] { -2.133986195498256, -1.3976822972668839, -0.918199946431143, -0.5265753462727588, -0.17199013069262026, 0.17199013069262026, 0.5265753462727588, 0.918199946431143, 1.3976822972668839, 2.133986195498256 };
            error = 0.005885974956458359;
            break;
        default:
            prob = new double[] { 0.187555, 0.312445, 0.312445, 0.187555 };
            means = new double[] { -1.43535, -0.415223, 0.415223, 1.43535 };
            error = 0.0339052;
            break;
    }
    try {
        IloCplex cplex = new IloCplex();
        // no cplex logging information
        cplex.setOut(null);
        // parameter values in array
        double[] S = new double[T];
        double[] h = new double[T];
        double[] v = new double[T];
        double[] pai = new double[T];
        Arrays.fill(S, fixOrderCost);
        Arrays.fill(h, holdingCost);
        Arrays.fill(v, variCost);
        Arrays.fill(pai, penaltyCost);
        // decision variables
        // whether ordering in period t
        IloIntVar[] x = cplex.boolVarArray(T);
        IloNumVar[][] P = new IloNumVar[T][T];
        for (int i = 0; i < P.length; i++) for (int j = 0; j < P.length; j++) P[i][j] = cplex.boolVar();
        IloNumVar[] I = cplex.numVarArray(T, -Double.MAX_VALUE, Double.MAX_VALUE);
        // positive inventory
        IloNumVar[] Iplus = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        // minus inventory
        IloNumVar[] Iminus = cplex.numVarArray(T, 0.0, Double.MAX_VALUE);
        double I0 = iniInventory;
        // IloNumVar I0 = cplex.numVar(-Double.MAX_VALUE, Double.MAX_VALUE);
        // objective function
        IloLinearNumExpr setupCosts = cplex.linearNumExpr();
        IloLinearNumExpr holdCosts = cplex.linearNumExpr();
        IloLinearNumExpr penaCosts = cplex.linearNumExpr();
        IloNumExpr variCosts = cplex.numExpr();
        setupCosts.addTerms(x, S);
        holdCosts.addTerms(h, Iplus);
        penaCosts.addTerms(pai, Iminus);
        variCosts = cplex.prod(v[0], cplex.diff(I[T - 1], I0));
        cplex.addMinimize(cplex.sum(setupCosts, variCosts, holdCosts, penaCosts));
        // Q_t >= 0
        for (int t = 0; t < T; t++) {
            if (t == 0) {
                cplex.addLe(cplex.sum(I[t], meanDemand[t] - I0), cplex.prod(x[t], M));
                cplex.addGe(cplex.sum(I[t], meanDemand[t]), I0);
            } else {
                cplex.addLe(cplex.sum(cplex.sum(I[t], meanDemand[t]), cplex.negative(I[t - 1])), cplex.prod(x[t], M));
                cplex.addGe(cplex.sum(I[t], meanDemand[t]), I[t - 1]);
            }
        }
        // sum Pjt == 1
        IloLinearNumExpr sumPjt;
        IloLinearNumExpr sumxjt;
        IloLinearNumExpr sumxjt2;
        for (int t = 0; t < T; t++) {
            sumPjt = cplex.linearNumExpr();
            for (int j = 0; j <= t; j++) sumPjt.addTerm(1, P[j][t]);
            // upper triangle
            cplex.addEq(sumPjt, 1);
            for (int j = t + 1; j < T; j++) // other Pjt = 0, or else cannot output values
            cplex.addEq(P[j][t], 0);
        }
        // sum_{j=1}{t}x_j == 0 => P[0][t] == 1, this constraints are important for the extra piecewise constraints
        for (int t = 0; t < T; t++) {
            sumxjt2 = cplex.linearNumExpr();
            for (int j = 0; j <= t; j++) {
                sumxjt = cplex.linearNumExpr();
                for (int k = j + 1; k <= t; k++) sumxjt.addTerm(x[k], 1);
                cplex.addGe(P[j][t], cplex.diff(x[j], sumxjt));
                sumxjt2.addTerm(x[j], 1);
            }
            cplex.addGe(sumxjt2, cplex.diff(1, P[0][t]));
        }
        // for computing G(y)
        switch(gyCx) {
            case COMPUTG:
                cplex.addEq(x[0], 0);
                break;
            case COMPUTC:
                cplex.addEq(x[0], 1);
            default:
                break;
        }
        // piecewise constraints
        IloNumExpr Ipk;
        IloLinearNumExpr PSigma;
        IloNumExpr pmeanPSigma;
        for (int t = 0; t < T; t++) {
            for (int i = 0; i < partionNum; i++) {
                PSigma = cplex.linearNumExpr();
                double pik = Arrays.stream(prob).limit(i + 1).sum();
                Ipk = cplex.prod(I[t], pik);
                double pmean = 0;
                for (int k = 0; k <= i; k++) pmean += prob[k] * means[k];
                for (int k = 0; k <= t; k++) PSigma.addTerm(P[k][t], conSigma[k][t]);
                // upper bound
                pmeanPSigma = cplex.prod(pmean, PSigma);
                IloNumExpr IpkMinuspmeanPSigma = cplex.diff(Ipk, pmeanPSigma);
                switch(boundCriteria) {
                    case UPBOUND:
                        // Iplus
                        cplex.addGe(Iplus[t], cplex.sum(IpkMinuspmeanPSigma, cplex.prod(error, PSigma)));
                        cplex.addGe(Iplus[t], cplex.prod(error, PSigma));
                        // Iminus
                        cplex.addGe(cplex.sum(Iminus[t], I[t]), cplex.sum(IpkMinuspmeanPSigma, cplex.prod(error, PSigma)));
                        cplex.addGe(cplex.sum(Iminus[t], I[t]), cplex.prod(error, PSigma));
                        break;
                    case LOWBOUND:
                        // Iplus
                        cplex.addGe(Iplus[t], IpkMinuspmeanPSigma);
                        // not necessary
                        cplex.addGe(Iplus[t], 0);
                        // Iminus
                        cplex.addGe(cplex.sum(Iminus[t], I[t]), IpkMinuspmeanPSigma);
                        cplex.addGe(cplex.sum(Iminus[t], I[t]), 0);
                        break;
                    default:
                        break;
                }
            }
        }
        // add another piecewise constraints, make results more robust
        // use piecewise expression, equal to the above expressions
        // P_{it} == 1 => H_t = piecewise; B_t = piecewise
        IloNumExpr HMinusPiecewise;
        IloNumExpr BMinusPiecewise;
        for (int t = 0; t < T; t++) for (int j = 0; j <= t; j++) {
            // Iplus
            double[] slopes = new double[partionNum + 1];
            double[] breakPointXCoor = means;
            slopes[0] = 0;
            for (int k = 1; k <= partionNum; k++) slopes[k] = slopes[k - 1] + prob[k - 1];
            double fa = 0;
            // require partionNum to be even, or else fa = 1/2 (prob[k]means[k] + prob[k+1]means[k+1]), k=(parNum-1)/2
            for (int k = 0; k < partionNum / 2; k++) fa -= prob[k] * means[k];
            if (boundCriteria == BoundCriteria.UPBOUND)
                fa = error + fa;
            HMinusPiecewise = cplex.diff(cplex.prod(Iplus[t], 1 / conSigma[j][t]), cplex.piecewiseLinear(cplex.prod(I[t], 1 / conSigma[j][t]), breakPointXCoor, slopes, 0, fa));
            cplex.addLe(HMinusPiecewise, cplex.prod(M, cplex.diff(1, P[j][t])));
            cplex.addGe(HMinusPiecewise, cplex.prod(-M, cplex.diff(1, P[j][t])));
            // Iminus
            slopes[0] = -1;
            for (int k = 1; k <= partionNum; k++) slopes[k] = slopes[k - 1] + prob[k - 1];
            BMinusPiecewise = cplex.diff(cplex.prod(Iminus[t], 1 / conSigma[j][t]), cplex.piecewiseLinear(cplex.prod(I[t], 1 / conSigma[j][t]), breakPointXCoor, slopes, 0, fa));
            cplex.addLe(BMinusPiecewise, cplex.prod(M, cplex.diff(1, P[j][t])));
            cplex.addGe(BMinusPiecewise, cplex.prod(-M, cplex.diff(1, P[j][t])));
        }
        if (cplex.solve()) {
            double[] varx = cplex.getValues(x);
            double[] varI = cplex.getValues(I);
            double[] varIplus = cplex.getValues(Iplus);
            double[] varIminus = cplex.getValues(Iminus);
            double[][] varP = new double[T][T];
            for (int i = 0; i < T; i++) for (int j = 0; j < T; j++) varP[i][j] = cplex.getValue(P[i][j]);
            System.out.println("Solution value = " + cplex.getObjValue());
            if (outputResults == true) {
                System.out.println("Solution status = " + cplex.getStatus());
                System.out.println("number of constriants are:" + cplex.getNcols());
                System.out.println("number of variables are:" + (T * T + 4 * T));
                System.out.println("x = ");
                System.out.println(Arrays.toString(varx));
                System.out.println("I = ");
                System.out.println(Arrays.toString(varI));
                String bound = boundCriteria == BoundCriteria.LOWBOUND ? "lower bound" : "upper bound";
                System.out.println("Iplus " + bound + " = ");
                System.out.println(Arrays.toString(varIplus));
                System.out.println("Iminus " + bound + "  = ");
                System.out.println(Arrays.toString(varIminus));
                System.out.println("P = ");
                System.out.println(Arrays.deepToString(varP));
            }
            double finalOptValue = cplex.getObjValue();
            cplex.end();
            return finalOptValue;
        }
    } catch (IloException e) {
        System.err.println("Concert exception '" + e + "' caught");
    }
    return 0;
}
Also used : IloCplex(ilog.cplex.IloCplex) IloIntVar(ilog.concert.IloIntVar) IloNumExpr(ilog.concert.IloNumExpr) IloLinearNumExpr(ilog.concert.IloLinearNumExpr) IloNumVar(ilog.concert.IloNumVar) IloException(ilog.concert.IloException)

Example 5 with IloCplex

use of ilog.cplex.IloCplex in project Stochastic-Inventory by RobinChen121.

the class MipRSPM method solveCallBack.

public double solveCallBack() {
    // piecewise approximation values
    // H \approx aS+b, a = \sum_{i=1}^w prob[i], b = \sum_{i=1}^w prob[i]*mean[i], multiply sigma[i][j] for general norm
    // plus error for upper bound
    double[] prob;
    double[] means;
    double error;
    switch(partionNum) {
        case 4:
            prob = new double[] { 0.187555, 0.312445, 0.312445, 0.187555 };
            means = new double[] { -1.43535, -0.415223, 0.415223, 1.43535 };
            error = 0.0339052;
            break;
        case 10:
            prob = new double[] { 0.04206108420763477, 0.0836356495308449, 0.11074334596058821, 0.1276821455299152, 0.13587777477101692, 0.13587777477101692, 0.1276821455299152, 0.11074334596058821, 0.0836356495308449, 0.04206108420763477 };
            means = new double[] { -2.133986195498256, -1.3976822972668839, -0.918199946431143, -0.5265753462727588, -0.17199013069262026, 0.17199013069262026, 0.5265753462727588, 0.918199946431143, 1.3976822972668839, 2.133986195498256 };
            error = 0.005885974956458359;
            break;
        default:
            prob = new double[] { 0.187555, 0.312445, 0.312445, 0.187555 };
            means = new double[] { -1.43535, -0.415223, 0.415223, 1.43535 };
            error = 0.0339052;
            break;
    }
    try {
        IloCplex cplex = new IloCplex();
        cplex.getVersion();
        // no cplex logging information
        cplex.setOut(null);
        // parameter values in array
        double[] K = new double[T];
        double[] h = new double[T];
        double[] v = new double[T];
        double[] pai = new double[T];
        Arrays.fill(K, fixOrderCost);
        Arrays.fill(h, holdingCost);
        Arrays.fill(v, variCost);
        Arrays.fill(pai, penaltyCost);
        // decision variables
        // whether [i, j) is a replenishment cycle
        IloIntVar[][] x = new IloIntVar[T][T];
        // total ordering quantity sums to period i, if [i, j) is a replenishment cycle
        IloNumVar[][] q = new IloNumVar[T][T];
        // loss function value at period t of repre cycle [i, j)
        IloNumVar[][][] H = new IloNumVar[T][T][T];
        for (int i = 0; i < T; i++) for (int j = 0; j < T; j++) {
            for (int t = 0; t < T; t++) {
                if (t >= i && t <= j)
                    H[i][j][t] = cplex.numVar(0, Double.MAX_VALUE);
                else
                    H[i][j][t] = cplex.numVar(0, 0);
            }
            if (j < i) {
                x[i][j] = cplex.intVar(0, 0);
                q[i][j] = cplex.numVar(0, 0);
            } else {
                x[i][j] = cplex.boolVar();
                q[i][j] = cplex.numVar(0, Double.MAX_VALUE);
            }
        }
        // objective function
        IloLinearNumExpr setupCosts = cplex.linearNumExpr();
        IloLinearNumExpr holdCosts = cplex.linearNumExpr();
        IloLinearNumExpr Dxij = cplex.linearNumExpr();
        IloLinearNumExpr penaCosts = cplex.linearNumExpr();
        for (int i = 0; i < T; i++) for (int j = 0; j < T; j++) {
            setupCosts.addTerm(x[i][j], K[i]);
            for (int t = i; t <= j; t++) {
                // Dxij.addTerm(pai[i] * cumSumDemand[t], x[i][j]);
                // holdCosts.addTerm(q[i][j], -pai[i]);
                Dxij.addTerm(-h[i] * cumSumDemand[t], x[i][j]);
                holdCosts.addTerm(q[i][j], h[i]);
                penaCosts.addTerm(h[i] + pai[i], H[i][j][t]);
            }
        }
        cplex.addMinimize(cplex.sum(setupCosts, holdCosts, Dxij, penaCosts));
        // constraints
        // sum_{i=0}^T x_{1, i} = 1
        // sum_{i=0}^T x_{i, T} = 1;
        // sum_{i=0}^t x_{i, t} = sum_{j=t+1}^T x_{t, j}
        IloLinearNumExpr sumX1j = cplex.linearNumExpr();
        IloLinearNumExpr sumXiT = cplex.linearNumExpr();
        IloLinearNumExpr sumXit;
        IloLinearNumExpr sumXtj;
        for (int i = 0; i < T; i++) {
            sumX1j.addTerm(1, x[0][i]);
            sumXiT.addTerm(1, x[i][T - 1]);
        }
        cplex.addEq(sumX1j, 1);
        cplex.addEq(sumXiT, 1);
        for (int t = 0; t < T - 1; t++) {
            sumXit = cplex.linearNumExpr();
            sumXtj = cplex.linearNumExpr();
            for (int i = 0; i <= t; i++) sumXit.addTerm(1, x[i][t]);
            for (int j = t + 1; j < T; j++) sumXtj.addTerm(1, x[t + 1][j]);
            cplex.addEq(sumXit, sumXtj);
        }
        // q_{i,j} <= Mx_{i,j}
        IloLinearNumExpr sumqit;
        IloLinearNumExpr sumqtj;
        for (int i = 0; i < T; i++) for (int j = 0; j < T; j++) cplex.addLe(q[i][j], cplex.prod(M, x[i][j]));
        // sum_{i=0}^t q_{i, t} <= sum_{j=t+1}^T q_{t, j}
        for (int t = 0; t < T - 1; t++) {
            sumqit = cplex.linearNumExpr();
            sumqtj = cplex.linearNumExpr();
            for (int i = 0; i <= t; i++) sumqit.addTerm(1, q[i][t]);
            for (int j = t + 1; j < T; j++) sumqtj.addTerm(1, q[t + 1][j]);
            cplex.addLe(sumqit, sumqtj);
        }
        // piecewise constraints
        IloNumExpr expectI;
        for (int i = 0; i < T; i++) for (int j = i; j < T; j++) {
            for (int t = i; t <= j; t++) {
                expectI = cplex.diff(q[i][j], cplex.prod(cumSumDemand[t], x[i][j]));
                for (int k = 0; k < partionNum; k++) {
                    double pik = Arrays.stream(prob).limit(k + 1).sum();
                    double pmean = 0;
                    for (int m = 0; m <= k; m++) pmean += prob[m] * means[m];
                    // cplex.addGe(H[i][j][t], cplex.diff(cplex.prod(expectI, pik), cplex.prod(x[i][j], conSigma[i][t] * pmean)));
                    cplex.addGe(cplex.sum(H[i][j][t], expectI), cplex.diff(cplex.prod(expectI, pik), cplex.prod(x[i][j], conSigma[i][t] * pmean)));
                }
            }
        }
        if (cplex.solve()) {
            double[][][] varH = new double[T][T][T];
            double[][] varQ = new double[T][T];
            double[][] varX = new double[T][T];
            for (int i = 0; i < T; i++) for (int j = 0; j < T; j++) {
                varX[i][j] = cplex.getValue(x[i][j]);
                varQ[i][j] = cplex.getValue(q[i][j]);
                for (int k = i; k <= j; k++) varH[i][j][k] = cplex.getValue(H[i][j][k]);
            }
            double[] z = new double[T];
            double[] quantity = new double[T];
            double[] I = new double[T];
            double lastQ = 0;
            for (int i = 0; i < T; i++) for (int j = 0; j < T; j++) {
                if (varX[i][j] == 1) {
                    z[i] = 1;
                    if (i == 0) {
                        quantity[i] = varQ[i][j];
                        lastQ = quantity[i];
                    } else {
                        quantity[i] = varQ[i][j] - lastQ;
                        lastQ = quantity[i];
                    }
                }
            }
            I[0] = quantity[0] + iniInventory - meanDemand[0];
            for (int i = 1; i < T; i++) I[i] = quantity[i] + I[i - 1] - meanDemand[i];
            System.out.println("Solution value = " + cplex.getObjValue());
            if (outputResults == true) {
                System.out.println("Solution status = " + cplex.getStatus());
                // it's not less than number of variables
                System.out.println("number of constriants are:" + cplex.getNcols());
                System.out.println("z = ");
                System.out.println(Arrays.toString(z));
                System.out.println("Ordering quantities = ");
                System.out.println(Arrays.toString(quantity));
                System.out.println("I = ");
                System.out.println(Arrays.toString(I));
                // System.out.println("part of holding costs is :");
                // System.out.println(cplex.getValue(holdCosts));
                // System.out.println("Another part of holding costs is :");
                // System.out.println(cplex.getValue(Dxij));
                // System.out.println("merged penalty costs is :");
                // System.out.println(cplex.getValue(penaCosts));
                System.out.println("x = ");
                System.out.println(Arrays.deepToString(varX));
                System.out.println("q = ");
                System.out.println(Arrays.deepToString(varQ));
                System.out.println("H = ");
                System.out.println(Arrays.deepToString(varH));
            }
            double finalOptValue = cplex.getObjValue();
            cplex.end();
            return finalOptValue;
        } else {
        }
    } catch (IloException e) {
        System.err.println("Concert exception '" + e + "' caught");
    }
    return 0;
}
Also used : IloCplex(ilog.cplex.IloCplex) IloIntVar(ilog.concert.IloIntVar) IloConstraint(ilog.concert.IloConstraint) IloNumExpr(ilog.concert.IloNumExpr) IloLinearNumExpr(ilog.concert.IloLinearNumExpr) IloNumVar(ilog.concert.IloNumVar) IloException(ilog.concert.IloException)

Aggregations

IloNumVar (ilog.concert.IloNumVar)13 IloCplex (ilog.cplex.IloCplex)13 IloException (ilog.concert.IloException)12 IloNumExpr (ilog.concert.IloNumExpr)12 IloIntVar (ilog.concert.IloIntVar)10 IloLinearNumExpr (ilog.concert.IloLinearNumExpr)6 IloRange (ilog.concert.IloRange)2 IloConstraint (ilog.concert.IloConstraint)1 IloLPMatrix (ilog.concert.IloLPMatrix)1 IloModeler (ilog.concert.IloModeler)1 CplexStatus (ilog.cplex.IloCplex.CplexStatus)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Iterator (java.util.Iterator)1 IntToDoubleFunction (java.util.function.IntToDoubleFunction)1 IntStream (java.util.stream.IntStream)1 MathFunction (umontreal.ssj.functions.MathFunction)1 MathFunctionUtil (umontreal.ssj.functions.MathFunctionUtil)1 ContinuousDistribution (umontreal.ssj.probdist.ContinuousDistribution)1 Distribution (umontreal.ssj.probdist.Distribution)1