Search in sources :

Example 1 with CashRecursion

use of sdp.cash.CashRecursion in project Stochastic-Inventory by RobinChen121.

the class CheckFG method main.

public static void main(String[] args) {
    double[] meanDemand = { 8, 8, 8 };
    double iniCash = 13;
    double iniInventory = 0;
    double fixOrderCost = 10;
    double variCost = 1;
    double price = 8;
    double salvageValue = 0.5;
    double holdingCost = 0;
    // 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(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 = 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 F(x, R)
     */
    int minInventorys = 0;
    // for drawing pictures
    int maxInventorys = 100;
    int minCash = 0;
    int maxCash = (int) fixOrderCost + 80;
    int RLength = maxCash - minCash + 1;
    int xLength = maxInventorys - minInventorys + 1;
    int period = 1;
    int index = 0;
    int rowIndex = 0;
    int columnIndex = 0;
    long currTime = System.currentTimeMillis();
    CashRecursion recursion = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition, immediateValue, discountFactor);
    double[][] yG = new double[xLength * RLength][3];
    double[][] resultTableF = new double[RLength][xLength];
    double[][] resultTableQ = new double[RLength][xLength];
    for (double initialCash = minCash; initialCash <= maxCash; initialCash++) {
        columnIndex = 0;
        for (double initialInventory = minInventorys; initialInventory <= maxInventorys; initialInventory++) {
            // initialInventory
            yG[index][0] = initialCash;
            yG[index][1] = initialInventory;
            // iniCash
            yG[index][2] = recursion.getExpectedValue(new CashState(period, initialInventory, initialCash));
            resultTableF[rowIndex][columnIndex] = yG[index][2];
            resultTableQ[rowIndex][columnIndex] = recursion.getAction(new CashState(period, initialInventory, initialCash));
            index++;
            columnIndex++;
        }
        rowIndex++;
    }
    // immediate value for GB and GA
    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;
            // variCost * state.getIniInventory(); // be careful
            variableCost = 0;
            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 for GA
    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[xLength][RLength];
    rowIndex = 0;
    for (double initialInventory = minInventoryState; initialInventory <= maxInventorys; initialInventory++) {
        columnIndex = 0;
        for (double initialCash = minCash; initialCash <= maxCash; initialCash++) {
            // initialInventory
            yG3[index][0] = initialInventory;
            // initialCash
            yG3[index][1] = initialCash;
            yG3[index][2] = recursion3.getExpectedValue(new CashState(period, initialInventory, initialCash)) - variCost * initialInventory;
            // careful, minus cy
            resultTableGA[rowIndex][columnIndex] = yG3[index][2];
            index++;
            columnIndex++;
        }
        rowIndex++;
    }
    double[][] resultH = recursion3.getH(resultTableGA, minCash, fixOrderCost, variCost);
    System.out.println("Single-crossing property: " + recursion3.checkSingleCrossing(resultH));
    WriteToCsv wr = new WriteToCsv();
    wr.writeArrayCSVLabel(resultTableQ, minCash, minInventorys, "Q.csv");
    wr.writeArrayCSVLabel(resultTableF, minCash, minInventorys, "F.csv");
    wr.writeArrayCSVLabel(resultTableGA, minCash, minInventorys, "G.csv");
    wr.writeArrayCSVLabel(resultH, minCash, minInventorys, "H.csv");
    // wr.writeArrayCSV(recursion3.getH3Column(resultTableGA, minCash, fixOrderCost, variCost), "G3column.csv");
    double time = (System.currentTimeMillis() - currTime) / 1000;
    System.out.println("running time is " + time + "s");
}
Also used : IntStream(java.util.stream.IntStream) GetPmf(sdp.inventory.GetPmf) ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) WriteToCsv(sdp.write.WriteToCsv) CashRecursion(sdp.cash.CashRecursion) OptDirection(sdp.cash.CashRecursion.OptDirection) CashState(sdp.cash.CashState) Function(java.util.function.Function) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) PoissonDist(umontreal.ssj.probdist.PoissonDist) Distribution(umontreal.ssj.probdist.Distribution) DoubleStream(java.util.stream.DoubleStream) PoissonDist(umontreal.ssj.probdist.PoissonDist) WriteToCsv(sdp.write.WriteToCsv) CashRecursion(sdp.cash.CashRecursion) Distribution(umontreal.ssj.probdist.Distribution) CashState(sdp.cash.CashState) GetPmf(sdp.inventory.GetPmf)

