package inventory; /** * Created on 09.04.2022 15:19:33 * * @author Alexander Mikhailovich Kovshov */ public class InventoryModel1 { public static void main(String[] args) { int n = 8; //число промежутков времени (месяцев) int max = 10; //наибольшее значение для остатка на складе double[] inprice = { 1, 1, 1, 2, 7, 10, 8, 6};//цены закупочные за каждый месяц double[] outprice = {15, 10, 9, 10, 20, 30, 20, 10};//цены отпускные за каждый месяц double[] store = { 1, 0, 0, 0, 1, 1, 1, 1};//стоимость хранения единицы товара за каждый месяц int[] need = { 2, 6, 8, 6, 2, 2, 2, 2};//потребность за каждый месяц double[] profit = new double[max + 1]; //Наибольшая прибыль за все последующие месяцы в зависимости от остатка на конец текущего месяца. double[] profitTemp = new double[max + 1]; //Прибыль за текущий месяц и все последующие за ним месяцы в зависимости от остатка на начало месяца. int[][] restFromProfit = new int[n][max + 1];//Наилучший остаток на конец каждого месяца в зависимости от остатка на начало каждого месяца. //Вычисление возможной прибыли за конечный (n-й) месяц в зависимости от остатка на складе. //r --- возможный остаток на складе от предыдущего месяца for (int r = 0; r <= max; r++) { int add_r = need[n - 1] - r; //Приобретение за конечный (n-й) месяц. if (add_r < 0) { profit[r] = Integer.MIN_VALUE; continue; } profit[r] = outprice[n - 1] * need[n - 1] - inprice[n - 1] * add_r - store[n - 1] * ((double) r / 2); } for (int m = n - 1; m > 0; m--) { //Вычисление возможной прибыли за m-й месяц в зависимости от остатка на складе. //r --- возможный остаток на складе на начало месяца. //rr --- возможный остаток на складе на конец месяца. for (int r = 0; r <= max; r++) { for (int rr = 0; rr <= max; rr++) { //Вычисление прибыли за m-й и последующие месяцы в зависимости от остатка на конец месяца. //Приобретение за m-й месяц. int add_r = need[m - 1] + rr - r; if (add_r < 0) { profitTemp[r] = Integer.MIN_VALUE; //Отрицательное приобретение невозможно. } else { //Прибыль за этот и последующие месяцы в зависимости от остатков //на начало и конец этого месяца (r и rr). double H = outprice[m - 1] * need[m - 1] - inprice[m - 1] * add_r - store[m - 1] * ((double) (r + rr) / 2) + profit[rr]; //Если прибыль для данного остатка rr на конец месяца оказалась самой большой //среди прибылей для других остатков на конец месяца при данном остатке r на //начало месяца, то эта пока наибольшая прибыль сохраняется. if (H > profitTemp[r]) { profitTemp[r] = H; restFromProfit[m - 1][r] = rr; //Сохраняется и пока наилучший остаток rr. } } } } //Значение наилучшей прибыли теперь будет включать и прибыль за текущий месяц m. for (int i = 0; i < profit.length; i++) { profit[i] = profitTemp[i]; } } System.out.println("=========== План закупок ==============="); for (int m = 0, r = 0; m < n; m++) { System.out.println((m + 1) + "; Остаток на начало: " + r + "; Остаток на конец: " + restFromProfit[m][r] + "; Потребление: " + need[m] + "; Закупки: " + (need[m] - r + restFromProfit[m][r]) ); r = restFromProfit[m][r]; } System.out.println("Прибыль " + profit[0]); } }