Search in sources :

Example 1 with GetPmf

use of sdp.inventory.GetPmf in project Stochastic-Inventory by RobinChen121.

the class LevelFitsS method main.

public static void main(String[] args) {
    double truncationQuantile = 0.9999;
    double stepSize = 1;
    double minInventory = -500;
    double maxInventory = 1000;
    double fixedOrderingCost = 250;
    double variOrderingCost = 0;
    double penaltyCost = 26;
    // double[] meanDemand = { 20, 40, 60, 40 };
    double holdingCost = 1;
    int maxOrderQuantity = 41;
    boolean isForDrawGy = true;
    // // get demand possibilities for each period
    // int T = meanDemand.length;
    // Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T)
    // //.mapToObj(i -> new PoissonDist(meanDemand[i]))
    // .mapToObj(i -> new NormalDist(meanDemand[i], coeValue * meanDemand[i]))
    // .toArray(Distribution[]::new);
    // double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
    // int T = 8;
    // double[] values = {6, 7};
    // double[] probs = {0.95, 0.05};
    // Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T)
    // .mapToObj(i -> new DiscreteDistribution(values, probs, values.length)) // can be changed to other distributions
    // .toArray(DiscreteDistribution[]::new);
    // double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
    int T = 4;
    double[][] values = { { 34, 159, 281, 286 }, { 14, 223, 225, 232 }, { 5, 64, 115, 171 }, { 35, 48, 145, 210 } };
    double[][] probs = { { 0.018, 0.888, 0.046, 0.048 }, { 0.028, 0.271, 0.17, 0.531 }, { 0.041, 0.027, 0.889, 0.043 }, { 0.069, 0.008, 0.019, 0.904 } };
    Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T).mapToObj(// can be changed to other distributions
    i -> new DiscreteDistribution(values[i], probs[i], values[i].length)).toArray(DiscreteDistribution[]::new);
    double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
    // feasible actions
    Function<State, double[]> getFeasibleAction = s -> {
        double[] feasibleActions = new double[(int) (maxOrderQuantity / stepSize) + 1];
        int index = 0;
        for (double i = 0; i <= maxOrderQuantity; i = i + stepSize) {
            feasibleActions[index] = i;
            index++;
        }
        return feasibleActions;
    };
    // state transition function
    StateTransitionFunction<State, Double, Double, State> stateTransition = (state, action, randomDemand) -> {
        double nextInventory = state.getIniInventory() + action - randomDemand;
        nextInventory = nextInventory > maxInventory ? maxInventory : nextInventory;
        nextInventory = nextInventory < minInventory ? minInventory : nextInventory;
        return new State(state.getPeriod() + 1, nextInventory);
    };
    // immediate value
    ImmediateValueFunction<State, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
        double fixedCost = 0, variableCost = 0, inventoryLevel = 0, holdingCosts = 0, penaltyCosts = 0;
        fixedCost = action > 0 ? fixedOrderingCost : 0;
        variableCost = variOrderingCost * action;
        inventoryLevel = state.getIniInventory() + action - randomDemand;
        holdingCosts = holdingCost * Math.max(inventoryLevel, 0);
        penaltyCosts = penaltyCost * Math.max(-inventoryLevel, 0);
        double totalCosts = fixedCost + variableCost + holdingCosts + penaltyCosts;
        return totalCosts;
    };
    /**
     *****************************************************************
     * Solve
     */
    Recursion recursion = new Recursion(OptDirection.MIN, pmf, getFeasibleAction, stateTransition, immediateValue);
    int period = 1;
    double iniInventory = 500;
    State initialState = new State(period, iniInventory);
    long currTime = System.currentTimeMillis();
    double opt = recursion.getExpectedValue(initialState);
    System.out.println("final optimal expected value is: " + opt);
    System.out.println("optimal order quantity in the first priod is : " + recursion.getAction(initialState));
    double time = (System.currentTimeMillis() - currTime) / 1000;
    System.out.println("running time is " + time + "s");
    /**
     *****************************************************************
     * Simulating sdp results
     */
    int sampleNum = 10000;
    SimulateFitsS simuation = new SimulateFitsS(distributions, sampleNum, recursion);
    simuation.simulateSDPGivenSamplNum(initialState);
    double error = 0.0001;
    double confidence = 0.95;
    simuation.simulateSDPwithErrorConfidence(initialState, error, confidence);
    /**
     *****************************************************************
     * Fit (s, S) levels
     */
    System.out.println("");
    double[][] optTable = recursion.getOptTable();
    MIPFitsS findsS = new MIPFitsS(maxOrderQuantity, T);
    double[][] optsS = findsS.getSinglesS(optTable);
    System.out.println("single s, S level: " + Arrays.deepToString(optsS));
    optsS = findsS.getTwosS(optTable);
    System.out.println("two s, S level: " + Arrays.deepToString(optsS));
    optsS = findsS.getThreesS(optTable);
    System.out.println("three s, S level: " + Arrays.deepToString(optsS));
    double sim1 = simuation.simulateSinglesS(initialState, optsS, maxOrderQuantity);
    System.out.printf("one level gap is %.2f%%\n", (sim1 - opt) * 100 / opt);
    double sim2 = simuation.simulateTwosS(initialState, optsS, maxOrderQuantity);
    System.out.printf("two level gap is %.2f%%\n", (sim2 - opt) * 100 / opt);
    double sim3 = simuation.simulateThreesS(initialState, optsS, maxOrderQuantity);
    System.out.printf("three level gap is %.2f%%\n", (sim3 - opt) * 100 / opt);
}
Also used : IntStream(java.util.stream.IntStream) ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) Arrays(java.util.Arrays) DiscreteDistribution(umontreal.ssj.probdist.DiscreteDistribution) NormalDist(umontreal.ssj.probdist.NormalDist) MIPFitsS(milp.MIPFitsS) Function(java.util.function.Function) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) GetPmf(sdp.inventory.GetPmf) OptDirection(sdp.inventory.Recursion.OptDirection) CheckKConvexity(sdp.inventory.CheckKConvexity) State(sdp.inventory.State) Recursion(sdp.inventory.Recursion) PoissonDist(umontreal.ssj.probdist.PoissonDist) Drawing(sdp.inventory.Drawing) Distribution(umontreal.ssj.probdist.Distribution) Recursion(sdp.inventory.Recursion) MIPFitsS(milp.MIPFitsS) State(sdp.inventory.State) DiscreteDistribution(umontreal.ssj.probdist.DiscreteDistribution) Distribution(umontreal.ssj.probdist.Distribution) GetPmf(sdp.inventory.GetPmf) DiscreteDistribution(umontreal.ssj.probdist.DiscreteDistribution)

