Quick start
This is a lightweight and simple Julia package for modeling and solving newsvendor problems.
Setup
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 NewsvendorModelMoreover, you need to load the Distributions.jl package.
julia> using DistributionsUsage
- Define a model with the function
nvm = NVModel(demand, cost, price)using the following required arguments:demanddistribution, which can be any choosen from the univariate distributions of the Distributions.jl package- unit production
cost - unit selling
price
- Find the optimal quanitity and obtain key metrics:
q_opt(nvm)returns the quantity that maximizes the expected profitprofit(nvm, q)to get the expected profit ifqis stockedprofit(nvm)is short for the maximal expected profitprofit(nvm, q_opt(nvm))solve(nvm)gives a list of further important metrics (critical fractile as well as expected sales, lost sales, and leftover).
Additional keyword arguments specifying salvage value, backorder penalty, holding cost, substitute value, fixcost, qmin, and qmax can be passed in Step 1. To obtain the unrounded optimal quantity, pass rounded=false in Step 2.
Example
Consider an example with
- unit
cost= 5 - unit
price= 7 demandthat 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)
Data of the Newsvendor Model
* Demand distribution: Normal{Float64}(μ=50.0, σ=20.0)
* Unit cost: 5.00
* Unit selling price: 7.00Next, you can solve the model and store the result in the variable res like so:
julia> res = solve(nvm)
=====================================
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 variable res. Reading the data from the stored result is straight-forward:
julia> q_opt(res)
39julia> profit(res)
52.40715617998893Analogously, underage_cost(res), overage_cost(res), critical_fractile(res), sales(res), lost_sales(res), leftover(res) read.
Applying the above functions directly to the model (instead of to the result) is also possible, with the ability to pass a quantity. For instance,
julia> leftover(nvm, 39)
3.656120545715868An advantage of using the solve function and then reading the data from the result lies in the fact that the model that was solved can be retrieved with nvmodel(res).