package inventory;

import java.text.DecimalFormat;

/**
 * Алгоритм, моделирующий торговлю сохраняемым товаром.
 * 
 * Created on 2022-03-18 14:56:09.
 * @author Alexander Mikhailovich Kovshov
 */
public class RandomDemandStore {
public static void main(String[] args) {
        System.out.println("Модель торговли сохраняемым товаром со случайным спросом");
        double x;            // дневной запас товара
        double p = 30;      // отпускная цена
        double q = 28;      // закупочная цена
        double r = 30;      // затраты на хранение ночью
        double a = 2;        // наименьшай спрос
        double b = 10;       // наибольший спрос
        int n = 10000000;    // число испытаний в численном опыте
        System.out.println("p=" + p + ",  q=" + q + ",  r=" + r + ",  a=" + a + ",  b=" + b + ",  n=" + n + ";");
        for (x = -a; x <= b+a; x += 1) {           //Повторения для разного размера дневного запаса. 
            process(x, p, q, r, a, b, n);       //Статистческое вычисление среднедневной прибыли.
        } 
        x = b - r / (p - q);                   //Формулв для наилучшего дневного запаса.
        if (x < a || x > b) {
            System.out.println("по формуле для наилучшего заказа x = " + x + " за пределами спроса");
            x = x < a ? a : x > b ? b : x;
        }
        System.out.println("максимум при х: " + x);
        process(x, p, q, r, a, b, n);
    }


    /**
     * Симуляция торговли со случайным спросом несохраняемого товара.
     * @param xдневной заказ.
     * @param pотпускная цена
     * @param qзакупочная цена
     * @param rзатраты на хранение ночью
     * @param aнаименьшай спрос
     * @param bнаибольший спрос
     * @param n - число испытаний в численном опыте.
     */
    public static void process(double x, double p, double q, double r, double a, double b, int n) {
        double profit = 0;                             //Прибыль. Начальное значение нулевое.
        double z = 0;                                  //Дневной остаток. Начальное значение нулевое.
        for (int i = 0; i < n; i++) {                  //Многократное повторение торговых дней.
            double y = Math.random() * (b - a);        //Равномерный случайный спрос заданного разброса.
            y += a;                                    //Смещение значения спроса к левой границе.
            profit += -q * (x - z);                    //Вычет из прибыли затрат на закупку пополнения дневного запаса.
            if (y < x) {                               //Если спрос оказался меньше заказа,
                profit += p * y;                       //то прибыль увеличивается на выручку от удовлетворения спроса,
                z = x - y;                             //вычисляется сохраняемый остаток товара,
                profit -= r;                           //и из прибыли вычитаются затраты на хранение.
            } else {                                   //Если спрос меньше заказа,
                profit += p * x;                       //то прибыль увеличивается на выручку от проданного запаса без остатка.
                z = 0;
            }
        }
        profit /= n;
        
        double h; 
        if (x < a)
            h = x * (p - q);
        else if (x > b)
            h = (p - q) * (a + b) / 2 - r;
        else
            h = -q * (x - (x - a) / 2 * (x - a) / (b - a)) 
                    + (p * (a + x) / 2 - r) * (x - a) / (b - a)
                    + p * x * (b - x) / (b - a);
        DecimalFormat ds = new DecimalFormat(" 00.0;-00.0"), dl = new DecimalFormat(" 00.000000;-00.000000");
        System.out.println("x: " + ds.format(x) + ";  среднедневная прибыль: " 
                + dl.format(profit) + ";  по формуле: " + dl.format(h));
        
    }
}

/*
run:
Модель торговли сохраняемым товаром со случайным спросом
p=30.0,  q=28.0,  r=30.0,  a=2.0,  b=10.0,  n=10000000;
x: -02,0;  среднедневная прибыль: -04,000000;  по формуле: -04,000000
x: -01,0;  среднедневная прибыль: -02,000000;  по формуле: -02,000000
x:  00,0;  среднедневная прибыль:  00,000000;  по формуле:  00,000000
x:  01,0;  среднедневная прибыль:  02,000000;  по формуле:  02,000000
x:  02,0;  среднедневная прибыль:  04,000000;  по формуле:  04,000000
x:  03,0;  среднедневная прибыль:  02,120309;  по формуле:  02,125000
x:  04,0;  среднедневная прибыль:  00,000372;  по формуле:  00,000000
x:  05,0;  среднедневная прибыль: -02,373206;  по формуле: -02,375000
x:  06,0;  среднедневная прибыль: -04,998868;  по формуле: -05,000000
x:  07,0;  среднедневная прибыль: -07,880200;  по формуле: -07,875000
x:  08,0;  среднедневная прибыль: -10,994108;  по формуле: -11,000000
x:  09,0;  среднедневная прибыль: -14,376294;  по формуле: -14,375000
x:  10,0;  среднедневная прибыль: -17,998518;  по формуле: -18,000000
x:  11,0;  среднедневная прибыль: -17,997816;  по формуле: -18,000000
x:  12,0;  среднедневная прибыль: -18,001355;  по формуле: -18,000000
по формуле для наилучшего заказа x = -5.0 за пределами спроса
максимум при х: 2.0
x:  02,0;  среднедневная прибыль:  04,000000;  по формуле:  04,000000
BUILD SUCCESSFUL (total time: 4 seconds)

*/