Example 2 with GetPmf

use of sdp.inventory.GetPmf in project Stochastic-Inventory by RobinChen121.

the class TwoLevelFitsSTest method main.

public static void main(String[] args) {
    String headString = "K, v, h, I0, pai, Qmax, DemandPatt, OpValue, Time(sec), simValue, error";
    WriteToCsv.writeToFile("./" + "test_results.csv", headString);
    double[][] demands = { { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }, { 6.6, 9.3, 11.1, 12.9, 16.8, 21.6, 24, 26.4, 31.5, 33.9, 36.3, 40.8, 44.4, 47.1, 48.3, 50.1, 50.1, 48.9, 47.1, 44.4 }, { 45.9, 48.6, 49.8, 49.8, 48.6, 45.9, 42.3, 37.8, 35.4, 33, 30.3, 27.9, 25.5, 23.1, 20.7, 18.3, 14.4, 10.8, 8.1, 6.3 }, { 36.3, 30, 23.7, 21, 23.7, 30, 36.3, 39, 36.3, 30, 23.7, 21, 23.7, 30, 36.3, 30.9, 24.3, 21.3, 26.4, 33 }, { 47.1, 30, 12.9, 6, 12.9, 30, 47.1, 54, 47.1, 30, 12.9, 6, 12.9, 30, 47.1, 29.7, 15, 7.5, 11.4, 29.7 }, { 62.7, 27.3, 9.9, 23.7, 1, 22.8, 32.7, 34.5, 67.2, 6.6, 14.4, 40.8, 3.9, 63.3, 25.5, 45, 53.1, 24.6, 10.2, 49.8 }, { 1, 15.3, 45.6, 140.1, 80.4, 146.7, 133.8, 74.4, 84.3, 108.9, 46.5, 87.9, 66, 27.9, 32.1, 88.5, 161.7, 36, 32.4, 49.8 }, { 14.1, 24.3, 70.8, 118.2, 49.2, 86.1, 152.4, 117.3, 226.2, 208.2, 78.3, 58.5, 96, 33.3, 57.3, 115.5, 17.7, 134.7, 127.8, 179.7 }, { 13.2, 34.8, 79.2, 43.2, 43.8, 59.4, 22.2, 54.9, 61.2, 34.2, 49.5, 95.4, 35.7, 144.6, 160.2, 103.8, 150.6, 86.4, 122.7, 63.6 }, { 14.7, 56.4, 19.2, 83.7, 135.9, 67.2, 66.9, 155.1, 87.3, 164.1, 193.8, 67.2, 64.5, 132, 34.8, 131.4, 132.9, 35.7, 172.5, 152.1 } };
    // 1500, 1000, 500
    double[] K = { 500, 800, 200 };
    double[] v = { 0, 5, 10 };
    // 15, 10, 5
    double[] pai = { 15, 10, 5 };
    // 3, 5, 7
    double[] capacity = { 2, 3, 4 };
    double truncationQuantile = 0.9999;
    double stepSize = 1;
    double minInventory = -300;
    double maxInventory = 800;
    double holdingCost = 1;
    for (int iK = 0; iK < K.length; iK++) {
        for (int iv = 0; iv < v.length; iv++) {
            for (int ipai = 0; ipai < pai.length; ipai++) {
                for (int idemand = 0; idemand < demands.length; idemand++) for (int icapacity = 0; icapacity < capacity.length; icapacity++) {
                    // double[] meanDemand = demands[idemand];
                    double[] meanDemand = { 9, 23, 53, 29 };
                    double fixedOrderingCost = K[iK];
                    double proportionalOrderingCost = v[iv];
                    double penaltyCost = pai[ipai];
                    int maxOrderQuantity = (int) (Math.round(Arrays.stream(meanDemand).sum() / meanDemand.length) * capacity[icapacity]);
                    // get demand possibilities for each period
                    int T = meanDemand.length;
                    Distribution[] distributions = IntStream.iterate(0, i -> i + 1).limit(T).mapToObj(// can be changed to other distributions
                    i -> new PoissonDist(meanDemand[i])).toArray(PoissonDist[]::new);
                    double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
                    // feasible actions
                    Function<State, double[]> getFeasibleAction = s -> {
                        double[] feasibleActions = new double[(int) (maxOrderQuantity / stepSize) + 1];
                        int index = 0;
                        for (double i = 0; i <= maxOrderQuantity; i = i + stepSize) {
                            feasibleActions[index] = i;
                            index++;
                        }
                        return feasibleActions;
                    };
                    // state transition function
                    StateTransitionFunction<State, Double, Double, State> stateTransition = (state, action, randomDemand) -> {
                        double nextInventory = state.getIniInventory() + action - randomDemand;
                        nextInventory = nextInventory > maxInventory ? maxInventory : nextInventory;
                        nextInventory = nextInventory < minInventory ? minInventory : nextInventory;
                        return new State(state.getPeriod() + 1, nextInventory);
                    };
                    // immediate value
                    ImmediateValueFunction<State, Double, Double, Double> immediateValue = (state, action, randomDemand) -> {
                        double fixedCost = 0, variableCost = 0, inventoryLevel = 0, holdingCosts = 0, penaltyCosts = 0;
                        fixedCost = action > 0 ? fixedOrderingCost : 0;
                        variableCost = proportionalOrderingCost * action;
                        inventoryLevel = state.getIniInventory() + action - randomDemand;
                        holdingCosts = holdingCost * Math.max(inventoryLevel, 0);
                        penaltyCosts = penaltyCost * Math.max(-inventoryLevel, 0);
                        double totalCosts = fixedCost + variableCost + holdingCosts + penaltyCosts;
                        return totalCosts;
                    };
                    /**
                     *****************************************************************
                     * Solve
                     */
                    Recursion recursion = new Recursion(OptDirection.MIN, pmf, getFeasibleAction, stateTransition, immediateValue);
                    // using tree map when finding levels for s and S
                    recursion.setTreeMapCacheAction();
                    int period = 1;
                    double iniInventory = 0;
                    State initialState = new State(period, iniInventory);
                    long currTime = System.currentTimeMillis();
                    double finalValue = recursion.getExpectedValue(initialState);
                    System.out.println("final optimal expected value is: " + finalValue);
                    System.out.println("optimal order quantity in the first priod is : " + recursion.getAction(initialState));
                    double time = (System.currentTimeMillis() - currTime) / 1000;
                    System.out.println("running time is " + time + "s");
                    /**
                     *****************************************************************
                     * Simulating two level s S results
                     */
                    int sampleNum = 10000;
                    SimulateFitsS simuation = new SimulateFitsS(distributions, sampleNum, recursion);
                    double[][] optTable = recursion.getOptTable();
                    MIPFitsS findsS = new MIPFitsS(maxOrderQuantity, T);
                    double[][] optsS = findsS.getTwosS(optTable);
                    System.out.println(Arrays.deepToString(optsS));
                    simuation.simulateSDPGivenSamplNum(initialState);
                    double simFinalValue = simuation.simulateTwosS(initialState, optsS, maxOrderQuantity);
                    System.out.printf("Optimality gap is: %.2f%%\n", (simFinalValue - finalValue) / finalValue * 100);
                    String out = fixedOrderingCost + ",\t" + proportionalOrderingCost + ",\t" + holdingCost + ",\t" + iniInventory + ",\t" + penaltyCost + ",\t" + maxOrderQuantity + ",\t" + (idemand + 1) + ",\t" + finalValue + ",\t" + time + ",\t" + simFinalValue + ",\t" + (simFinalValue - finalValue) / finalValue;
                    WriteToCsv.writeToFile("./" + "test_results.csv", out);
                }
            }
        }
    }
}
Also used : PoissonDist(umontreal.ssj.probdist.PoissonDist) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) Recursion(sdp.inventory.Recursion) MIPFitsS(milp.MIPFitsS) ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) Function(java.util.function.Function) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) State(sdp.inventory.State) GetPmf(sdp.inventory.GetPmf) ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction)