Example 2 with CashRecursion

use of sdp.cash.CashRecursion in project Stochastic-Inventory by RobinChen121.

the class SingleCrossTesting method main.

public static void main(String[] args) {
    String headString = "K, v, h, price, salvageValue, DemandPatt, Single-crossing";
    WriteToCsv.writeToFile("./" + "test_results.csv", headString);
    double[][] iniMeanDemands = { { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }, { 21.15, 18.9, 17.7, 16.5, 15.15, 13.95, 12.75, 11.55, 10.35, 9.15 }, { 6.6, 9.3, 11.1, 12.9, 16.8, 21.6, 24, 26.4, 31.5, 33.9 }, { 12.1, 10, 7.9, 7, 7.9, 10, 12.1, 13, 12.1, 10 }, { 15.7, 10, 4.3, 2, 4.3, 10, 15.7, 18, 15.7, 10 }, { 41.8, 6.6, 2, 21.8, 44.8, 9.6, 2.6, 17, 30, 35.4 }, { 4.08, 12.16, 37.36, 21.44, 39.12, 35.68, 19.84, 22.48, 29.04, 12.4 }, { 4.7, 8.1, 23.6, 39.4, 16.4, 28.7, 50.8, 39.1, 75.4, 69.4 }, { 4.4, 11.6, 26.4, 14.4, 14.6, 19.8, 7.4, 18.3, 20.4, 11.4 }, { 4.9, 18.8, 6.4, 27.9, 45.3, 22.4, 22.3, 51.7, 29.1, 54.7 } };
    double[] K = { 10 };
    double[] v = { 1 };
    // ini cash can order 4 or 6 items
    double[] B0 = { 3, 5, 7 };
    // margin is 4, 5, 6
    double[] p = { 5, 6, 7 };
    double[] h = { 0 };
    double salvageValue = 0;
    FindCCrieria criteria = FindCCrieria.XRELATE;
    double truncationQuantile = 0.999;
    int stepSize = 1;
    // minimum cash balance the retailer can withstand
    double overheadCost = 0;
    // maximum ordering quantity when having enough cash
    double maxOrderQuantity = 150;
    double minInventoryState = 0;
    double maxInventoryState = 200;
    // can affect results, should be smaller than minus fixedOrderCost
    double minCashState = -100;
    double maxCashState = 1500;
    // generally 1 for the cash constrained problem
    double discountFactor = 1;
    boolean isForDrawGy = true;
    /**
     *****************************************************************
     * set demands length, for testing
     */
    int TLength = 2;
    double[][] meanDemands = new double[iniMeanDemands.length][TLength];
    for (int i = 0; i < iniMeanDemands.length; i++) for (int j = 0; j < TLength; j++) {
        meanDemands[i][j] = iniMeanDemands[i][j];
    }
    for (int idemand = 0; idemand < meanDemands.length; idemand++) for (int iK = 0; iK < K.length; iK++) for (int iv = 0; iv < v.length; iv++) for (int ip = 0; ip < p.length; ip++) for (int ih = 0; ih < h.length; ih++) {
        double[] meanDemand = meanDemands[idemand];
        double fixOrderCost = K[iK];
        double variCost = v[iv];
        double price = p[ip];
        double holdingCost = h[ih];
        int minInventorys = 0;
        // for drawing pictures
        int maxInventorys = 30;
        int minCash = 0;
        int maxCash = (int) fixOrderCost + 30;
        int RLength = maxCash - minCash + 1;
        int xLength = maxInventorys - minInventorys + 1;
        int period = 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 = 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;
                // variCost * state.getIniInventory(); // be careful
                variableCost = 0;
                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
        StateTransitionFunction<CashState, Double, Double, CashState> stateTransition = (state, action, randomDemand) -> {
            double nextInventory = isForDrawGy && state.getPeriod() == 1 ? state.getIniInventory() - randomDemand : 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;
            return new CashState(state.getPeriod() + 1, nextInventory, nextCash);
        };
        long currTime = System.currentTimeMillis();
        CashRecursion recursion = new CashRecursion(OptDirection.MAX, pmf, getFeasibleAction, stateTransition, immediateValue, discountFactor);
        double[][] yG = new double[xLength * RLength][3];
        int index = 0;
        double[][] resultTableG = new double[RLength][xLength];
        int rowIndex = 0;
        int columnIndex = 0;
        for (double initialCash = minCash; initialCash <= maxCash; initialCash++) {
            columnIndex = 0;
            for (double initialInventory = minInventorys; initialInventory <= maxInventorys; initialInventory++) {
                // initialInventory
                yG[index][0] = initialCash;
                // initialInventory
                yG[index][1] = initialInventory;
                yG[index][2] = recursion.getExpectedValue(new CashState(period, initialInventory, initialCash)) - variCost * initialInventory;
                // careful, minus cy
                resultTableG[rowIndex][columnIndex] = yG[index][2];
                index++;
                columnIndex++;
            }
            rowIndex++;
        }
        double[][] resultH = recursion.getH(resultTableG, minCash, fixOrderCost, variCost);
        boolean singleCrossing = recursion.checkSingleCrossing(resultH);
        System.out.println("Single-crossing property: " + singleCrossing);
        double time = (System.currentTimeMillis() - currTime) / 1000.0;
        System.out.println("running time is " + time + "s");
        String out = fixOrderCost + ",\t" + variCost + ",\t" + holdingCost + ",\t" + price + ",\t" + salvageValue + ",\t" + (idemand + 1) + ",\t" + singleCrossing;
        WriteToCsv.writeToFile("./" + "test_results.csv", out);
    }
}
Also used : IntStream(java.util.stream.IntStream) ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) FindCCrieria(cash.strongconstraint.FindsCS.FindCCrieria) WriteToCsv(sdp.write.WriteToCsv) CashRecursion(sdp.cash.CashRecursion) OptDirection(sdp.cash.CashRecursion.OptDirection) CashState(sdp.cash.CashState) Function(java.util.function.Function) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) DoubleStream(java.util.stream.DoubleStream) GetPmf(sdp.inventory.GetPmf) PoissonDist(umontreal.ssj.probdist.PoissonDist) Distribution(umontreal.ssj.probdist.Distribution) PoissonDist(umontreal.ssj.probdist.PoissonDist) FindCCrieria(cash.strongconstraint.FindsCS.FindCCrieria) CashRecursion(sdp.cash.CashRecursion) Distribution(umontreal.ssj.probdist.Distribution) CashState(sdp.cash.CashState) GetPmf(sdp.inventory.GetPmf)

