use of sdp.inventory.State in project Stochastic-Inventory by RobinChen121.
the class LevelFitsS method main.
public static void main(String[] args) {
double truncationQuantile = 0.9999;
double stepSize = 1;
double minInventory = -500;
double maxInventory = 1000;
double fixedOrderingCost = 250;
double variOrderingCost = 0;
double penaltyCost = 26;
// double[] meanDemand = { 20, 40, 60, 40 };
double holdingCost = 1;
int maxOrderQuantity = 41;
boolean isForDrawGy = true;
// // get demand possibilities for each period
// int T = meanDemand.length;
// Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T)
// //.mapToObj(i -> new PoissonDist(meanDemand[i]))
// .mapToObj(i -> new NormalDist(meanDemand[i], coeValue * meanDemand[i]))
// .toArray(Distribution[]::new);
// double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
// int T = 8;
// double[] values = {6, 7};
// double[] probs = {0.95, 0.05};
// Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T)
// .mapToObj(i -> new DiscreteDistribution(values, probs, values.length)) // can be changed to other distributions
// .toArray(DiscreteDistribution[]::new);
// double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
int T = 4;
double[][] values = { { 34, 159, 281, 286 }, { 14, 223, 225, 232 }, { 5, 64, 115, 171 }, { 35, 48, 145, 210 } };
double[][] probs = { { 0.018, 0.888, 0.046, 0.048 }, { 0.028, 0.271, 0.17, 0.531 }, { 0.041, 0.027, 0.889, 0.043 }, { 0.069, 0.008, 0.019, 0.904 } };
Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T).mapToObj(// can be changed to other distributions
i -> new DiscreteDistribution(values[i], probs[i], values[i].length)).toArray(DiscreteDistribution[]::new);
double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
// feasible actions
Function<State, double[]> getFeasibleAction = s -> {
double[] feasibleActions = new double[(int) (maxOrderQuantity / stepSize) + 1];
int index = 0;
for (double i = 0; i <= maxOrderQuantity; i = i + stepSize) {
feasibleActions[index] = i;
index++;
}
return feasibleActions;
};
// state transition function
StateTransitionFunction<State, Double, Double, State> stateTransition = (state, action, randomDemand) -> {
double nextInventory = state.getIniInventory() + action - randomDemand;
nextInventory = nextInventory > maxInventory ? maxInventory : nextInventory;
nextInventory = nextInventory < minInventory ? minInventory : nextInventory;
return new State(state.getPeriod() + 1, nextInventory);
};
// immediate value
ImmediateValueFunction<State, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
double fixedCost = 0, variableCost = 0, inventoryLevel = 0, holdingCosts = 0, penaltyCosts = 0;
fixedCost = action > 0 ? fixedOrderingCost : 0;
variableCost = variOrderingCost * action;
inventoryLevel = state.getIniInventory() + action - randomDemand;
holdingCosts = holdingCost * Math.max(inventoryLevel, 0);
penaltyCosts = penaltyCost * Math.max(-inventoryLevel, 0);
double totalCosts = fixedCost + variableCost + holdingCosts + penaltyCosts;
return totalCosts;
};
/**
*****************************************************************
* Solve
*/
Recursion recursion = new Recursion(OptDirection.MIN, pmf, getFeasibleAction, stateTransition, immediateValue);
int period = 1;
double iniInventory = 500;
State initialState = new State(period, iniInventory);
long currTime = System.currentTimeMillis();
double opt = recursion.getExpectedValue(initialState);
System.out.println("final optimal expected value is: " + opt);
System.out.println("optimal order quantity in the first priod is : " + recursion.getAction(initialState));
double time = (System.currentTimeMillis() - currTime) / 1000;
System.out.println("running time is " + time + "s");
/**
*****************************************************************
* Simulating sdp results
*/
int sampleNum = 10000;
SimulateFitsS simuation = new SimulateFitsS(distributions, sampleNum, recursion);
simuation.simulateSDPGivenSamplNum(initialState);
double error = 0.0001;
double confidence = 0.95;
simuation.simulateSDPwithErrorConfidence(initialState, error, confidence);
/**
*****************************************************************
* Fit (s, S) levels
*/
System.out.println("");
double[][] optTable = recursion.getOptTable();
MIPFitsS findsS = new MIPFitsS(maxOrderQuantity, T);
double[][] optsS = findsS.getSinglesS(optTable);
System.out.println("single s, S level: " + Arrays.deepToString(optsS));
optsS = findsS.getTwosS(optTable);
System.out.println("two s, S level: " + Arrays.deepToString(optsS));
optsS = findsS.getThreesS(optTable);
System.out.println("three s, S level: " + Arrays.deepToString(optsS));
double sim1 = simuation.simulateSinglesS(initialState, optsS, maxOrderQuantity);
System.out.printf("one level gap is %.2f%%\n", (sim1 - opt) * 100 / opt);
double sim2 = simuation.simulateTwosS(initialState, optsS, maxOrderQuantity);
System.out.printf("two level gap is %.2f%%\n", (sim2 - opt) * 100 / opt);
double sim3 = simuation.simulateThreesS(initialState, optsS, maxOrderQuantity);
System.out.printf("three level gap is %.2f%%\n", (sim3 - opt) * 100 / opt);
}
use of sdp.inventory.State in project Stochastic-Inventory by RobinChen121.
the class SimulateFitsS method simulateTwosS.
/**
* @param iniState
* @param optsS
* @param maxOrderQuantity
* @return simulation results for two level fitted s S policy
*/
public double simulateTwosS(State iniState, double[][] optsS, int maxOrderQuantity) {
Sampling.resetStartStream();
Sampling sampling = new Sampling();
double[][] samples = sampling.generateLHSamples(distributions, sampleNum);
double[] costs = new double[samples.length];
for (int i = 0; i < samples.length; i++) {
double sum = 0;
State state = iniState;
for (int t = 0; t < samples[0].length; t++) {
double optQ;
if (t == 0)
optQ = optsS[t][1];
else {
if (state.getIniInventory() < optsS[t][0])
optQ = Math.min(maxOrderQuantity, optsS[t][1] - state.getIniInventory());
else if (optsS[t][0] <= state.getIniInventory() && state.getIniInventory() < optsS[t][2])
optQ = Math.min(maxOrderQuantity, optsS[t][3] - state.getIniInventory());
else
optQ = 0.0;
}
sum += immediateValue.apply(state, optQ, samples[i][t]);
state = stateTransition.apply(state, optQ, samples[i][t]);
costs[i] = sum;
}
}
double simFinalValue = Arrays.stream(costs).sum() / samples.length;
System.out.println("\nfinal simulated expected value for fitted two level (s, S) policy is " + simFinalValue);
return simFinalValue;
}
use of sdp.inventory.State in project Stochastic-Inventory by RobinChen121.
the class SimulateFitsS method simulateThreesS.
/**
* @param iniState
* @param optsS
* @param maxOrderQuantity
* @return simulation results for three level fitted s S policy
*/
public double simulateThreesS(State iniState, double[][] optsS, int maxOrderQuantity) {
Sampling.resetStartStream();
Sampling sampling = new Sampling();
double[][] samples = sampling.generateLHSamples(distributions, sampleNum);
double[] costs = new double[samples.length];
for (int i = 0; i < samples.length; i++) {
double sum = 0;
State state = iniState;
for (int t = 0; t < samples[0].length; t++) {
double optQ;
if (t == 0)
optQ = optsS[t][1];
else {
if (state.getIniInventory() < optsS[t][0])
optQ = Math.min(maxOrderQuantity, optsS[t][1] - state.getIniInventory());
else if (optsS[t][0] <= state.getIniInventory() && state.getIniInventory() < optsS[t][2])
optQ = Math.min(maxOrderQuantity, optsS[t][3] - state.getIniInventory());
else if (optsS[t][2] <= state.getIniInventory() && state.getIniInventory() < optsS[t][4])
optQ = Math.min(maxOrderQuantity, optsS[t][5] - state.getIniInventory());
else
optQ = 0.0;
}
sum += immediateValue.apply(state, optQ, samples[i][t]);
state = stateTransition.apply(state, optQ, samples[i][t]);
costs[i] = sum;
}
}
double simFinalValue = Arrays.stream(costs).sum() / samples.length;
System.out.println("\nfinal simulated expected value for fitted three level (s, S) policy is " + simFinalValue);
return simFinalValue;
}
use of sdp.inventory.State in project Stochastic-Inventory by RobinChen121.
the class TwoLevelFitsSTest method main.
public static void main(String[] args) {
String headString = "K, v, h, I0, pai, Qmax, DemandPatt, OpValue, Time(sec), simValue, error";
WriteToCsv.writeToFile("./" + "test_results.csv", headString);
double[][] demands = { { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }, { 6.6, 9.3, 11.1, 12.9, 16.8, 21.6, 24, 26.4, 31.5, 33.9, 36.3, 40.8, 44.4, 47.1, 48.3, 50.1, 50.1, 48.9, 47.1, 44.4 }, { 45.9, 48.6, 49.8, 49.8, 48.6, 45.9, 42.3, 37.8, 35.4, 33, 30.3, 27.9, 25.5, 23.1, 20.7, 18.3, 14.4, 10.8, 8.1, 6.3 }, { 36.3, 30, 23.7, 21, 23.7, 30, 36.3, 39, 36.3, 30, 23.7, 21, 23.7, 30, 36.3, 30.9, 24.3, 21.3, 26.4, 33 }, { 47.1, 30, 12.9, 6, 12.9, 30, 47.1, 54, 47.1, 30, 12.9, 6, 12.9, 30, 47.1, 29.7, 15, 7.5, 11.4, 29.7 }, { 62.7, 27.3, 9.9, 23.7, 1, 22.8, 32.7, 34.5, 67.2, 6.6, 14.4, 40.8, 3.9, 63.3, 25.5, 45, 53.1, 24.6, 10.2, 49.8 }, { 1, 15.3, 45.6, 140.1, 80.4, 146.7, 133.8, 74.4, 84.3, 108.9, 46.5, 87.9, 66, 27.9, 32.1, 88.5, 161.7, 36, 32.4, 49.8 }, { 14.1, 24.3, 70.8, 118.2, 49.2, 86.1, 152.4, 117.3, 226.2, 208.2, 78.3, 58.5, 96, 33.3, 57.3, 115.5, 17.7, 134.7, 127.8, 179.7 }, { 13.2, 34.8, 79.2, 43.2, 43.8, 59.4, 22.2, 54.9, 61.2, 34.2, 49.5, 95.4, 35.7, 144.6, 160.2, 103.8, 150.6, 86.4, 122.7, 63.6 }, { 14.7, 56.4, 19.2, 83.7, 135.9, 67.2, 66.9, 155.1, 87.3, 164.1, 193.8, 67.2, 64.5, 132, 34.8, 131.4, 132.9, 35.7, 172.5, 152.1 } };
// 1500, 1000, 500
double[] K = { 500, 800, 200 };
double[] v = { 0, 5, 10 };
// 15, 10, 5
double[] pai = { 15, 10, 5 };
// 3, 5, 7
double[] capacity = { 2, 3, 4 };
double truncationQuantile = 0.9999;
double stepSize = 1;
double minInventory = -300;
double maxInventory = 800;
double holdingCost = 1;
for (int iK = 0; iK < K.length; iK++) {
for (int iv = 0; iv < v.length; iv++) {
for (int ipai = 0; ipai < pai.length; ipai++) {
for (int idemand = 0; idemand < demands.length; idemand++) for (int icapacity = 0; icapacity < capacity.length; icapacity++) {
// double[] meanDemand = demands[idemand];
double[] meanDemand = { 9, 23, 53, 29 };
double fixedOrderingCost = K[iK];
double proportionalOrderingCost = v[iv];
double penaltyCost = pai[ipai];
int maxOrderQuantity = (int) (Math.round(Arrays.stream(meanDemand).sum() / meanDemand.length) * capacity[icapacity]);
// get demand possibilities for each period
int T = meanDemand.length;
Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T).mapToObj(// can be changed to other distributions
i -> new PoissonDist(meanDemand[i])).toArray(PoissonDist[]::new);
double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
// feasible actions
Function<State, double[]> getFeasibleAction = s -> {
double[] feasibleActions = new double[(int) (maxOrderQuantity / stepSize) + 1];
int index = 0;
for (double i = 0; i <= maxOrderQuantity; i = i + stepSize) {
feasibleActions[index] = i;
index++;
}
return feasibleActions;
};
// state transition function
StateTransitionFunction<State, Double, Double, State> stateTransition = (state, action, randomDemand) -> {
double nextInventory = state.getIniInventory() + action - randomDemand;
nextInventory = nextInventory > maxInventory ? maxInventory : nextInventory;
nextInventory = nextInventory < minInventory ? minInventory : nextInventory;
return new State(state.getPeriod() + 1, nextInventory);
};
// immediate value
ImmediateValueFunction<State, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
double fixedCost = 0, variableCost = 0, inventoryLevel = 0, holdingCosts = 0, penaltyCosts = 0;
fixedCost = action > 0 ? fixedOrderingCost : 0;
variableCost = proportionalOrderingCost * action;
inventoryLevel = state.getIniInventory() + action - randomDemand;
holdingCosts = holdingCost * Math.max(inventoryLevel, 0);
penaltyCosts = penaltyCost * Math.max(-inventoryLevel, 0);
double totalCosts = fixedCost + variableCost + holdingCosts + penaltyCosts;
return totalCosts;
};
/**
*****************************************************************
* Solve
*/
Recursion recursion = new Recursion(OptDirection.MIN, pmf, getFeasibleAction, stateTransition, immediateValue);
// using tree map when finding levels for s and S
recursion.setTreeMapCacheAction();
int period = 1;
double iniInventory = 0;
State initialState = new State(period, iniInventory);
long currTime = System.currentTimeMillis();
double finalValue = recursion.getExpectedValue(initialState);
System.out.println("final optimal expected value is: " + finalValue);
System.out.println("optimal order quantity in the first priod is : " + recursion.getAction(initialState));
double time = (System.currentTimeMillis() - currTime) / 1000;
System.out.println("running time is " + time + "s");
/**
*****************************************************************
* Simulating two level s S results
*/
int sampleNum = 10000;
SimulateFitsS simuation = new SimulateFitsS(distributions, sampleNum, recursion);
double[][] optTable = recursion.getOptTable();
MIPFitsS findsS = new MIPFitsS(maxOrderQuantity, T);
double[][] optsS = findsS.getTwosS(optTable);
System.out.println(Arrays.deepToString(optsS));
simuation.simulateSDPGivenSamplNum(initialState);
double simFinalValue = simuation.simulateTwosS(initialState, optsS, maxOrderQuantity);
System.out.printf("Optimality gap is: %.2f%%\n", (simFinalValue - finalValue) / finalValue * 100);
String out = fixedOrderingCost + ",\t" + proportionalOrderingCost + ",\t" + holdingCost + ",\t" + iniInventory + ",\t" + penaltyCost + ",\t" + maxOrderQuantity + ",\t" + (idemand + 1) + ",\t" + finalValue + ",\t" + time + ",\t" + simFinalValue + ",\t" + (simFinalValue - finalValue) / finalValue;
WriteToCsv.writeToFile("./" + "test_results.csv", out);
}
}
}
}
}
use of sdp.inventory.State in project Stochastic-Inventory by RobinChen121.
the class MultiItemCashG method main.
public static void main(String[] args) {
double[] price = { 2, 10 };
// higher margin vs lower margin
double[] variCost = { 1, 2 };
// initial cash
double iniCash = 10;
// initial inventory
int[] iniInventory = { 0, 0 };
// compute G(d)
int d = 1;
int T = 4;
// mean demand is shape * scale and variance is shape * scale^2
double[] meanDemands = new double[] { 10, 3 };
// higher average demand vs lower average demand
double[][] demand = new double[2][T];
// higher variance vs lower variance
double[] beta = { 10, 1 };
double d1 = meanDemands[0];
double d2 = meanDemands[1];
for (int t = 0; t < T; t++) {
demand[0][t] = d1;
demand[1][t] = d2;
}
double[] salPrice = Arrays.stream(variCost).map(a -> a * 0.5).toArray();
double truncationQuantile = 0.9999;
int stepSize = 1;
int maxInventoryState = 200;
int Qbound = 40;
double discountFactor = 1;
// get shape possibilities for a product in each period
// normal dist for one product
GammaDist[] distributions = new GammaDist[T];
for (int t = 0; t < T; t++) distributions[t] = new GammaDist(demand[d - 1][t] * beta[d - 1], beta[d - 1]);
// build action list for this item
Function<State, double[]> buildActionList = s -> {
return DoubleStream.iterate(0, i -> i + stepSize).limit(Qbound + 1).toArray();
};
// Immediate Value Function
ImmediateValueFunction<State, Double, Double, Double> immediateValue = (IniState, action, randomDemand) -> {
double revenue = 0;
revenue = (price[d - 1] - variCost[d - 1]) * Math.min(IniState.getIniInventory() + action, randomDemand);
if (IniState.getPeriod() == T) {
revenue += (salPrice[d - 1] - variCost[d - 1]) * Math.max(IniState.getIniInventory() + action - randomDemand, 0);
}
return revenue;
};
// State Transition Function
// need change
StateTransitionFunction<State, Double, Double, State> stateTransition = (IniState, action, randomDemand) -> {
double endInventory = IniState.getIniInventory() + action - randomDemand;
endInventory = Math.max(0, endInventory);
endInventory = endInventory > maxInventoryState ? maxInventoryState : endInventory;
endInventory = (int) endInventory;
return new State(IniState.getPeriod() + 1, endInventory);
};
double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
/**
*****************************************************************
* Solve
*/
RecursionG recursion = new RecursionG(pmf, buildActionList, stateTransition, immediateValue);
int period = 1;
State iniState = new State(period, iniInventory[d - 1]);
long currTime = System.currentTimeMillis();
double finalValue = iniCash + recursion.getExpectedValue(iniState);
System.out.println("final optimal cash is " + finalValue);
System.out.println("optimal order quantity in the first priod is : Q = " + recursion.getAction(iniState));
double time = (System.currentTimeMillis() - currTime) / 1000;
System.out.println("running time is " + time + "s");
System.out.println("a* in each period:");
double[] optY = recursion.getOptY();
optY[0] = iniState.getIniInventory() + recursion.getAction(iniState);
System.out.println(Arrays.toString(optY));
}
Aggregations