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);
}
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);
}
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);
}
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;
}
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;
}
Aggregations