Example 3 with CashRecursion

use of sdp.cash.CashRecursion 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]);
}
Also used : IntStream(java.util.stream.IntStream) ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) FindCCrieria(cash.strongconstraint.FindsCS.FindCCrieria) CashSimulation(sdp.cash.CashSimulation) CashRecursion(sdp.cash.CashRecursion) DecimalFormat(java.text.DecimalFormat) OptDirection(sdp.cash.CashRecursion.OptDirection) CashState(sdp.cash.CashState) Function(java.util.function.Function) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) DoubleStream(java.util.stream.DoubleStream) GetPmf(sdp.inventory.GetPmf) PoissonDist(umontreal.ssj.probdist.PoissonDist) Distribution(umontreal.ssj.probdist.Distribution) CashSimulation(sdp.cash.CashSimulation) PoissonDist(umontreal.ssj.probdist.PoissonDist) DecimalFormat(java.text.DecimalFormat) FindCCrieria(cash.strongconstraint.FindsCS.FindCCrieria) CashRecursion(sdp.cash.CashRecursion) Distribution(umontreal.ssj.probdist.Distribution) CashState(sdp.cash.CashState) GetPmf(sdp.inventory.GetPmf)

Example 4 with CashRecursion

use of sdp.cash.CashRecursion 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();
// 
}
Also used : IntStream(java.util.stream.IntStream) ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) FindCCrieria(cash.strongconstraint.FindsCS.FindCCrieria) CashSimulation(sdp.cash.CashSimulation) Arrays(java.util.Arrays) DiscreteDistribution(umontreal.ssj.probdist.DiscreteDistribution) WriteToCsv(sdp.write.WriteToCsv) CashRecursion(sdp.cash.CashRecursion) OptDirection(sdp.cash.CashRecursion.OptDirection) MipCashConstraint(milp.MipCashConstraint) CashState(sdp.cash.CashState) NormalDist(umontreal.ssj.probdist.NormalDist) Function(java.util.function.Function) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) ArrayList(java.util.ArrayList) DoubleStream(java.util.stream.DoubleStream) GetPmf(sdp.inventory.GetPmf) CheckKConvexity(sdp.inventory.CheckKConvexity) TreeMap(java.util.TreeMap) Map(java.util.Map) State(sdp.inventory.State) PoissonDist(umontreal.ssj.probdist.PoissonDist) Drawing(sdp.inventory.Drawing) Distribution(umontreal.ssj.probdist.Distribution) CashSimulation(sdp.cash.CashSimulation) PoissonDist(umontreal.ssj.probdist.PoissonDist) MipCashConstraint(milp.MipCashConstraint) FindCCrieria(cash.strongconstraint.FindsCS.FindCCrieria) CashRecursion(sdp.cash.CashRecursion) DiscreteDistribution(umontreal.ssj.probdist.DiscreteDistribution) Distribution(umontreal.ssj.probdist.Distribution) CashState(sdp.cash.CashState) GetPmf(sdp.inventory.GetPmf)