Example 3 with GetPmf

use of sdp.inventory.GetPmf in project Stochastic-Inventory by RobinChen121.

the class MultiItemCashG method main.

public static void main(String[] args) {
    double[] price = { 2, 10 };
    // higher margin vs lower margin
    double[] variCost = { 1, 2 };
    // initial cash
    double iniCash = 10;
    // initial inventory
    int[] iniInventory = { 0, 0 };
    // compute G(d)
    int d = 1;
    int T = 4;
    // mean demand is shape * scale and variance is shape * scale^2
    double[] meanDemands = new double[] { 10, 3 };
    // higher average demand vs lower average demand
    double[][] demand = new double[2][T];
    // higher variance vs lower variance
    double[] beta = { 10, 1 };
    double d1 = meanDemands[0];
    double d2 = meanDemands[1];
    for (int t = 0; t < T; t++) {
        demand[0][t] = d1;
        demand[1][t] = d2;
    }
    double[] salPrice = Arrays.stream(variCost).map(a -> a * 0.5).toArray();
    double truncationQuantile = 0.9999;
    int stepSize = 1;
    int maxInventoryState = 200;
    int Qbound = 40;
    double discountFactor = 1;
    // get shape possibilities for a product in each period
    // normal dist for one product
    GammaDist[] distributions = new GammaDist[T];
    for (int t = 0; t < T; t++) distributions[t] = new GammaDist(demand[d - 1][t] * beta[d - 1], beta[d - 1]);
    // build action list for this item
    Function<State, double[]> buildActionList = s -> {
        return DoubleStream.iterate(0, i -> i + stepSize).limit(Qbound + 1).toArray();
    };
    // Immediate Value Function
    ImmediateValueFunction<State, Double, Double, Double> immediateValue = (IniState, action, randomDemand) -> {
        double revenue = 0;
        revenue = (price[d - 1] - variCost[d - 1]) * Math.min(IniState.getIniInventory() + action, randomDemand);
        if (IniState.getPeriod() == T) {
            revenue += (salPrice[d - 1] - variCost[d - 1]) * Math.max(IniState.getIniInventory() + action - randomDemand, 0);
        }
        return revenue;
    };
    // State Transition Function
    // need change
    StateTransitionFunction<State, Double, Double, State> stateTransition = (IniState, action, randomDemand) -> {
        double endInventory = IniState.getIniInventory() + action - randomDemand;
        endInventory = Math.max(0, endInventory);
        endInventory = endInventory > maxInventoryState ? maxInventoryState : endInventory;
        endInventory = (int) endInventory;
        return new State(IniState.getPeriod() + 1, endInventory);
    };
    double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmf();
    /**
     *****************************************************************
     * Solve
     */
    RecursionG recursion = new RecursionG(pmf, buildActionList, stateTransition, immediateValue);
    int period = 1;
    State iniState = new State(period, iniInventory[d - 1]);
    long currTime = System.currentTimeMillis();
    double finalValue = iniCash + recursion.getExpectedValue(iniState);
    System.out.println("final optimal cash  is " + finalValue);
    System.out.println("optimal order quantity in the first priod is :  Q = " + recursion.getAction(iniState));
    double time = (System.currentTimeMillis() - currTime) / 1000;
    System.out.println("running time is " + time + "s");
    System.out.println("a* in each period:");
    double[] optY = recursion.getOptY();
    optY[0] = iniState.getIniInventory() + recursion.getAction(iniState);
    System.out.println(Arrays.toString(optY));
}
Also used : ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) Arrays(java.util.Arrays) GammaDist(umontreal.ssj.probdist.GammaDist) 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) OptDirection(sdp.inventory.Recursion.OptDirection) RecursionG(sdp.cash.multiItem.RecursionG) State(sdp.inventory.State) Recursion(sdp.inventory.Recursion) BiNormalDist(umontreal.ssj.probdistmulti.BiNormalDist) WriteToExcel(sdp.write.WriteToExcel) RecursionG(sdp.cash.multiItem.RecursionG) GammaDist(umontreal.ssj.probdist.GammaDist) State(sdp.inventory.State) GetPmf(sdp.inventory.GetPmf)

