Algorithms for ‘Selling to the Newsvendor: An analysis of Price-only Contracts’
I developed the algorithms during my PhD study to deepen my understanding of both MATLAB and Newsvendor model. I found it was quite useful. Here I also put the algorithms for your reference. It would be appreciated if you can send your comments when spotting any errors.
Analysis 1
clc;
syms y a b c r
% specify variables
unifcdf = @unifCDF;
% call the Uniform Cumulative Distribution Function (CDF)
optiFun_y = (1 - unifcdf(y, a, b)) * (1 - y * diff(unifcdf(y, a, b),y) / (1 - unifcdf(y, a, b))) - c/r
% the equation used to calcualte optimal order quantity
%%
clc;
syms y
A = [100, 100, 180];
B = [500, 600, 500];
% parameters regarding different market sizes
M = zeros(3, 4);
% create an empty matrix to store parameters and results
for i = 1 : 3
x = [4, 10, A(i), B(i)];
c = x(1);
r = x(2);
a = x(3);
b = x(4);
opti_unif_y = solve(((a - y)/(a - b) - 1)*(y/(((a - y)/(a - b) - 1)*(a - b)) - 1) - c/r);
% calculate the optimal order quantity
% the equation in the solve function is produced by 'optiFun_y' in the
% last section
opti_unif_w = double(r * (1 - unifcdf(opti_unif_y, a, b)));
% calculate the optimal wholesale price
M(i, 1 : 4) = [a, b, opti_unif_y, opti_unif_w];
% grap the data to the empty matrix
end
M
% show the matrix with stored values
%%
%################### functions for numerical analysis 1 ##################%
%=================== set up the function of the uniform CDF ==============%
function uniCdf = unifCDF(x, a, b)
uniCdf = (x -a) / (b - a);
end
end
Analysis 2
clc;
syms y k theta
% specify variables
assume(k > 0 & theta >0)
% set assumption on symbolic object
c = 4;
r = 10;
% assign certain parameters values
powcdf = @powCDF;
% call the Power Cumulative Distribution Function (CDF)
%=== calculate the optimial order in the decentralised supply chain (DSC) ====%
optiPowFun_y_dsc = (1 - powcdf(y, theta, k)) * (1 - y * ...
diff(powcdf(y, theta, k),y) / (1 - powcdf(y, theta, k))) - c/r
% this function is for calculating the optimal quantity in the DSC
optiQuan_ds = solve(optiPowFun_y_dsc, y)
% the optimal quantity for DSC
%===== calculate the optimial order in the integrated supply chain (ISC) ====%
optiPowFun_y_isc = powcdf(y, theta, k) - 1 + c/r;
% the function for calculating the optimal quantity in ISC
optiQuan_isc = solve(optiPowFun_y_isc, y)
% the optimal quantity for ISC
%=============== define coefficient of variation (CV) ===================%
syms y
% specify the variable
expect_x = int(y * diff(powcdf(y, theta, k), y), 0, 1);
% calculate expected value
sd_x = sqrt(int(y^2 * diff(powcdf(y, theta, k), y), 0, 1) - expect_x^2);
% calculate standard deviation
cvFun = sd_x / expect_x
% calculate CV
%%
clc;
syms y
powcdf = @powCDF;
% call the Power CDF
K = linspace(0.2, 8, 30);
% generate linearly spaced vector for k
for i = 1 : 30
c = 4;
r = 10;
theta = 1;
k = K(i)
% assign certain parameters values
cv(i) = -(1 - (1/(k + 1) - 1)^2 - 2/(k + 2))^(1/2)/(1/(k + 1) - 1);
% coefficient of variation (CV)
optimal_y = double(theta*(3/(5*(k + 1)))^(1/k));
% the optimal order quantity
prop_dm = double(((1 - powcdf(optimal_y, theta, k)) - c/r) * optimal_y);
% the numerator of the ratio (the manufacturer's profit)
prop_dsc = double(optimal_y * (1 - powcdf(optimal_y, theta, k)) +...
int(y * diff(powcdf(y, theta, k), y), 0, optimal_y) - c/r * optimal_y);
% the denominator of the ratio (the DSC's profit)
prop_dm_dsc(i) = double(prop_dm / prop_dsc)
% the ratio of the manufacturer's to DSC's profit
optiQuan_is(i) = (3/5)^(1/k)*theta;
% the optimal quanity of ISC
prop_isc = - c/r * optiQuan_is(i) + optiQuan_is(i) -...
int(powcdf(y, theta, k), 0, optiQuan_is(i));
% denominator of the ratio (ISC's profit)
prop_dsc_isc(i) = double(prop_dsc/prop_isc)
% the ratio of the decentralised to ISC profit
end
%%
plot(K, prop_dm_dsc * 100, 'k-.')
% plot the ratio of the manufacturer's to DSC's profit
ytickformat('percentage')
% specify y-axis tick label format
hold on;
% retains the current plot and certain axes properties
% so that subsequent graphing commands add to the existing graph.
[hAx, hLine1, hLine2] = plotyy(K, prop_dsc_isc * 100, K, cv)
% plot the ratio of the decentralized to integrated supply chain profit
% plot the relationship between K and cv
title('Supply-Chain Performance Under Power Function Demand')
xlabel('k')
ylabel(hAx(2), 'Coefficient of Variation') % right y-axis
% add the title and name the x and y axis
set(hLine1, 'Color', 'k', 'LineStyle', '-');
set(hLine2, 'Color', 'k', 'LineStyle', '-', 'Marker','X');
% set the color, style and marker of the line
set(hAx, 'XTick', 0: 2 : 8, {'YTick'}, {0: 10 :100; 0 : 0.25 : 2}, {'ycolor'},{'k';'k'})
% customising the tick values
legend('\Pi_M/\Pi_D', '\Pi_D/\Pi_I','CV','Location','east')
% add legend
box off;
% removes the box outline around the current axes
hold off;
%%
%#################### functions for numercial analysis 2 #################%
%=================== CDF of the power distribution =======================%
function pwercdf = powCDF(y, theta, k)
pwercdf = (y / theta)^k;
end
Analysis 3
%##################### numerical analysis 3 ##############################%
clc;
syms y k
% specify variables
M_num1 = zeros(4, 8);
% create an empty matrix to store parameters and results
for j = 1 : 4
K = [0.20, 0.25, 0.50, 1.00, 2.00, 4.00, 9.00, 16.00];
C = [2, 4, 6, 8];
c = C(1);
r = 10;
theta = 1.2;
k = K(j)
% assign certain parameters values
gamapdf = @gamaPDF;
% call the Gamma Cumulative Distribution Function (CDF)
expect_gam_x = int(y * gamapdf(y, theta, k), y, 0, +inf);
sd_gam_x = sqrt(int(y^2 * gamapdf(y, theta, k), y, 0, +inf) - expect_gam_x^2);
cv_gam = double(sd_gam_x / expect_gam_x);
% define coefficient of variation (CV)
%========= calculate the optimial order in the decentralized supply chain (DSC) ====%
optiGamFun_y_dsc = (1 - int(gamapdf(y, theta, k),0 , y)) * (1 - y *...
gamapdf(y, theta, k) / (1 - int(gamapdf(y, theta, k),0 , y))) - c/r;
% the function for calculating the optimal quantity of DSC
optiQuan_ds_gama = double(vpasolve(optiGamFun_y_dsc, y));
% the optimal quanity for DSC
opti_w_gama = r * (1 - int(gamapdf(y, theta, k),0, optiQuan_ds_gama));
% the optimal wholesale price
ratio_w_r = double(1 - int(gamapdf(y, theta, k),0, optiQuan_ds_gama));
% the tatio of wholesale price to retail price
%========= calculate optimial order in the integrated supply chain =======%
optiGamaFun_y_isc = int(gamapdf(y, theta, k),0, y) + c/r - 1;
% the function used to calculate the optimal quantity of integrated
% supply chain (ISC)
optiQuan_isc_gama = double(vpasolve(optiGamaFun_y_isc, y));
% the optimal quanity for ISC
ratio_ydsc_yisc = optiQuan_ds_gama / optiQuan_isc_gama;
% the ratio of DSC to ISC order quantity
prop_dsc_profit = (1 - int(gamapdf(y, theta, k),0, optiQuan_ds_gama)) *...
optiQuan_ds_gama + int(y * gamapdf(y, theta, k), 0, optiQuan_ds_gama)...
- c/r * optiQuan_ds_gama;
% the numerator of the ratio (the DSC's profit)
prop_isc_profit = - c/r * optiQuan_isc_gama + optiQuan_isc_gama -...
int(int(gamapdf(y, theta, k),0, y), 0, optiQuan_isc_gama);
% the denominator of the ratio (the ISC's profit)
ratio_dsc_isc_profit = double(prop_dsc_profit / prop_isc_profit);
% the ratio of DSC to the ISC profit
prop_m_profit = (1 - int(gamapdf(y, theta, k),0, optiQuan_ds_gama) - c/r) * optiQuan_ds_gama;
ratio_m_dsc_profit = double(prop_m_profit / prop_dsc_profit);
% the ratio of manufactuer to DSC profit
ratio_m_isc_profit = double(prop_m_profit / prop_isc_profit);
% the ratio of manufactuer to ISC profit
M_num1(j, 1:8) = [c/r, k, cv_gam, ratio_ydsc_yisc * 100,...
ratio_w_r, ratio_dsc_isc_profit*100, ratio_m_dsc_profit*100,...
ratio_m_isc_profit*100]
% grap the data to the empty matrix
end
M_num1
% show the matrix with stored values
%%
%#################### functions for numercial analysis 3 #################%
%============================== define Gamma CDF =========================%
function gamapdf = gamaPDF(y, theta, k)
gamapdf = theta^(-k) * y^(k -1) * exp(-y/theta)/gamma(k);
end
Analysis 4
clc;
syms y k
% specify variables
assume(k > 0)
% set assumption on symbolic object
c = 4;
r = 10;
theta = 1;
% assign certain parameters values
powcdf = @powCDF;
% call the Power Cumulative Distribution Function (CDF)
%=== calculate the optimial order in the decentralised supply chain (DSC) ====%
optiPowFun_y_dsc = (1 - powcdf(y, theta, k)) * (1 - y * ...
diff(powcdf(y, theta, k),y) / (1 - powcdf(y, theta, k))) - c/r;
% this function is for calculating the optimal quantity in the DSC
optiQuan_ds = solve(optiPowFun_y_dsc, y)
% the optimal quantity for DSC
%===== calculate the optimial order in the integrated supply chain (ISC) ====%
optiPowFun_y_isc = powcdf(y, theta, k) - 1 + c/r;
% the function for calculating the optimal quantity in ISC
optiQuan_isc = solve(optiPowFun_y_isc, y)
% the optimal quantity for ISC
%=============== define coefficient of variation (CV) ===================%
syms y
% specify the variable
expect_x = int(y * diff(powcdf(y, theta, k), y), 0, 1);
% calculate expected value
sd_x = sqrt(int(y^2 * diff(powcdf(y, theta, k), y), 0, 1) - expect_x^2);
% calculate standard deviation
cvFun = sd_x / expect_x
% calculate CV
%%
clc;
syms y
assume(y>0)
powcdf = @powCDF;
% call the Power CDF
M_num3 = zeros(32, 7)
% create an empty matrix to store parameters and results
for j = 1 : 4
BETA = [0.3, 0.4, 0.5, 0.6];
for i = 1 : 8
K = [0.1, 0.25, 0.414, 0.75, 1.00, 1.5, 2.00, 3.00];
c = 4;
r = 10;
theta = 1;
k = K(i)
% assign certain parameters values
cv = -(1 - (1/(k + 1) - 1)^2 - 2/(k + 2))^(1/2)/(1/(k + 1) - 1);
% coefficient of variation (CV)
optimal_y = double(solve(- ((k*y*y^(k - 1))/(y^k - 1) + 1)*(y^k - 1) - 2/5, y));
% the optimal order quantity
prop_dm =((1 - powcdf(optimal_y, theta, k)) - c/r) * optimal_y;
% the numerator of the ratio (the manufacturer's profit)
prop_dsc = optimal_y * (1 - powcdf(optimal_y, theta, k)) +...
int(y * diff(powcdf(y, theta, k), y), 0, optimal_y) - c/r * optimal_y;
% the denominator of the ratio (the DSC's profit)
prop_dm_dsc = prop_dm / prop_dsc;
% the ratio of the manufacturer's to DSC's profit
optiQuan_is = (3/5)^(1/k);
% the optimal quanity of IDS
prop_isc = - c/r * optiQuan_is + optiQuan_is - int(powcdf(y, theta, k), 0, optiQuan_is);
% denominator of the ratio (ISC's profit)
prop_dsc_isc = prop_dsc/prop_isc;
% the ratio of the DSC to ISC profit
%========== optimal strategy considering the retailer's power=====%
optiQuanBe = @optiQuanBeta;
beta = BETA(j)
% assign certain parameters values
optiQuan_beta = optiQuanBe(c, r, beta, k);
% the optimal order quanity considering the retailer's power
optiQuan_beta_SC = optiQuan_beta / optimal_y;
% ratio of beta SC to integrated SC quantity
prop_dsc_beta = optiQuan_beta * (1 - powcdf(optiQuan_beta, theta, k)) +...
int(y * diff(powcdf(y, theta, k), y), 0, optiQuan_beta) - c/r * optiQuan_beta;
% denominator of the ratio (beta SC's profit)
ratio_betaSC_isc = double(prop_dsc_beta / prop_isc);
% ratio of beta SC to ISC profit
ratio_betaSC_dsc = double(prop_dsc_beta/prop_dsc);
% ratio of beta SC to DSC profit
prop_beta_m = ((1 - powcdf(optiQuan_beta, theta, k)) - c/r) * optiQuan_beta;
% the numerator of the ratio (the manufacturer's profit)
ratio_betaM_DscM = prop_beta_m / prop_dm;
% ratio of the manufacturer's profit in beta SC to the
% manufacturer's profit in DSC.
M_num3(8 * (j-1)+ i, 1:7) = [beta, k, cv, optiQuan_beta_SC*100,...
ratio_betaSC_isc*100, ratio_betaSC_dsc*100, ratio_betaM_DscM*100];
% grap the data to the empty matrix
end
end
M_num3
% show the matrix with stored values
%%
%#################### functions for numercial analysis 4 #################%
%================== power CDF ========================%
function pwercdf = powCDF(y, theta, k)
pwercdf = (y / theta)^k;
end
%============ the optimal quantity considering the retailer' power ========%
function optiQuan = optiQuanBeta(c, r, beta, k)
optiQuan = ((r - c) * beta * (k + 1) / (r * (k + beta)) )^(1/k);
end