Example 5 with CashRecursion

use of sdp.cash.CashRecursion 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);
}
Also used : IntStream(java.util.stream.IntStream) ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) FindCCrieria(cash.strongconstraint.FindsCS.FindCCrieria) CashSimulation(sdp.cash.CashSimulation) DiscreteDistribution(umontreal.ssj.probdist.DiscreteDistribution) WriteToCsv(sdp.write.WriteToCsv) CashRecursion(sdp.cash.CashRecursion) OptDirection(sdp.cash.CashRecursion.OptDirection) CashState(sdp.cash.CashState) Function(java.util.function.Function) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) DoubleStream(java.util.stream.DoubleStream) GetPmf(sdp.inventory.GetPmf) CheckKConvexity(sdp.inventory.CheckKConvexity) TreeMap(java.util.TreeMap) Map(java.util.Map) State(sdp.inventory.State) WriteToExcel(sdp.write.WriteToExcel) PoissonDist(umontreal.ssj.probdist.PoissonDist) Drawing(sdp.inventory.Drawing) Distribution(umontreal.ssj.probdist.Distribution) CashSimulation(sdp.cash.CashSimulation) Drawing(sdp.inventory.Drawing) WriteToCsv(sdp.write.WriteToCsv) CashRecursion(sdp.cash.CashRecursion) CashState(sdp.cash.CashState) GetPmf(sdp.inventory.GetPmf) PoissonDist(umontreal.ssj.probdist.PoissonDist) TreeMap(java.util.TreeMap) FindCCrieria(cash.strongconstraint.FindsCS.FindCCrieria) CashState(sdp.cash.CashState) State(sdp.inventory.State) DiscreteDistribution(umontreal.ssj.probdist.DiscreteDistribution) Distribution(umontreal.ssj.probdist.Distribution)

Aggregations

Function (java.util.function.Function)16 CashRecursion (sdp.cash.CashRecursion)16 CashState (sdp.cash.CashState)16 GetPmf (sdp.inventory.GetPmf)16 ImmediateValueFunction (sdp.inventory.ImmediateValue.ImmediateValueFunction)16 StateTransitionFunction (sdp.inventory.StateTransition.StateTransitionFunction)16 PoissonDist (umontreal.ssj.probdist.PoissonDist)16 Distribution (umontreal.ssj.probdist.Distribution)15 DoubleStream (java.util.stream.DoubleStream)13 IntStream (java.util.stream.IntStream)13 OptDirection (sdp.cash.CashRecursion.OptDirection)13 CashSimulation (sdp.cash.CashSimulation)11 FindCCrieria (cash.strongconstraint.FindsCS.FindCCrieria)8 Arrays (java.util.Arrays)6 Map (java.util.Map)6 TreeMap (java.util.TreeMap)6 WriteToCsv (sdp.write.WriteToCsv)6 State (sdp.inventory.State)5 MipCashConstraint (milp.MipCashConstraint)4 ArrayList (java.util.ArrayList)3