Example 4 with GetPmf

use of sdp.inventory.GetPmf in project Stochastic-Inventory by RobinChen121.

the class MultiItemCashLookPolicy method main.

public static void main(String[] args) {
    double[] price = { 10, 5 };
    // higher margin vs lower margin
    double[] variCost = { 4, 2 };
    // initial cash
    double iniCash = 25;
    // initial inventory
    int iniInventory1 = 0;
    int iniInventory2 = 0;
    // higher average demand vs lower average demand
    double[][] demand = { { 6, 6 }, { 8, 8 } };
    // higher variance vs lower variance
    double[] coe = { 0.5, 0.25 };
    double[] salPrice = { 2, 1 };
    // horizon length
    int T = demand[0].length;
    double truncationQuantile = 0.999;
    int stepSize = 1;
    double minCashState = 0;
    double maxCashState = 10000;
    int minInventoryState = 0;
    int maxInventoryState = 200;
    int Qbound = 100;
    double discountFactor = 1;
    double Rmin = 25;
    double Rmax = 80;
    int incre = 2;
    int rowNum = (int) ((Rmax - Rmin) / incre) + 2;
    int row = 0;
    double[][] optResults = new double[rowNum][5];
    for (iniCash = Rmin; iniCash <= Rmax; iniCash = iniCash + incre) {
        // get demand possibilities for each period
        Distribution[][] distributions = new Distribution[demand.length][T];
        for (int t = 0; t < T; t++) {
            for (int i = 0; i < demand.length; i++) {
                distributions[t][i] = new PoissonDist(demand[i][t]);
            }
        }
        double[][][] pmf = new GetPmf(distributions, truncationQuantile, stepSize).getpmfMulti();
        // build action list for two items
        Function<CashStateMulti, ArrayList<Actions>> buildActionList = s -> {
            ArrayList<Actions> actions = new ArrayList<>();
            for (int i = 0; i < Qbound; i++) for (int j = 0; j < Qbound; j++) {
                if (variCost[0] * i + variCost[1] * j < s.getIniCash() + 0.1) {
                    Actions thisAction = new Actions(i, j);
                    actions.add(thisAction);
                }
            }
            return actions;
        };
        // Immediate Value Function
        ImmediateValueFunction<CashStateMulti, Actions, Demands, Double> immediateValue = (IniState, Actions, RandomDemands) -> {
            double action1 = Actions.getFirstAction();
            double action2 = Actions.getSecondAction();
            double demand1 = RandomDemands.getFirstDemand();
            double demand2 = RandomDemands.getSecondDemand();
            double endInventory1 = Math.max(0, IniState.getIniInventory1() + action1 - demand1);
            double endInventory2 = Math.max(0, IniState.getIniInventory2() + action2 - demand2);
            double revenue = price[0] * (IniState.getIniInventory1() + action1 - endInventory1) + price[1] * (IniState.getIniInventory2() + action2 - endInventory2);
            double orderingCosts = variCost[0] * action1 + variCost[1] * action2;
            double salValue = 0;
            if (IniState.getPeriod() == T - 1) {
                salValue = salPrice[0] * endInventory1 + salPrice[1] * endInventory2;
            }
            return revenue - orderingCosts + salValue;
        };
        // State Transition Function
        StateTransitionFunction<CashStateMulti, Actions, Demands, CashStateMulti> stateTransition = (IniState, Actions, RandomDemands) -> {
            double endInventory1 = IniState.getIniInventory1() + Actions.getFirstAction() - RandomDemands.getFirstDemand();
            endInventory1 = Math.max(0, endInventory1);
            double endInventory2 = IniState.getIniInventory2() + Actions.getSecondAction() - RandomDemands.getSecondDemand();
            endInventory2 = Math.max(0, endInventory2);
            double nextCash = IniState.getIniCash() + immediateValue.apply(IniState, Actions, RandomDemands);
            nextCash = nextCash > maxCashState ? maxCashState : nextCash;
            nextCash = nextCash < minCashState ? minCashState : nextCash;
            endInventory1 = endInventory1 > maxInventoryState ? maxInventoryState : endInventory1;
            endInventory2 = endInventory2 < minInventoryState ? minInventoryState : endInventory2;
            // rounding states to save computing time
            nextCash = (int) nextCash;
            endInventory1 = (int) endInventory1;
            endInventory2 = (int) endInventory2;
            return new CashStateMulti(IniState.getPeriod() + 1, endInventory1, endInventory2, nextCash);
        };
        /**
         *****************************************************************
         * Solve
         */
        CashRecursionMulti recursion = new CashRecursionMulti(discountFactor, pmf, buildActionList, stateTransition, immediateValue, T);
        int period = 1;
        CashStateMulti iniState = new CashStateMulti(period, iniInventory1, iniInventory2, iniCash);
        long currTime = System.currentTimeMillis();
        double finalValue = iniCash + recursion.getExpectedValueMulti(iniState);
        System.out.println("final optimal cash  is " + finalValue);
        System.out.println("optimal order quantity in the first priod is :  Q1 = " + recursion.getAction(iniState).getFirstAction() + ", Q2 = " + recursion.getAction(iniState).getSecondAction());
        double time = (System.currentTimeMillis() - currTime) / 1000;
        System.out.println("running time is " + time + "s");
        /**
         *****************************************************************
         * Simulating sdp results
         *
         * simulating results a little lower than SDP
         */
        int sampleNum = 10000;
        CashSimulationMulti simuation = new CashSimulationMulti(sampleNum, distributions, discountFactor, recursion, stateTransition, immediateValue);
        double simFinalValue = simuation.simulateSDPGivenSamplNumMulti(iniState);
        System.out.println(simFinalValue);
        /**
         *****************************************************************
         * try to find some ordering patters from optTable
         *
         * output results to excel
         */
        double Q1 = recursion.getAction(iniState).getFirstAction();
        double Q2 = recursion.getAction(iniState).getSecondAction();
        System.out.println("");
        optResults[row][0] = iniInventory1;
        optResults[row][1] = iniInventory2;
        optResults[row][2] = iniCash;
        optResults[row][3] = Q1;
        optResults[row][4] = Q2;
        row++;
    }
    System.out.println("**************************************************");
    WriteToExcel wr = new WriteToExcel();
    String fileName = "optTable2.xls";
    String headString = "x1" + "\t" + "x2" + "\t" + "R" + "\t" + "Q1" + "\t" + "Q2";
    wr.writeArrayToExcel(optResults, fileName, headString);
}
Also used : ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) Demands(sdp.cash.multiItem.Demands) CashRecursionMulti(sdp.cash.multiItem.CashRecursionMulti) Actions(sdp.cash.multiItem.Actions) Function(java.util.function.Function) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) ArrayList(java.util.ArrayList) GetPmf(sdp.inventory.GetPmf) GetPmfMulti(sdp.cash.multiItem.GetPmfMulti) BiNormalDist(umontreal.ssj.probdistmulti.BiNormalDist) WriteToExcel(sdp.write.WriteToExcel) CashSimulationMulti(sdp.cash.multiItem.CashSimulationMulti) CashStateMulti(sdp.cash.multiItem.CashStateMulti) PoissonDist(umontreal.ssj.probdist.PoissonDist) Distribution(umontreal.ssj.probdist.Distribution) PoissonDist(umontreal.ssj.probdist.PoissonDist) Actions(sdp.cash.multiItem.Actions) Demands(sdp.cash.multiItem.Demands) ArrayList(java.util.ArrayList) CashStateMulti(sdp.cash.multiItem.CashStateMulti) CashSimulationMulti(sdp.cash.multiItem.CashSimulationMulti) WriteToExcel(sdp.write.WriteToExcel) Distribution(umontreal.ssj.probdist.Distribution) GetPmf(sdp.inventory.GetPmf) CashRecursionMulti(sdp.cash.multiItem.CashRecursionMulti)

