Flow Optimization
In this section we will see how to best flow products through the supply chain. We will assume that we want to leverage the current network (we will not open or close facilities – we will do so in the Locations Optimization example). Finding the right facility to serve customers from can be simple if there are few constraints but can become challenging when considering constraints such as throughput limits or considering complex cost structures. We will start with a simple example and then show how to handle realistic constraints.
In the first example we consider four storage locations servicing 350 customers distributed throughout the US. The aim is to find which storage location service which customer. The setup is done as in the following code.
using CSV using DataFrames using SupplyChainModeling using SupplyChainOptimization
nm = tempname() url = "https://raw.githubusercontent.com/plotly/datasets/master/2014uscities.csv" download(url, nm) uscities = CSV.read(nm, DataFrame) uscities[!,:name] = strip.(us_cities[!,:name]) rm(nm)
sort!(us_cities, [:pop], rev=true)
sc = SupplyChain(1)
product = Product("Product 1") add_product!(sc, product)
for r in eachrow(uscities[in(["Fort Worth", "Long Beach", "Philadelphia", "Louisville/Jefferson County"]).(uscities.name), :]) storage = Storage("Storage r.name", Location(r.lat + 0.2, r.lon + 0.2, r.name); fixedcost= 2000000 + r.pop / 2, openingcost=0.0, closingcost=0.0, initialopened=false) addproduct!(storage, product; initialinventory=100000) addstorage!(sc, storage) end
for (i, r) in enumerate(eachrow(first(uscities, 350))) customer = Customer("customer i", Location(r.lat, r.lon, r.name)) addcustomer!(sc, customer) adddemand!(sc, customer, product, [r.pop / 10000]) end
for c in sc.customers, s in sc.storages addlane!(sc, Lane(s, c; unitcost=haversine(s.location, c.location) / 250)) end
minimize_cost!(sc)
We can visualize the results.
In the second example, we will add a constraint on the maximal throughput that each storage location can support. We do this with a simple modification of the code:
add_product!(storage, product; initial_inventory=100_000, maximum_throughput=2_400)
After optimizing the network we see that some customers have been re-assigned to other storage locations to ensure that the throughput capacity is not exceeded.