Search in sources :

Example 1 with BiNormalDist

use of umontreal.ssj.probdistmulti.BiNormalDist in project Stochastic-Inventory by RobinChen121.

the class Sampling method generateLHSamples.

/**
 * latin hypercube sampling for binormal distribution.
 *
 * Since two independent variable, generate two variable independently, and merge the two samples into one
 * @param distributions
 * @param sampleNum
 * @return a 2D random samples
 */
public double[][] generateLHSamples(BiNormalDist[] distributions, int sampleNum) {
    int periodNum = distributions.length;
    double[][] samples = new double[sampleNum][periodNum * 2];
    double[][] samples1 = new double[sampleNum][periodNum];
    double[][] samples2 = new double[sampleNum][periodNum];
    // generate random possibility in [i/n, (i+1)/n], then get percent point function according to the possibility
    for (int i = 0; i < periodNum; i++) {
        NormalDist distribution1 = new NormalDist(distributions[i].getMu1(), distributions[i].getSigma1());
        for (int j = 0; j < sampleNum; j++) {
            // UniformGen.nextDouble(stream, 0, 1.0/sampleNum);
            double randomNum = Math.random() / (double) sampleNum;
            double lowBound = (double) j / (double) sampleNum;
            samples1[j][i] = lowBound + randomNum;
            samples1[j][i] = distribution1.inverseF(samples1[j][i]);
        }
        // ��������
        shuffle(samples1);
    }
    for (int i = 0; i < periodNum; i++) {
        NormalDist distribution2 = new NormalDist(distributions[i].getMu2(), distributions[i].getSigma2());
        for (int j = 0; j < sampleNum; j++) {
            // UniformGen.nextDouble(stream, 0, 1.0/sampleNum);
            double randomNum = Math.random() / (double) sampleNum;
            double lowBound = (double) j / (double) sampleNum;
            samples2[j][i] = lowBound + randomNum;
            samples2[j][i] = distribution2.inverseF(samples2[j][i]);
        }
        // ��������
        shuffle(samples2);
    }
    for (int i = 0; i < sampleNum; i++) {
        for (int j = 0; j < periodNum; j++) {
            samples[i][j] = samples1[i][j];
            samples[i][j + periodNum] = samples2[i][j];
        }
    }
    return samples;
}
Also used : NormalDist(umontreal.ssj.probdist.NormalDist) BiNormalDist(umontreal.ssj.probdistmulti.BiNormalDist)

Example 2 with BiNormalDist

use of umontreal.ssj.probdistmulti.BiNormalDist in project Stochastic-Inventory by RobinChen121.

the class MultiItemCash method main.

public static void main(String[] args) {
    double[] price = { 4, 50 };
    // higher margin vs lower margin
    double[] variCost = { 2, 4 };
    // initial cash
    double iniCash = 100;
    // initial inventory
    int iniInventory1 = 0;
    int iniInventory2 = 0;
    // higher average demand vs lower average demand
    double[][] demand = { { 5, 6 }, { 5, 6 } };
    // higher variance vs lower variance
    double[] coe = { 0.25, 0.25 };
    double[] salPrice = { 1, 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;
    // get demand possibilities for each period
    BiNormalDist[] distributions = new BiNormalDist[T];
    for (int t = 0; t < T; t++) distributions[t] = new BiNormalDist(demand[0][t], coe[0] * demand[0][t], demand[1][t], coe[1] * demand[1][t], 0);
    // 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 revenue1 = price[0] * (IniState.getIniInventory1() + action1 - endInventory1);
        double revenue2 = price[1] * (IniState.getIniInventory2() + action2 - endInventory2);
        double revenue = revenue1 + revenue2;
        double orderingCost1 = variCost[0] * action1;
        double orderingCost2 = variCost[1] * action2;
        double orderingCosts = orderingCost1 + orderingCost2;
        double salValue = 0;
        if (IniState.getPeriod() == T) {
            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);
    };
// GetPmfMulti pmfMulti = new GetPmfMulti(distributions, truncationQuantile, stepSize);
// 
// /*******************************************************************
// * Solve
// */
// CashRecursionMulti recursion = new CashRecursionMulti(discountFactor, pmfMulti, buildActionList,
// stateTransition, immediateValue, T);
// int period = 1;
// CashStateMulti iniState = new CashStateMulti(period, iniInventory1, iniInventory2, iniCash);
// 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 :  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.simulateSDPGivenSamplNum(iniState);
// System.out.println(simFinalValue);
/**
 *****************************************************************
 * try to find some ordering patters from optTable
 *
 * output results to excel
 */
// System.out.println("");
// double[][] optTable = recursion.getOptTable(variCost);
// WriteToExcel wr = new WriteToExcel();
// String fileName = "optTable" + "_c1=" + variCost[0] + "c2=" + variCost[1] + ".xls";
// String headString =  "period" + "\t" + "x1" + "\t" + "x2" + "\t" + "w"+ "\t" + "R" + "\t" + "is limited cash and both ordering" + "\t" + "alpha"
// + "\t" + "Q1"+ "\t" + "Q2" + "\t" + "c1" + "\t" + "c2";
// wr.writeArrayToExcel(optTable, fileName, headString);
// 
}
Also used : ImmediateValueFunction(sdp.inventory.ImmediateValue.ImmediateValueFunction) Demands(sdp.cash.multiItem.Demands) CashRecursionMulti(sdp.cash.multiItem.CashRecursionMulti) GetPmfMulti(sdp.cash.multiItem.GetPmfMulti) Actions(sdp.cash.multiItem.Actions) BiNormalDist(umontreal.ssj.probdistmulti.BiNormalDist) WriteToExcel(sdp.write.WriteToExcel) Function(java.util.function.Function) CashSimulationMulti(sdp.cash.multiItem.CashSimulationMulti) CashStateMulti(sdp.cash.multiItem.CashStateMulti) StateTransitionFunction(sdp.inventory.StateTransition.StateTransitionFunction) ArrayList(java.util.ArrayList) Actions(sdp.cash.multiItem.Actions) Demands(sdp.cash.multiItem.Demands) ArrayList(java.util.ArrayList) CashStateMulti(sdp.cash.multiItem.CashStateMulti) BiNormalDist(umontreal.ssj.probdistmulti.BiNormalDist)

Aggregations

BiNormalDist (umontreal.ssj.probdistmulti.BiNormalDist)2 ArrayList (java.util.ArrayList)1 Function (java.util.function.Function)1 Actions (sdp.cash.multiItem.Actions)1 CashRecursionMulti (sdp.cash.multiItem.CashRecursionMulti)1 CashSimulationMulti (sdp.cash.multiItem.CashSimulationMulti)1 CashStateMulti (sdp.cash.multiItem.CashStateMulti)1 Demands (sdp.cash.multiItem.Demands)1 GetPmfMulti (sdp.cash.multiItem.GetPmfMulti)1 ImmediateValueFunction (sdp.inventory.ImmediateValue.ImmediateValueFunction)1 StateTransitionFunction (sdp.inventory.StateTransition.StateTransitionFunction)1 WriteToExcel (sdp.write.WriteToExcel)1 NormalDist (umontreal.ssj.probdist.NormalDist)1