This is a lightweight and simple Julia package for modeling and solving newsvendor problems.
NewsvendorModel.jl requires an installation of Julia (can be downloaded from the official website). You can install NewsvendorModel.jl like any other Julia package using the REPL as follows:
julia> import Pkg
julia> Pkg.add("NewsvendorModel")
After installation, it can be loaded with the usual command.
julia> using NewsvendorModel
Moreover, you need to load the Distributions.jl package.
julia> using Distributions
- Define a model with the function
nvm = NVModel(cost, price, demand)
using the following required arguments:- unit production
cost
- unit selling
price
demand
distribution, which can be any choosen from the Distributions.jl package
- unit production
- Solve for optimal quanitity and obtain key metrics with the
solve(nvm)
function.
Note that additional keyword arguments can be passed in Step 1: salvage
value and holding
cost of left-over inventory, substitute
profit obtained from serving a lost customer with an alternative, backorder
penalty from an unserved customer, fixcost
of the operations, a lower quantity bound q_min
, and an upper quantity bound q_max
.
Moreover, it is possible to obtain the unrounded optimal quantity by passing rounded=false
in Step 2. For more details go to the documentation.
Consider an example with
- unit
cost
= 5 - unit
price
= 7 demand
that draws from a normal distribution with- mean = 50
- standard deviation = 20
Define the model and store it in the variable nvm
as follows:
julia> nvm = NVModel(demand = Normal(50, 20), cost = 5, price = 7)
Julia shows the model data:
Data of the Newsvendor Model
* Demand distribution: Normal{Float64}(μ=50.0, σ=20.0)
* Unit cost: 5.00
* Unit selling price: 7.00
Next, you can solve the model and store the result in the variable res
like so:
julia> res = solve(nvm)
This gives the following output:
=====================================
Results of maximizing expected profit
* Optimal quantity: 39 units
* Expected profit: 52.41
=====================================
This is a consequence of
* Cost of underage: 2.00
╚ + Price: 7.00
╚ - Cost: 5.00
* Cost of overage: 5.00
╚ + Cost: 5.00
* Critical fractile: 0.29
* Rounded to nearest integer: true
-------------------------------------
Ordering the optimal quantity yields
* Expected sales: 35.34 units
* Expected lost sales: 14.66 units
* Expected leftover: 3.66 units
-------------------------------------
Moreover, you have stored the result in the varial res
. Reading the data from the stored result is straight-forward:
julia> q_opt(res)
39
julia> profit(res)
52.687735385066865
Analogously, underage_cost(res)
, overage_cost(res)
, critical_fractile(res)
,
rounded(res)
, sales(res)
, lost_sales(res)
, leftover(res)
,
read the other information the stored in res
. The model that was solved can be retrieved with nvmodel(res)
.