use of sdp.cash.CashSimulation in project Stochastic-Inventory by RobinChen121.
the class cashSurvival method main.
/**
* @param args
* @date: Nov 21, 2020, 6:01:10 PM
*/
public static void main(String[] args) {
double[] meanDemand = { 5, 5, 5, 5 };
// double[] meanDemand = {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20};
double iniInventory = 0;
double iniCash = 15;
double fixOrderCost = 0;
double variCost = 1;
double[] price = { 3, 3, 3, 3 };
double depositeRate = 0;
double salvageValue = 0.5;
double holdingCost = 0;
FindCCrieria criteria = FindCCrieria.XRELATE;
// costs like wages or rents which is required to pay in each period
double overheadCost = 10;
// rate from revenue to pay overhead wages
double overheadRate = 0;
// maximum ordering quantity when having enough cash
double maxOrderQuantity = 200;
double truncationQuantile = 0.9999;
int stepSize = 1;
double minInventoryState = 0;
double maxInventoryState = 500;
// can affect results, should be smaller than minus fixedOrderCost
double minCashState = -1000;
double maxCashState = 2000;
// can also be overdraft rate; large penalty cost cause big gaps for simulation results, since may generate zero demand;
double penaltyCost = 0;
double discountFactor = 1;
// 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])).toArray(Distribution[]::new);
double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
// feasible actions
// in fact, no cash constraint in this paper
Function<CashState, double[]> getFeasibleAction = s -> {
return DoubleStream.iterate(0, i -> i + stepSize).limit((int) maxOrderQuantity + 1).toArray();
};
// immediate value
ImmediateValueFunction<CashState, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
int t = state.getPeriod() - 1;
double revenue = price[t] * Math.min(state.getIniInventory() + action, randomDemand);
double fixedCost = action > 0 ? fixOrderCost : 0;
double variableCost = variCost * action;
double deposite = (state.getIniCash() - fixedCost - variableCost) * (1 + depositeRate);
double inventoryLevel = state.getIniInventory() + action - randomDemand;
double holdCosts = holdingCost * Math.max(inventoryLevel, 0);
double cashIncrement = (1 - overheadRate) * revenue + deposite - holdCosts - overheadCost - state.getIniCash();
double salValue = state.getPeriod() == T ? salvageValue * Math.max(inventoryLevel, 0) : 0;
cashIncrement += salValue;
double endCash = state.getIniCash() + cashIncrement;
if (endCash < 0) {
// can change to overdraft interest
cashIncrement += penaltyCost * endCash;
}
return cashIncrement;
};
// state transition function
StateTransitionFunction<CashState, Double, Double, CashState> stateTransition = (state, action, randomDemand) -> {
double nextInventory = Math.max(0, state.getIniInventory() + action - randomDemand);
double nextCash = state.getIniCash() + immediateValue.apply(state, action, randomDemand);
nextCash = nextCash > maxCashState ? maxCashState : nextCash;
nextCash = nextCash < minCashState ? minCashState : nextCash;
nextInventory = nextInventory > maxInventoryState ? maxInventoryState : nextInventory;
nextInventory = nextInventory < minInventoryState ? minInventoryState : nextInventory;
// cash is integer or not
// the right should be a decimal
nextCash = Math.round(nextCash * 1) / 1;
return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
};
/**
*****************************************************************
* Solve
*/
CashRecursion recursion = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition, immediateValue, discountFactor);
int period = 1;
CashState initialState = new CashState(period, iniInventory, iniCash);
long currTime = System.currentTimeMillis();
recursion.setTreeMapCacheAction();
double finalValue = recursion.getSurvProb(initialState);
System.out.println("survival probability for this initial state 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");
double[][] optTable = recursion.getOptTable();
System.out.println();
/**
*****************************************************************
* Simulate the result
*/
// immediate value
ImmediateValueFunction<CashState, Double, Double, Double> immediateValue2 = (state, action, randomDemand) -> {
int t = state.getPeriod() - 1;
double revenue = price[t] * Math.min(state.getIniInventory() + action, randomDemand);
double fixedCost = action > 0 ? fixOrderCost : 0;
double variableCost = variCost * action;
double deposite = (state.getIniCash() - fixedCost - variableCost) * (1 + depositeRate);
double inventoryLevel = state.getIniInventory() + action - randomDemand;
double holdCosts = holdingCost * Math.max(inventoryLevel, 0);
double cashIncrement = (1 - overheadRate) * revenue + deposite - holdCosts - overheadCost - state.getIniCash();
double salValue = state.getPeriod() == T ? salvageValue * Math.max(inventoryLevel, 0) : 0;
cashIncrement += salValue;
double endCash = state.getIniCash() + cashIncrement;
return cashIncrement;
};
int sampleNum = 100000;
// no need to add overheadCost in this class
CashSimulation simulation = new CashSimulation(distributions, sampleNum, recursion, discountFactor);
double[] result = simulation.simulateSDPGivenSamplNum(initialState, immediateValue2);
DecimalFormat df2 = new DecimalFormat("###, ###");
System.out.println("\nfinal simulated survival probability in " + df2.format(sampleNum) + " samples is: " + result[0]);
System.out.println("\nfinal simulated lost sale rate " + " is: " + result[1]);
}
use of sdp.cash.CashSimulation in project Stochastic-Inventory by RobinChen121.
the class CashConstraint method main.
// d=[8, 10, 10], iniCash=20, K=10; price=5, v=1; h = 1
public static void main(String[] args) {
double[] meanDemand = { 10 };
// double[] meanDemand = {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20};
double iniInventory = 0;
double iniCash = 200;
double fixOrderCost = 0;
double variCost = 2;
double[] price = { 6 };
double depositeRate = 0;
double salvageValue = 1;
double holdingCost = 0;
FindCCrieria criteria = FindCCrieria.XRELATE;
// costs like wages or rents which is required to pay in each period
double overheadCost = 0;
// rate from revenue to pay overhead wages
double overheadRate = 0;
// maximum ordering quantity when having enough cash
double maxOrderQuantity = 200;
double truncationQuantile = 0.9999;
int stepSize = 1;
double minInventoryState = 0;
double maxInventoryState = 500;
// can affect results, should be smaller than minus fixedOrderCost
double minCashState = -1000;
double maxCashState = 2000;
// large penalty cost cause big gaps for simulation results, since may generate zero demand
double penaltyCost = 0;
double discountFactor = 1;
// 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])).toArray(Distribution[]::new);
// double[] values1 = {6, 7};
// double[] probs1 = {0.95, 0.05};
// double[] values2 = {6, 7};
// double[] probs2 = {0.95, 0.05};
// DiscreteDistribution[] distributions = new DiscreteDistribution[T];
// for (int i = 0; i < T; i++) {
// if (i % 2 == 0)
// distributions[i] = new DiscreteDistribution(values1, probs1, values1.length);
// else
// distributions[i] = new DiscreteDistribution(values2, probs2, values2.length);
// }
double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
// feasible actions
Function<CashState, double[]> getFeasibleAction = s -> {
double maxQ = // maxOrderQuantity;
(int) Math.min(maxOrderQuantity, Math.max(0, (s.getIniCash() - overheadCost - fixOrderCost) / variCost));
return DoubleStream.iterate(0, i -> i + stepSize).limit((int) maxQ + 1).toArray();
};
// immediate value
ImmediateValueFunction<CashState, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
int t = state.getPeriod() - 1;
double revenue = price[t] * Math.min(state.getIniInventory() + action, randomDemand);
double fixedCost = action > 0 ? fixOrderCost : 0;
double variableCost = variCost * action;
double deposite = (state.getIniCash() - fixedCost - variableCost) * (1 + depositeRate);
double inventoryLevel = state.getIniInventory() + action - randomDemand;
double holdCosts = holdingCost * Math.max(inventoryLevel, 0);
double cashIncrement = (1 - overheadRate) * revenue + deposite - holdCosts - overheadCost - state.getIniCash();
double salValue = state.getPeriod() == T ? salvageValue * Math.max(inventoryLevel, 0) : 0;
cashIncrement += salValue;
double endCash = state.getIniCash() + cashIncrement;
if (endCash < 0) {
cashIncrement += penaltyCost * endCash;
}
return cashIncrement;
};
// state transition function
StateTransitionFunction<CashState, Double, Double, CashState> stateTransition = (state, action, randomDemand) -> {
double nextInventory = Math.max(0, state.getIniInventory() + action - randomDemand);
double nextCash = state.getIniCash() + immediateValue.apply(state, action, randomDemand);
nextCash = nextCash > maxCashState ? maxCashState : nextCash;
nextCash = nextCash < minCashState ? minCashState : nextCash;
nextInventory = nextInventory > maxInventoryState ? maxInventoryState : nextInventory;
nextInventory = nextInventory < minInventoryState ? minInventoryState : nextInventory;
// cash is integer or not
// the right should be a decimal
nextCash = Math.round(nextCash * 10) / 10.0;
return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
};
/**
*****************************************************************
* Solve
*/
CashRecursion recursion = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition, immediateValue, discountFactor);
int period = 1;
CashState initialState = new CashState(period, iniInventory, iniCash);
long currTime = System.currentTimeMillis();
recursion.setTreeMapCacheAction();
double finalValue = iniCash + recursion.getExpectedValue(initialState);
System.out.println("final optimal cash 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 sdp results
* parameter vales like price, variCost, holdingCost etc.
* are only for compute L(y), not very necessary
*/
int sampleNum = 10000;
// no need to add overheadCost in this class
CashSimulation simulation = new CashSimulation(distributions, sampleNum, recursion, discountFactor);
double simFinalValue = simulation.simulateSDPGivenSamplNum(initialState);
double error = 0.0001;
double confidence = 0.95;
simulation.simulateSDPwithErrorConfidence(initialState, error, confidence);
double defaultRisk = simulation.simulateDefaultProb(initialState);
System.out.println("default risk is " + defaultRisk);
/**
*****************************************************************
* Find (s, C1, C2 S) by SDP and simulate
*/
// System.out.println("");
// double[][] optTable = recursion.getOptTable();
// FindsCS findsCS = new FindsCS(iniCash, distributions, fixOrderCost, price, variCost, holdingCost, salvageValue);
// double[][] optsC12S = findsCS.getsC12S(optTable, overheadCost, criteria);
// Map<State, Double> cacheC1Values = new TreeMap<>();
// Map<State, Double> cacheC2Values = new TreeMap<>();
// double simsCSFinalValue = simulation.simulatesCS(initialState, optsC12S, cacheC1Values, cacheC2Values,
// overheadCost, maxOrderQuantity, fixOrderCost, variCost);
// double gap1 = (finalValue -simsCSFinalValue)/finalValue;
// double gap2 = (simFinalValue -simsCSFinalValue)/simFinalValue;
// System.out.printf("Optimality gap for (s, C1, C2 S) is: %.2f%% or %.2f%%\n", gap1 * 100, gap2 * 100);
//
// /*******************************************************************
// * Find (s, C1, S) by SDP and simulate
// */
// System.out.println("");
// System.out.println("************************************************");
// double[][] optsCS = findsCS.getsCS(optTable, overheadCost, criteria);
// cacheC1Values = findsCS.cacheC1Values;
// simsCSFinalValue = simulation.simulatesCS(initialState, optsCS, cacheC1Values,
// overheadCost, maxOrderQuantity, fixOrderCost, variCost);
// double gap21 = (finalValue -simsCSFinalValue)/finalValue;
// double gap22 = (simFinalValue -simsCSFinalValue)/simFinalValue;
// System.out.printf("Optimality gap for (s, C1, S) is: %.2f%% or %.2f%%\n", gap21 * 100, gap22 * 100);
// double[][] numFrequency = findsCS.getMaxSFrequency(optTable, overheadCost, criteria);
// System.out.println("most frequent S in each period");
// System.out.println(Arrays.deepToString(numFrequency));
/**
*****************************************************************
* Find (s, meanC, S) by SDP and simulate
*/
// System.out.println("");
// System.out.println("************************************************");
// optsCS = findsCS.getsCS(optTable, overheadCost, FindCCrieria.AVG);
// simsCSFinalValue = simulation.simulatesMeanCS(initialState, optsCS, overheadCost, maxOrderQuantity, fixOrderCost, variCost);
// double gap31 = (finalValue -simsCSFinalValue)/finalValue;
// double gap32 = (simFinalValue -simsCSFinalValue)/simFinalValue;
// System.out.printf("Optimality gap for (s, meanC, S) is: %.2f%% or %.2f%%\n", gap31 * 100, gap32 * 100);
/**
*****************************************************************
* Check (s, C1, C2, S) policy,
* sometimes not always hold, because in certain period
* for some state C is 12, and 13 in other state,
* we use heuristic step by choosing maximum one
*/
// findsCS.checksCS(optsCS, optTable, overheadCost, maxOrderQuantity, fixOrderCost, variCost);
// System.out.printf(
// "\n*******************************************************************\n");
/**
*****************************************************************
* Find (s, C, S) by MIP and simulate
*/
// System.out.println("************************************************");
// MipCashConstraint mipHeuristic = new MipCashConstraint(iniInventory, iniCash, fixOrderCost, variCost, holdingCost, price, salvageValue, distributions, overheadCost);
// double[][] sCS = mipHeuristic.findsCSPieceWise();
// Map<State, Double> cacheCValues = new TreeMap<>();
// cacheCValues = mipHeuristic.cacheC1Values;
// double simsCSMIPValue = simulation.simulatesCS(initialState, sCS, cacheCValues, overheadCost, maxOrderQuantity, fixOrderCost, variCost);
// gap1 = (finalValue - simsCSMIPValue)/finalValue;
// gap2 = (simFinalValue - simsCSMIPValue)/simFinalValue;
// System.out.printf("Optimality gap is: %.2f%% or %.2f%%\n", gap1 * 100, gap2 * 100);
// /*******************************************************************
// * Check CK-convexity
// */
//
// // immediate value
// boolean isForDrawGy = true;
// ImmediateValueFunction<CashState, Double, Double, Double> immediateValue2 = (state, action, randomDemand) -> {
// double revenue = 0;
// double fixedCost = 0;
// double variableCost = 0;
// double inventoryLevel = 0;
// if (isForDrawGy == true && state.getPeriod() == 1) {
// revenue = price * Math.min(state.getIniInventory(), randomDemand);
// fixedCost = 0;
// variableCost = variCost * state.getIniInventory();
// inventoryLevel = state.getIniInventory() - randomDemand;
// } else {
// revenue = price * Math.min(state.getIniInventory() + action, randomDemand);
// fixedCost = action > 0 ? fixOrderCost : 0;
// variableCost = variCost * action;
// inventoryLevel = state.getIniInventory() + action - randomDemand;
// }
// double holdCosts = holdingCost * Math.max(inventoryLevel, 0);
// double cashIncrement = revenue - fixedCost - variableCost - holdCosts - overheadCost;
// double salValue = state.getPeriod() == T ? salvageValue * Math.max(inventoryLevel, 0) : 0;
// cashIncrement += salValue;
// return cashIncrement;
// };
//
// // state transition function 2
// StateTransitionFunction<CashState, Double, Double, CashState> stateTransition2 = (state, action,
// randomDemand) -> {
// double nextInventory = isForDrawGy && state.getPeriod() == 1 ? state.getIniInventory() - randomDemand
// : state.getIniInventory() + action - randomDemand;
// double nextCash = state.getIniCash() + immediateValue2.apply(state, action, randomDemand);
// if (isForDrawGy == true && state.getPeriod() == 1) // this is the only difference with transition function3
// nextCash -= fixOrderCost;
// nextCash = nextCash > maxCashState ? maxCashState : nextCash;
// nextCash = nextCash < minCashState ? minCashState : nextCash;
// nextInventory = nextInventory > maxInventoryState ? maxInventoryState : nextInventory;
// nextInventory = nextInventory < minInventoryState ? minInventoryState : nextInventory;
// return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
// };
//
//
// int minInventorys = 0;
// int maxInventorys = 50; // for drawing pictures
// int xLength = maxInventorys - minInventorys + 1;
// int index = 0;
// CashRecursion recursion2 = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition2,
// immediateValue2, discountFactor);
// double[][] yG2 = new double[xLength][2];
// index = 0;
// for (int initialInventory = minInventorys; initialInventory <= maxInventorys; initialInventory++) {
// yG2[index][0] = initialInventory;
// yG2[index][1] = -recursion2.getExpectedValue(new CashState(period, initialInventory, iniCash));
// index++;
// }
//
// int capacity = (int) Math.max(0, (iniCash - overheadCost - fixOrderCost) / variCost);
// Drawing drawing = new Drawing();
// drawing.drawSimpleG(yG2, iniCash, "K transfered in cash GB"); // GB
// System.out.println();
// System.out.println("CK convex of GB:");
// CheckKConvexity.checkCK(yG2, fixOrderCost, capacity); // check the CK convex of GB
// System.out.println();
//
}
use of sdp.cash.CashSimulation in project Stochastic-Inventory by RobinChen121.
the class CashConstraintDraw method main.
public static void main(String[] args) {
double[] meanDemand = { 7, 2, 6 };
// double[] meanDemand = {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20};
double iniCash = 13;
double iniInventory = 0;
double fixOrderCost = 20;
double variCost = 1;
double price = 5;
double salvageValue = 0;
double holdingCost = 0;
FindCCrieria criteria = FindCCrieria.XRELATE;
// minimum cash balance the retailer can withstand
double overheadCost = 0;
// maximum ordering quantity when having enough cash
double maxOrderQuantity = 200;
double truncationQuantile = 0.9999;
int stepSize = 1;
double minInventoryState = 0;
double maxInventoryState = 500;
// can affect results, should be smaller than minus fixedOrderCost
double minCashState = -100;
double maxCashState = 2000;
double discountFactor = 1;
boolean isForDrawGy = true;
// 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[] 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();
// feasible actions
Function<CashState, double[]> getFeasibleAction = s -> {
double maxQ = (int) Math.min(maxOrderQuantity, Math.max(0, (s.getIniCash() - overheadCost - fixOrderCost) / variCost));
return DoubleStream.iterate(0, i -> i + stepSize).limit((int) maxQ + 1).toArray();
};
// immediate value
ImmediateValueFunction<CashState, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
double revenue = 0;
double fixedCost = 0;
double variableCost = 0;
double inventoryLevel = 0;
revenue = price * Math.min(state.getIniInventory() + action, randomDemand);
fixedCost = action > 0 ? fixOrderCost : 0;
variableCost = variCost * action;
inventoryLevel = state.getIniInventory() + action - randomDemand;
double holdCosts = holdingCost * Math.max(inventoryLevel, 0);
double cashIncrement = revenue - fixedCost - variableCost - holdCosts;
double salValue = state.getPeriod() == T ? salvageValue * Math.max(inventoryLevel, 0) : 0;
cashIncrement += salValue;
return cashIncrement;
};
// state transition function
StateTransitionFunction<CashState, Double, Double, CashState> stateTransition = (state, action, randomDemand) -> {
double nextInventory = state.getIniInventory() + action - randomDemand;
double nextCash = state.getIniCash() + immediateValue.apply(state, action, randomDemand);
nextCash = nextCash > maxCashState ? maxCashState : nextCash;
nextCash = nextCash < minCashState ? minCashState : nextCash;
nextInventory = nextInventory > maxInventoryState ? maxInventoryState : nextInventory;
nextInventory = nextInventory < minInventoryState ? minInventoryState : nextInventory;
// nextCash = Math.round(nextCash * 100) / 100.00;
return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
};
/**
*****************************************************************
* Solve
*/
CashRecursion recursion = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition, immediateValue, discountFactor);
int period = 1;
CashState initialState = new CashState(period, iniInventory, iniCash);
long currTime = System.currentTimeMillis();
recursion.setTreeMapCacheAction();
double finalCash = iniCash + recursion.getExpectedValue(initialState);
System.out.println("final optimal cash is: " + finalCash);
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;
CashSimulation simuation = new CashSimulation(distributions, sampleNum, recursion, discountFactor);
double simFinalValue = simuation.simulateSDPGivenSamplNum(initialState);
double error = 0.0001;
double confidence = 0.95;
simuation.simulateSDPwithErrorConfidence(initialState, error, confidence);
/**
*****************************************************************
* Find (s, C, S) and simulate
*/
System.out.println("");
double[][] optTable = recursion.getOptTable();
FindsCS findsCS = new FindsCS(iniCash, distributions, fixOrderCost, price, variCost, holdingCost, salvageValue);
double[][] optsCS = findsCS.getsC12S(optTable, overheadCost, criteria);
Map<State, Double> cacheC1Values = new TreeMap<>();
Map<State, Double> cacheC2Values = new TreeMap<>();
cacheC1Values = findsCS.cacheC1Values;
cacheC2Values = findsCS.cacheC2Values;
double simsCSFinalValue = simuation.simulatesCS(initialState, optsCS, cacheC1Values, cacheC2Values, overheadCost, maxOrderQuantity, fixOrderCost, variCost);
double gap1 = (finalCash - simsCSFinalValue) / finalCash;
double gap2 = (simFinalValue - simsCSFinalValue) / simFinalValue;
System.out.printf("Optimality gap is: %.2f%% or %.2f%%\n", gap1 * 100, gap2 * 100);
/**
*****************************************************************
* Drawing x Q
*/
int minInventorys = 0;
// for drawing pictures
int maxInventorys = 30;
int minCash = (int) fixOrderCost;
int maxCash = (int) (fixOrderCost + 50);
int RLength = maxCash - minCash + 1;
int xLength = maxInventorys - minInventorys + 1;
Drawing drawing = new Drawing();
double initialInventory = 0;
// double[][] xQ = new double[xLength][2];
// int index = 0;
// for (initialInventory = minInventorys; initialInventory <= maxInventorys; initialInventory++) {
// //for (double initialCash = minCash; initialCash <= maxCash; initialCash++) {
// period = 1;
// xQ[index][0] = initialInventory;
// recursion.getExpectedValue(new CashState(period, initialInventory, iniCash));
// xQ[index][1] = recursion.getAction(new CashState(period, initialInventory, iniCash));
// index++;
// }
// drawing.drawXQ(xQ);
/**
*****************************************************************
* Drawing y G since comupteIfAbsent, we need initializing a new class to draw
* Gy; if not, java would not compute sdp again, we must redefine
* stateTransition function and immediate Function;
*/
// immediate value for GB
ImmediateValueFunction<CashState, Double, Double, Double> immediateValue2 = (state, action, randomDemand) -> {
double revenue = 0;
double fixedCost = 0;
double variableCost = 0;
double inventoryLevel = 0;
if (isForDrawGy == true && state.getPeriod() == 1) {
revenue = price * Math.min(state.getIniInventory(), randomDemand);
fixedCost = 0;
variableCost = variCost * state.getIniInventory();
inventoryLevel = state.getIniInventory() - randomDemand;
} else {
revenue = price * Math.min(state.getIniInventory() + action, randomDemand);
fixedCost = action > 0 ? fixOrderCost : 0;
variableCost = variCost * action;
inventoryLevel = state.getIniInventory() + action - randomDemand;
}
double holdCosts = holdingCost * Math.max(inventoryLevel, 0);
double cashIncrement = revenue - fixedCost - variableCost - holdCosts - overheadCost;
double salValue = state.getPeriod() == T ? salvageValue * Math.max(inventoryLevel, 0) : 0;
cashIncrement += salValue;
return cashIncrement;
};
// state transition function 2, for GB
StateTransitionFunction<CashState, Double, Double, CashState> stateTransition2 = (state, action, randomDemand) -> {
double nextInventory = isForDrawGy && state.getPeriod() == 1 ? state.getIniInventory() - randomDemand : state.getIniInventory() + action - randomDemand;
double nextCash = state.getIniCash() + immediateValue2.apply(state, action, randomDemand);
if (isForDrawGy == true && state.getPeriod() == 1)
nextCash -= fixOrderCost;
nextCash = nextCash > maxCashState ? maxCashState : nextCash;
nextCash = nextCash < minCashState ? minCashState : nextCash;
nextInventory = nextInventory > maxInventoryState ? maxInventoryState : nextInventory;
nextInventory = nextInventory < minInventoryState ? minInventoryState : nextInventory;
return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
};
CashRecursion recursion2 = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition2, immediateValue2, discountFactor);
double[][] yG2 = new double[xLength * RLength][3];
int index = 0;
double[][] resultTableGB = new double[RLength][xLength];
int rowIndex = 0;
int columnIndex = 0;
for (double initialCash = minCash; initialCash <= maxCash; initialCash++) {
columnIndex = 0;
for (initialInventory = minInventorys; initialInventory <= maxInventorys; initialInventory++) {
// initialInventory
yG2[index][0] = initialCash;
yG2[index][1] = initialInventory;
// iniCash
yG2[index][2] = recursion2.getExpectedValue(new CashState(period, initialInventory, initialCash));
resultTableGB[rowIndex][columnIndex] = yG2[index][2];
index++;
columnIndex++;
}
rowIndex++;
}
WriteToCsv wr = new WriteToCsv();
wr.writeArrayCSV(resultTableGB, "GB.csv");
// CheckKConvexity.check(yG2, fixOrderCost);
// drawing.drawSimpleG(yG2, iniCash, "K transfered in cash GB"); // GB
/**
*****************************************************************
* Drawing another G() that has no fixed ordering cost transition in the
* first period, GA
* the difference lies in state transition function
*/
// state transition function 3
StateTransitionFunction<CashState, Double, Double, CashState> stateTransition3 = (state, action, randomDemand) -> {
double nextInventory = isForDrawGy && state.getPeriod() == 1 ? state.getIniInventory() - randomDemand : state.getIniInventory() + action - randomDemand;
double nextCash = state.getIniCash() + immediateValue2.apply(state, action, randomDemand);
nextCash = nextCash > maxCashState ? maxCashState : nextCash;
nextCash = nextCash < minCashState ? minCashState : nextCash;
nextInventory = nextInventory > maxInventoryState ? maxInventoryState : nextInventory;
nextInventory = nextInventory < minInventoryState ? minInventoryState : nextInventory;
return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
};
CashRecursion recursion3 = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition3, immediateValue2, discountFactor);
double[][] yG3 = new double[xLength * RLength][3];
index = 0;
double[][] resultTableGA = new double[RLength][xLength];
rowIndex = 0;
// for (int initialInventory = minInventorys; initialInventory <= maxInventorys; initialInventory++) {
for (double initialCash = minCash; initialCash <= maxCash; initialCash++) {
columnIndex = 0;
for (initialInventory = minInventoryState; initialInventory <= maxInventorys; initialInventory++) {
// initialInventory
yG3[index][0] = initialCash;
// initialInventory
yG3[index][1] = initialInventory;
// iniCash
yG3[index][2] = recursion3.getExpectedValue(new CashState(period, initialInventory, initialCash));
resultTableGA[rowIndex][columnIndex] = yG3[index][2];
index++;
columnIndex++;
}
rowIndex++;
}
double[][] resultMinusGBA = recursion.getMinusGAGB(resultTableGA, resultTableGB, minCash, fixOrderCost, variCost);
wr.writeArrayCSV(resultTableGA, "GA.csv");
wr.writeArrayCSV(resultMinusGBA, "minusGBA.csv");
// drawing.drawSimpleG(yG3, iniCash, "K not transfered in cash GA");
// drawing.drawTwoGR(yG3, yG2, initialInventory); //drawing.drawTwoG(yG3, yG2, iniCash);
// double[] interPoint = drawing.intersectionPoint(yG3, yG2, iniCash);
// String fileName= "interSectionPoints.xls";
// wr.writeToExcelAppend(interPoint, fileName);
}
use of sdp.cash.CashSimulation in project Stochastic-Inventory by RobinChen121.
the class CashConstraintLookPolicy method main.
public static void main(String[] args) {
double[] meanDemand = { 2, 3, 8 };
// double[] meanDemand = {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20};
double iniInventory = 8;
double iniCash = 100;
double fixOrderCost = 10;
double variCost = 1;
double price = 8;
double depositeRate = 0;
double salvageValue = 0.5;
double holdingCost = 0;
FindCCrieria criteria = FindCCrieria.XRELATE;
// costs like wages or rents which is required to pay in each period
double overheadCost = 0;
// rate from revenue to pay overhead wages
double overheadRate = 0;
// maximum ordering quantity when having enough cash
double maxOrderQuantity = 200;
double truncationQuantile = 0.9999;
int stepSize = 1;
double minInventoryState = 0;
double maxInventoryState = 500;
// can affect results, should be smaller than minus fixedOrderCost
double minCashState = -100;
double maxCashState = 2000;
double discountFactor = 1;
double xmin = 0;
double xmax = 10;
double Rmin = fixOrderCost;
double Rmax = 40;
int row = 0;
int column = 0;
int columnNum = (int) (Rmax - Rmin + 1) + 1;
// ((Rmax - Rmin + 1)/2) + 2;
int rowNum = (int) ((xmax - xmin + 1) / 1) + 1;
double[][] resultTable = new double[rowNum][columnNum];
for (iniInventory = xmax; iniInventory >= xmin; iniInventory--) {
column = 0;
for (iniCash = Rmin; iniCash <= Rmax; iniCash = iniCash + 1) {
// 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])).toArray(Distribution[]::new);
double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
// feasible actions
Function<CashState, double[]> getFeasibleAction = s -> {
double maxQ = (int) Math.min(maxOrderQuantity, Math.max(0, (s.getIniCash() - overheadCost - fixOrderCost) / variCost));
return DoubleStream.iterate(0, i -> i + stepSize).limit((int) maxQ + 1).toArray();
};
// immediate value
ImmediateValueFunction<CashState, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
double revenue = price * Math.min(state.getIniInventory() + action, randomDemand);
double fixedCost = action > 0 ? fixOrderCost : 0;
double variableCost = variCost * action;
double deposite = (state.getIniCash() - fixedCost - variableCost) * (1 + depositeRate);
double inventoryLevel = state.getIniInventory() + action - randomDemand;
double holdCosts = holdingCost * Math.max(inventoryLevel, 0);
double cashIncrement = (1 - overheadRate) * revenue + deposite - holdCosts - overheadCost - state.getIniCash();
double salValue = state.getPeriod() == T ? salvageValue * Math.max(inventoryLevel, 0) : 0;
cashIncrement += salValue;
return cashIncrement;
};
// state transition function
StateTransitionFunction<CashState, Double, Double, CashState> stateTransition = (state, action, randomDemand) -> {
double nextInventory = Math.max(0, state.getIniInventory() + action - randomDemand);
double nextCash = state.getIniCash() + immediateValue.apply(state, action, randomDemand);
nextCash = nextCash > maxCashState ? maxCashState : nextCash;
nextCash = nextCash < minCashState ? minCashState : nextCash;
nextInventory = nextInventory > maxInventoryState ? maxInventoryState : nextInventory;
nextInventory = nextInventory < minInventoryState ? minInventoryState : nextInventory;
// cash is integer or not
nextCash = Math.round(nextCash * 1) / 1;
return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
};
/**
*****************************************************************
* Solve
*/
CashRecursion recursion = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition, immediateValue, discountFactor);
int period = 1;
CashState initialState = new CashState(period, iniInventory, iniCash);
long currTime = System.currentTimeMillis();
recursion.setTreeMapCacheAction();
double finalValue = iniCash + recursion.getExpectedValue(initialState);
System.out.println("final optimal cash is " + finalValue);
double optQ = recursion.getAction(initialState);
System.out.println("optimal order quantity in the first priod is : " + optQ);
double time = (System.currentTimeMillis() - currTime) / 1000;
System.out.println("running time is " + time + "s");
System.out.println("initial inventory is " + iniInventory);
System.out.println("initial cash is " + iniCash);
resultTable[0][column + 1] = iniCash;
resultTable[row + 1][0] = iniInventory;
// finalValue - iniCash;
resultTable[row + 1][column + 1] = optQ;
System.out.println("**********************************************************");
// /*******************************************************************
// * Simulating sdp results
// * parameter vales like price, variCost, holdingCost etc.
// * are only for compute L(y), not very necessary
// */
// int sampleNum = 10000;
//
// CashSimulation simuation = new CashSimulation(distributions, sampleNum, recursion, discountFactor,
// fixOrderCost, price, variCost, holdingCost, salvageValue); // no need to add overheadCost in this class
// double simFinalValue = simuation.simulateSDPGivenSamplNum(initialState);
// double error = 0.0001;
// double confidence = 0.95;
// simuation.simulateSDPwithErrorConfidence(initialState, error, confidence);
//
column++;
}
row++;
}
WriteToExcel wr = new WriteToExcel();
wr.writeArrayToExcel(resultTable, "resultTable.xls");
}
use of sdp.cash.CashSimulation in project Stochastic-Inventory by RobinChen121.
the class ChanceCash method main.
public static void main(String[] args) {
double iniCash = 150;
double iniI = 0;
double trunQuantile = 0.999;
// the higher value results in slower running speed. maximum negative possibility rate is 1 - serviceRate.
double serviceRate = 0.6;
// sample number in each period, the number of samples in the first period can have big influence
int[] sampleNums = { 5, 5, 5, 5 };
double[] meanDemand = { 10, 5, 10, 5 };
int T = sampleNums.length;
int[] sampleNumsRolling = { 5, 5, 5, 5 };
// rolling horizon length
int rollingLength = 2;
double meanDemandSum = Arrays.stream(meanDemand).sum();
double rollingDemandSum = Arrays.stream(meanDemand).limit(rollingLength).sum();
double portion = rollingDemandSum / meanDemandSum;
double rollingServiceRate = Math.pow(serviceRate, portion);
// simulating sample number in testing SAA and extended SAA
int sampleNum = 100;
double holdCostUnit = 0;
double salvageValueUnit = 5;
double[] prices = new double[T];
double[] variCostUnits = new double[T];
double[] overheadCosts = new double[T];
double[] mus = new double[T];
double sigmasCoe = 0.25;
Arrays.fill(prices, 22);
Arrays.fill(variCostUnits, 10);
// overhead costs
Arrays.fill(overheadCosts, 100);
// Arrays.fill(mus, 3.6);
// Arrays.fill(sigmas, 0.6);
// maximum ordering quantity when having enough cash
double maxOrderQuantity = 300;
Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T).mapToObj(i -> new PoissonDist(meanDemand[i])).toArray(// Poisson demand
Distribution[]::new);
// .mapToObj(i -> new LognormalDist(mus[i], sigmas[i])).toArray(Distribution[]::new);
/**
* solve the problem by SAA
*/
// generate scenarios, samples in each period form a scenario tree
Sampling sampling = new Sampling();
double[][] scenarios = sampling.generateLHSamples(distributions, sampleNums);
int sampleNumTotal = IntStream.of(sampleNums).reduce(1, (a, b) -> a * b);
int sampleNumTotalSimulate = IntStream.of(sampleNumsRolling).limit(rollingLength).reduce(1, (a, b) -> a * b);
int negativeScenarioNumRequire = (int) (sampleNumTotal * (1 - serviceRate));
LostSaleChance model = new LostSaleChance(distributions, sampleNums, iniCash, iniI, prices, variCostUnits, salvageValueUnit, holdCostUnit, overheadCosts, serviceRate, scenarios);
long currTime = System.currentTimeMillis();
double[] result;
double time1;
double positiveScenario;
double survivalProb;
double lostRate;
NumberFormat nf = NumberFormat.getPercentInstance();
nf.setMinimumFractionDigits(5);
DecimalFormat df = new DecimalFormat("###, ###");
result = model.solveMaxSurvival();
time1 = (System.currentTimeMillis() - currTime) / 1000.00;
currTime = System.currentTimeMillis();
System.out.println("**********************************************");
System.out.println("result of SAA-scenario tree before sorting scenarios: ");
System.out.println("running time is " + time1 + "s");
System.out.printf("first stage decison Q is: %.2f\n", result[0]);
positiveScenario = result[1];
System.out.printf("Objective value is: %.0f in %d scenarios\n", result[1], sampleNumTotal);
survivalProb = 100 * result[1] / sampleNumTotal;
System.out.printf("Survival probability is: %.5f%%\n", survivalProb);
System.out.println("lost sale scenario number in the solution is : " + result[2]);
System.out.println("maximum lost sale scenario number allowed is: " + negativeScenarioNumRequire);
lostRate = result[2] / (double) sampleNumTotal;
System.out.println("lost sale rate of SAA is: " + nf.format(lostRate));
System.out.println("lost sale max required rate is: " + nf.format(1 - serviceRate));
System.out.println();
/**
* Simulate the restult of SAA
*/
int stepSize = 1;
double fixOrderCost = 0;
double depositeRate = 0;
double minInventoryState = 0;
double maxInventoryState = 500;
// can affect results, should be smaller than minus fixedOrderCost
double minCashState = -1000;
double maxCashState = 2000;
double discountFactor = 1;
double[][][] pmf = new GetPmf(distributions, trunQuantile, stepSize).getpmf();
// immediate value
ImmediateValueFunction<CashState, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
int t = state.getPeriod() - 1;
double revenue = prices[t] * Math.min(state.getIniInventory() + action, randomDemand);
double fixedCost = action > 0 ? fixOrderCost : 0;
double variableCost = variCostUnits[t] * action;
double deposite = (state.getIniCash() - fixedCost - variableCost) * (1 + depositeRate);
double inventoryLevel = state.getIniInventory() + action - randomDemand;
double holdCosts = holdCostUnit * Math.max(inventoryLevel, 0);
double cashIncrement = revenue + deposite - holdCosts - overheadCosts[t] - state.getIniCash();
double salValue = state.getPeriod() == T ? salvageValueUnit * Math.max(inventoryLevel, 0) : 0;
cashIncrement += salValue;
return cashIncrement;
};
// state transition function
StateTransitionFunction<CashState, Double, Double, CashState> stateTransition = (state, action, randomDemand) -> {
double nextInventory = Math.max(0, state.getIniInventory() + action - randomDemand);
double nextCash = state.getIniCash() + immediateValue.apply(state, action, randomDemand);
nextCash = nextCash > maxCashState ? maxCashState : nextCash;
nextCash = nextCash < minCashState ? minCashState : nextCash;
nextInventory = nextInventory > maxInventoryState ? maxInventoryState : nextInventory;
nextInventory = nextInventory < minInventoryState ? minInventoryState : nextInventory;
// cash is integer or not
// the right should be a decimal
nextCash = Math.round(nextCash * 1) / 1;
return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
};
int period = 1;
CashState initialState = new CashState(period, iniI, iniCash);
double[] result1;
// no need to add overheadCost in this class
CashSimulation simulation1 = new CashSimulation(distributions, sampleNum, immediateValue, stateTransition);
double error;
double thisServiceRate;
result1 = simulation1.simulateSAA(initialState, result[0], serviceRate, sampleNums, prices, variCostUnits, overheadCosts, salvageValueUnit, holdCostUnit, scenarios, sampleNum);
System.out.println("final simulated survival probability of SAA in " + df.format(sampleNum) + " samples is: " + nf.format(result1[0]));
error = 1.96 * Math.sqrt(result1[1] * (1 - result1[1]) / sampleNum);
thisServiceRate = 1 - result1[1];
System.out.println("final simulated service sale rate of SAA " + " is: " + nf.format(thisServiceRate) + " with error " + nf.format(error));
/**
* solve the problem by extended formulation of SAA,
* sort scenarios in the whole planning horizon
*/
currTime = System.currentTimeMillis();
// same result with soveSort or solveSort2, but less computational time
result = model.solveSortWhole();
// former name is solveSortFurther()
time1 = (System.currentTimeMillis() - currTime) / 1000.00;
currTime = System.currentTimeMillis();
System.out.println("**********************************************");
System.out.println("after sorting scenarios in the whole planning horizon, result of SAA-scenario tree: ");
System.out.println("running time is " + time1 + "s");
System.out.printf("first stage decison Q is: %.2f\n", result[0]);
positiveScenario = result[1];
System.out.printf("Objective value is: %.0f in %d scenarios\n", positiveScenario, sampleNumTotal);
survivalProb = 100 * result[1] / sampleNumTotal;
System.out.printf("Survival probability is: %.5f%%\n", survivalProb);
System.out.println("lost sale scenario number in the solution is : " + result[2]);
System.out.println("maximum lost sale scenario number allowed is: " + negativeScenarioNumRequire);
lostRate = result[2] / (double) sampleNumTotal;
System.out.println("lost sale rate of SAA is: " + nf.format(lostRate));
System.out.println("lost sale max required rate is: " + nf.format(1 - serviceRate));
System.out.println();
/**
* Simulate the result of extended SAA
*/
result1 = simulation1.simulateExtendSAAWhole(initialState, result[0], serviceRate, sampleNums, prices, variCostUnits, overheadCosts, salvageValueUnit, holdCostUnit, scenarios, sampleNum);
System.out.println("final simulated survival probability of extended SAA(sort whole planning horizon) in " + df.format(sampleNum) + " samples is: " + nf.format(result1[0]));
error = 1.96 * Math.sqrt(result1[1] * (1 - result1[1]) / sampleNum);
thisServiceRate = 1 - result1[1];
System.out.println("final simulated service rate of extended SAA(sort whole planning horizon) " + " is: " + nf.format(thisServiceRate) + " with error " + nf.format(error));
/**
* solve the problem by extended formulation of SAA,
* sort scenarios in each period.
*/
// currTime = System.currentTimeMillis();
// result = model.solveSortEach(); // same result with soveSort or solveSort2, but less computational time
// // former name is solveSortFurther()
//
// time1 = (System.currentTimeMillis() - currTime) / 1000.00;
// currTime = System.currentTimeMillis();
// System.out.println("**********************************************");
// System.out.println("after sorting scenarios in each period, the result of SAA-scenario tree: ");
// System.out.println("running time is " + time1 + "s");
// System.out.printf("first stage decison Q is: %.2f\n", result[0]);
// positiveScenario = result[1];
// System.out.printf("Objective value is: %.0f in %d scenarios\n", positiveScenario, sampleNumTotal);
// survivalProb = 100 * result[1] / sampleNumTotal;
// System.out.printf("Survival probability is: %.5f%%\n", survivalProb);
// System.out.println("lost sale scenario number in the solution is : " + result[2]);
// System.out.println("maximum lost sale scenario number allowed is: " + negativeScenarioNumRequire);
// lostRate = result[2] / (double) sampleNumTotal;
// System.out.println("lost sale rate of SAA is: " + nf.format(lostRate));
// System.out.println("lost sale max required rate is: " + nf.format(1 - serviceRate));
// System.out.println();
//
// /**
// * Simulate the result of extended SAA sorting each period
// */
// result1 = simulation1.simulateExtendSAAEach(initialState, result[0], serviceRate, sampleNums, prices, variCostUnits, overheadCosts, salvageValueUnit, holdCostUnit, scenarios, sampleNum);
// System.out.println("final simulated survival probability of extended SAA sorting each period in " + df.format(sampleNum) + " samples is: " + nf.format(result1[0]));
// System.out.println("final simulated lost sale rate of extended SAA sorting each period " + " is: " + nf.format(result1[1]));
/**
* solve the problem by SDP when there is no joint chance constraint
*/
// feasible actions
Function<CashState, double[]> getFeasibleAction1 = s -> {
int t = s.getPeriod() - 1;
double thisPeriodServRate = (1 - serviceRate) / T;
// double minQ = Math.ceil(distributions[t].inverseF(1 - thisPeriodServRate)); // minimum ordering quantity in each period
double minQ = 0;
return DoubleStream.iterate(minQ, i -> i + stepSize).limit((int) maxOrderQuantity + 1).toArray();
};
/**
*****************************************************************
* Solve
*/
CashRecursion recursion = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction1, stateTransition, immediateValue, discountFactor);
currTime = System.currentTimeMillis();
recursion.setTreeMapCacheAction();
double finalValue = recursion.getSurvProb(initialState);
System.out.println("**********************************************");
System.out.println("result of SDP with no service rate constraint is: ");
System.out.println("survival probability for this initial state is: " + nf.format(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 sdp results
*/
sampleNum = 10000;
// no need to add overheadCost in this class
CashSimulation simulation = new CashSimulation(distributions, sampleNum, recursion, discountFactor);
double[] result2 = simulation.simulateSDPGivenSamplNum(initialState, immediateValue);
System.out.println("final simulated survival probability in " + df.format(sampleNum) + " samples is: " + nf.format(result2[0]));
System.out.println("final simulated lost sale rate " + " is: " + nf.format(result2[1]));
/**
*****************************************************************
* solve the problem by SDP when there is individual chance constraint approximation
*/
// feasible actions 2
// in fact, no cash constraint in this paper
Function<CashState, double[]> getFeasibleAction2 = s -> {
int t = s.getPeriod() - 1;
double thisPeriodServRate = (1 - serviceRate) / T;
// minimum ordering quantity in each period
double minQ = Math.ceil(distributions[t].inverseF(1 - thisPeriodServRate));
return DoubleStream.iterate(minQ, i -> i + stepSize).limit((int) maxOrderQuantity + 1).toArray();
};
/**
*****************************************************************
* Solve
*/
recursion = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction2, stateTransition, immediateValue, discountFactor);
period = 1;
initialState = new CashState(period, iniI, iniCash);
currTime = System.currentTimeMillis();
recursion.setTreeMapCacheAction();
finalValue = recursion.getSurvProb(initialState);
System.out.println("**********************************************");
System.out.println("result of SDP with service rate constraint is: ");
finalValue = finalValue * 100;
System.out.printf("survival probability for this initial state is: %.2f%%\n", finalValue);
System.out.println("optimal order quantity in the first priod is : " + recursion.getAction(initialState));
time = (System.currentTimeMillis() - currTime) / 1000;
System.out.println("running time is " + time + "s");
/**
*****************************************************************
* Simulating sdp results
*/
sampleNum = 10000;
// no need to add overheadCost in this class
simulation = new CashSimulation(distributions, sampleNum, recursion, discountFactor);
result2 = simulation.simulateSDPGivenSamplNum(initialState, immediateValue);
System.out.println("final simulated survival probability in " + df.format(sampleNum) + " samples is: " + nf.format(result2[0]));
System.out.println("final simulated lost sale rate " + " is: " + nf.format(result2[1]));
/**
* solve the problem by rolling horizon of further SAA
*/
// number of scenarios for rolling SAA
sampleNum = 100;
currTime = System.currentTimeMillis();
System.out.println("**********************************************");
result1 = simulation1.rollingHoirzonFurtherExtendSAA(rollingLength, initialState, rollingServiceRate, sampleNumsRolling, prices, variCostUnits, overheadCosts, salvageValueUnit, holdCostUnit, scenarios, sampleNum);
time1 = (System.currentTimeMillis() - currTime) / 1000.00;
System.out.println("after rolling horizon for length " + rollingLength + ", result of SAA-scenario tree: ");
System.out.println("running time is " + time1 + "s");
System.out.println("final simulated survival probability of rolling further SAA in " + df.format(sampleNum) + " samples is: " + nf.format(result1[0]));
System.out.println("final simulated lost sale rate of rolling further SAA " + " is: " + nf.format(result1[1]));
}
Aggregations