Example 5 with GetPmf

use of sdp.inventory.GetPmf 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)

Aggregations

GetPmf (sdp.inventory.GetPmf)33 Function (java.util.function.Function)31 StateTransitionFunction (sdp.inventory.StateTransition.StateTransitionFunction)30 PoissonDist (umontreal.ssj.probdist.PoissonDist)30 Distribution (umontreal.ssj.probdist.Distribution)28 ImmediateValueFunction (sdp.inventory.ImmediateValue.ImmediateValueFunction)27 IntStream (java.util.stream.IntStream)21 CashState (sdp.cash.CashState)18 Arrays (java.util.Arrays)16 DoubleStream (java.util.stream.DoubleStream)16 CashRecursion (sdp.cash.CashRecursion)16 OptDirection (sdp.cash.CashRecursion.OptDirection)13 State (sdp.inventory.State)13 CashSimulation (sdp.cash.CashSimulation)12 NormalDist (umontreal.ssj.probdist.NormalDist)12 ArrayList (java.util.ArrayList)11 WriteToExcel (sdp.write.WriteToExcel)10 FindCCrieria (cash.strongconstraint.FindsCS.FindCCrieria)9 DecimalFormat (java.text.DecimalFormat)8 WriteToCsv (sdp.write.WriteToCsv)8