Search in sources :

Example 1 with CashState

use of sdp.cash.CashState 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 CashState

use of sdp.cash.CashState 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 CashState

use of sdp.cash.CashState 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 CashState

use of sdp.cash.CashState 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 CashState

use of sdp.cash.CashState 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

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