feat: Implement replenishment benchmark - #96
Conversation
6d46b59 to
b0ef349
Compare
add replenishment benchmarl update docstrings
8058990 to
bb9c34a
Compare
40b64d9 to
f13f6cd
Compare
BatyLeo
left a comment
There was a problem hiding this comment.
Thank you for your huge (you were probably right and we should have cut it in multiple smaller PRs) contribution, good start!
I've reviewed most of the src code (I just have not yet checked the maths of the maximizer and of the anticipative solver). I'll review what is missing along with plot utilities and tests in a second wave.
There are some bugs scattered around (see comments) to correct and some things to cleanup (add a bit more doctrings and explanation of what core methods/types do).
Additionally, it would be nice to have a documentation page describing the maths (see other benchmark pages) of this problem (it's quite difficult to understand the details and design choices by only reading the code).
BatyLeo
left a comment
There was a problem hiding this comment.
Second round of review:
- reviewed the new changes
- reviewed the anticipative and maximizer
- still need to review tests and plots
| scenario::Scenario | ||
| "initial stock" | ||
| stock_ini::Vector{Int} | ||
| end |
There was a problem hiding this comment.
If the stock is mutated in place the struct is still non-mutable since we do not overwrite its value (only its content)
| """ | ||
| mutable struct DRPState{B<:DynamicReplenishmentBenchmark} | ||
| "The benchmark configuration." | ||
| config::B |
There was a problem hiding this comment.
question: do we absolutely need to store the benchmark in state? This can affect performance when using deepcopy
There was a problem hiding this comment.
We need the benchmark for the maximizer : we need the constraint matrix, the number of items....
One thing that we could do is override the deepcopy of the states in order to not copying the benchmark.
We have this performance:
julia> @allocated deepcopy(state)
7568
julia> @elapsed for _ in 1:2000 deepcopy(state) end
0.003458666
julia> @allocated deepcopy(state.config)
525360
julia> @elapsed for _ in 1:2000 deepcopy(state.config) end
0.060429333
| @constraint( | ||
| m, | ||
| [i in 1:N, t in 2:(T + 1)], | ||
| v[t, i] >= |
There was a problem hiding this comment.
question: I'm not sure to understand this constraint. When z[i, t] == 0, this means 0 >= v[t, i] >= this. What am I missing?
There was a problem hiding this comment.
The physical stock is defined as the number of items that arrived in the store ( > delivery_delay time steps) and are not yet sold.
The number of items that have arrived in t in the store is :
arrived_t = stock_ini[i] + sum(y[τ, i] for τ in 1:(t - delivery_delay)
The number of items sold in t is :
sold = sum(α[i, τ, k] for τ in 1:(t - 1) for k in 1:nb_customers[τ])
Therefore, the physical stock is defined as :
max(0, arrived - sold)
To linearize this, we have :
v >= arrived - soldv <= arrived - sold + M * (1 - z)v <= M * z
Therefore :
- if
z=0: necessaryarrived-sold = 0or constraint 1. is violated and we have0 <= v <= 0 - if
z = 1:arrived - sold >= 0andv = arrived - sold
abd4455 to
16dadd0
Compare
This Pull Request adds the dynamic replenishment benchmark to the list of available benchmarks.