- We want to order items in different quantities from suppliers.
- Suppliers have an available inventory for these items. This can be zero.
- We can split the ordering over different suppliers.
- The cost structure is as follows:
- Shipping cost is a fixed cost per supplier.
- Item cost is a variable per-unit cost.
---- 45 PARAMETER demand demand for items
item1 2.000, item2 9.000, item3 6.000, item4 4.000, item5 3.000, item6 3.000, item7 4.000
item8 9.000, item9 1.000, item10 6.000, item11 10.000, item12 6.000, item13 10.000, item14 8.000
item15 2.000, item16 7.000, item17 2.000, item18 3.000, item19 7.000, item20 5.000, item21 4.000
item22 4.000, item23 2.000, item24 2.000, item25 6.000, item26 9.000, item27 3.000, item28 7.000
item29 8.000, item30 4.000, item31 2.000, item32 6.000, item33 2.000, item34 9.000, item35 3.000
item36 3.000, item37 6.000, item38 8.000, item39 7.000, item40 5.000, item41 5.000, item42 2.000
item43 4.000, item44 1.000, item45 4.000, item46 2.000, item47 7.000, item48 6.000, item49 8.000
item50 3.000
---- 45 PARAMETER avail availability of items
supplier1 supplier2 supplier3 supplier4 supplier5 supplier6 supplier7 supplier8 supplier9 supplier10
item1 5.0006.0005.0002.0005.0004.0006.000
item2 1.0004.0006.0001.0004.0004.0003.0002.000
item3 1.0001.0001.0007.0003.0006.0002.0001.0005.000
item4 1.0002.0003.0001.0001.0002.0002.0002.0007.000
item5 7.0002.0002.0006.0003.0007.0005.0004.000
item6 3.0004.0005.0001.0003.0002.0001.0007.000
item7 3.0001.0003.0002.0002.0007.0001.0002.0003.000
item8 3.0002.0001.0004.0004.0006.0007.000
item9 4.0004.0002.0004.0005.0004.0001.0005.0004.000
item10 7.0001.0005.0006.0007.0001.0002.0001.0001.0005.000
item11 5.0001.0003.0001.0005.0006.0001.0003.0005.000
item12 6.0004.0007.0001.0004.0001.0005.000
item13 3.0006.0003.0004.0004.0003.0007.0001.0001.000
item14 1.0006.0004.0001.0007.0002.000
item15 4.0002.0005.0001.0003.0003.0006.0004.0003.0004.000
item16 7.0002.0007.0004.0002.0007.0006.0007.000
item17 4.0001.0005.0002.0007.0007.0002.0005.0004.000
item18 6.0007.0004.0002.0003.0006.0004.0005.000
item19 5.0005.0007.0005.0007.0006.0004.0005.0005.000
item20 6.0004.0003.0005.0001.0001.0006.0007.000
item21 6.0005.0002.0006.0006.0006.0001.0003.000
item22 2.0003.0002.0001.0006.0003.0001.0003.0002.0007.000
item23 3.0002.0003.0005.0005.0002.0007.0001.000
item24 7.0003.0002.0003.0003.0006.0006.000
item25 3.0002.0007.0005.0007.0007.0007.0006.0003.000
item26 4.0006.0004.0004.0004.0005.0001.0002.0002.000
item27 4.0002.0001.0005.0004.0004.0005.0005.0006.000
item28 5.0001.0004.0005.0001.0002.0004.0005.0003.0001.000
item29 7.0007.0007.0006.0001.0004.0001.000
item30 7.0006.0002.0003.0002.0004.0003.0003.000
item31 7.0001.0001.0004.0005.0002.0001.0007.0002.000
item32 2.0006.0001.0003.0002.0003.0005.0004.0001.000
item33 1.0002.0004.0002.0005.0005.0002.0006.0001.000
item34 5.0005.0006.0004.0002.0004.0003.0006.0002.000
item35 4.0005.0007.0004.0003.0005.0004.0007.000
item36 6.0001.0002.0005.0003.0007.0007.0007.0002.0003.000
item37 4.0007.0001.0005.0006.0004.0006.0002.0003.000
item38 2.0004.0004.0004.0004.0007.0002.0006.0007.0007.000
item39 2.0002.0001.0001.0005.0002.0006.0004.0002.0005.000
item40 6.0003.0002.0005.0003.0004.0002.0005.000
item41 7.0003.0001.0004.0002.0007.0004.0003.0001.000
item42 4.0004.0002.0002.0004.0004.0003.0007.0003.000
item43 1.0003.0003.0001.0005.0004.0004.0006.000
item44 6.0002.0001.0003.0002.0004.0007.000
item45 6.0006.0005.0003.0003.0006.0007.0004.0002.0003.000
item46 2.0003.0006.0004.0005.0006.0003.0007.0003.000
item47 3.0005.0005.0004.0001.0004.0004.0005.0001.0001.000
item48 7.0003.0007.0002.0007.0003.0004.0001.0001.000
item49 5.0006.0004.0007.0003.0002.0006.0006.0007.000
item50 4.0003.0005.0004.0002.0001.000
---- 45 PARAMETER shipcost shipping cost
supplier1 23.574, supplier2 15.066, supplier3 27.148, supplier4 35.761, supplier5 11.076, supplier6 20.661
supplier7 20.136, supplier8 24.595, supplier9 17.781, supplier10 36.736
---- 45 PARAMETER itemcostcost of items
supplier1 supplier2 supplier3 supplier4 supplier5 supplier6 supplier7 supplier8 supplier9 supplier10
item1 4.3973.5384.9464.0323.0324.0714.329
item2 3.3363.3003.2273.4144.9083.2164.7402.653
item3 4.2261.0032.8212.6771.0631.3283.3953.2213.472
item4 4.5401.7592.7121.6664.5453.7064.4531.3714.986
item5 3.4671.0033.4361.6952.2453.9161.3392.768
item6 3.6362.9382.2734.6561.7374.4882.8242.836
item7 1.4961.4151.9402.3614.4924.3794.2922.9224.655
item8 4.7171.4322.4024.4402.3621.8524.705
item9 2.4434.5041.5932.8242.0732.1871.4622.5994.647
item10 2.0061.4121.5852.5451.1861.1061.6161.2914.3152.599
item11 2.6694.8891.9742.4483.5211.9711.4042.6242.916
item12 1.5803.0394.5411.2223.0304.0564.916
item13 3.8824.4882.1984.0164.3752.8733.6202.5122.435
item14 2.0182.0222.8024.7792.3421.194
item15 4.2263.9304.6802.3271.8391.1894.5321.3714.3482.855
item16 1.0011.6263.8202.1213.5423.3204.8483.057
item17 3.3613.2701.1204.8763.3751.2383.1761.5092.682
item18 4.5263.8662.2544.9721.2213.4764.2182.186
item19 4.8363.7793.5263.4643.0921.5644.3474.5683.786
item20 2.2472.4234.0441.5453.8674.8552.7682.058
item21 2.7772.5872.4683.4854.4394.0204.6032.752
item22 1.2764.7544.3764.8023.3181.1412.6301.2303.1281.450
item23 4.5751.9673.5692.1634.2541.7453.0034.755
item24 3.7261.7414.4921.6602.7234.0874.912
item25 4.7781.9954.5464.5384.8603.9973.5903.9943.093
item26 3.7443.7644.4634.1831.8703.3584.6903.4121.143
item27 4.6443.2602.2992.5602.1971.8764.2871.6114.802
item28 1.1283.9381.4422.9512.4441.8664.6952.8004.8841.385
item29 2.9163.8892.7331.6331.4034.2222.595
item30 1.4684.4971.5791.7113.1812.8744.6373.892
item31 1.6652.3103.3253.3103.5101.1071.5181.2572.244
item32 3.3144.2393.7173.9432.3541.8974.6004.3182.265
item33 4.8092.0273.5044.8854.8482.7011.4221.3083.577
item34 2.2493.3813.4263.5354.8331.3291.5013.4213.966
item35 4.3902.4103.5664.5832.5532.0944.8822.385
item36 2.6384.7593.4124.5982.1391.8893.2993.0383.2302.377
item37 2.5934.1051.1132.4504.0232.9001.3051.3902.319
item38 1.8021.3632.7952.8514.2482.8004.8171.4912.6264.545
item39 3.8134.5003.2212.0232.0372.4201.5484.2282.3042.715
item40 1.0361.8973.6432.1501.5242.6281.6464.447
item41 2.5114.5542.0804.1102.6912.7191.9962.5271.284
item42 3.8633.8121.2814.8742.0802.2734.5343.3452.528
item43 4.8923.6834.8053.8732.7744.5192.8792.855
item44 2.4861.4734.8624.3743.8854.8582.458
item45 4.0732.3303.1681.5542.2551.3204.7372.9773.7163.766
item46 1.2191.9614.5311.4023.7131.4061.1714.0144.948
item47 1.0591.5874.9641.5291.3421.7444.1614.4583.9922.558
item48 4.1803.4844.0453.3213.6541.3293.2672.7732.313
item49 2.3221.4923.4713.1361.5762.5691.0594.4831.982
item50 4.2131.3364.9493.2333.7284.438
Mathematical Model |
---|
\[ \begin{align} \text{Sets} \\ & i \text{: items} \\ & s \text{: suppliers} \\ & \hline \\ \text{Data} \\ & \color{darkblue}{\mathit{shipCost}}_s \text{: shipping cost}\\ & \color{darkblue}{\mathit{itemCost}}_{i,s} \text{: item cost}\\ & \color{darkblue}{\mathit{demand}}_{i} \text{: demand quantities}\\ & \color{darkblue}{\mathit{avail}}_{i,s} \text{: availability}\\ & \color{darkblue}{\mathit{maxBuy}}_{i,s} := \min\left\{\color{darkblue}{\mathit{avail}}_{i,s},\color{darkblue}{\mathit{demand}}_{i}\right\} \text{: upperbound on buying quantities}\\ & \hline \\ \text{Variables} \\ & \color{darkred}{\mathit buy}_{i,s} \text{: purchase quantities} \\ & \color{darkred}{\mathit use}_{s} = \begin{cases}1&\text{if supplier is used}\\ 0&\text{otherwise}\end{cases} \\ & \hline \\ \text{Model} \\ \min& \sum_s \color{darkblue}{\mathit shipCost}_s\cdot \color{darkred}{\mathit use}_s + \sum_{i,s} \color{darkblue}{\mathit itemCost}_{i,s}\cdot \color{darkred}{\mathit buy}_{i,s} \\ & \sum_s \color{darkred}{\mathit buy}_{i,s} = \color{darkblue}{\mathit demand}_{i} && \forall i \\ & \color{darkred}{\mathit buy}_{i,s} \le \color{darkblue}{\mathit maxBuy}_{i,s} \cdot \color{darkred}{\mathit use}_s && \forall i,s\\ & \color{darkred}{\mathit buy}_{i,s} \in \{0,\dots,\color{darkblue}{\mathit maxBuy}_{i,s}\}\\ & \color{darkred}{\mathit use}_s \in \{0,1\} \end{align}\] |
---- 97 VARIABLE totalcost.L = 598.132to be minimized
---- 97 VARIABLE use.L supplier is used
supplier1 1.000, supplier5 1.000, supplier6 1.000, supplier7 1.000, supplier8 1.000, supplier9 1.000
---- 97 VARIABLE buy.L orders to be placed at suppliers
supplier1 supplier5 supplier6 supplier7 supplier8 supplier9
item1 2.000
item2 1.0001.0004.0003.000
item3 3.0003.000
item4 1.0001.0002.000
item5 3.000
item6 3.000
item7 3.0001.000
item8 3.0006.000
item9 1.000
item10 5.0001.000
item11 1.0006.0001.0002.000
item12 5.0001.000
item13 3.0006.0001.000
item14 6.0002.000
item15 2.000
item16 7.000
item17 2.000
item18 3.000
item19 1.0006.000
item20 5.000
item21 1.0003.000
item22 3.0001.000
item23 2.000
item24 2.000
item25 6.000
item26 4.0005.000
item27 3.000
item28 5.0002.000
item29 1.0006.0001.000
item30 4.000
item31 2.000
item32 1.0002.0003.000
item33 2.000
item34 2.0004.0003.000
item35 3.000
item36 3.000
item37 6.000
item38 2.0006.000
item39 1.0006.000
item40 3.0002.000
item41 1.0004.000
item42 2.000
item43 4.000
item44 1.000
item45 4.000
item46 2.000
item47 3.0001.0003.000
item48 3.0002.0001.000
item49 2.0006.000
item50 3.000
Conclusion
References
- How would I go about finding the optimal way to split up an order, https://stackoverflow.com/questions/75447782/how-would-i-go-about-finding-the-optimal-way-to-split-up-an-order
Appendix: GAMS model
$ontext
Supplier selection problem We want to order quantities for different items. The shipping cost is a fixed cost: any amount ordered from a supplier has the same shipping cost. There are also variable cost: the item cost. We use here random data. A check is added for the case that demand exceeds the availability. maxBuy are big-M values. We try to make them as small as possible.
$offtext
*----------------------------------------------------------------------- * size of the problem *-----------------------------------------------------------------------
Sets i 'items' /item1*item50/ s 'suppliers' /supplier1*supplier10/ ;
*----------------------------------------------------------------------- * random data *-----------------------------------------------------------------------
Parameters demand(i) 'demand for items' avail(i,s) 'availability of items' shipcost(s) 'shipping cost' itemcost(i,s) 'cost of items' ;
demand(i) = uniformint(1,10); avail(i,s) = uniformint(0,7); shipcost(s) = uniform(10,40); itemcost(i,s)$avail(i,s) = uniform(1,5);
display demand,avail,shipcost,itemcost;
*----------------------------------------------------------------------- * derived data *-----------------------------------------------------------------------
Parameters totalavail(i) 'total availability' short(i) 'shortages' maxbuy(i,s) 'upperbound on buy' ;
totalavail(i) = sum(s,avail(i,s)); short(i) = max(0, demand(i)-totalavail(i)); maxbuy(i,s) = min(demand(i),avail(i,s));
display totalavail,short,maxbuy;
*----------------------------------------------------------------------- * stop if we have shortages. That would yield an infeasible model. *-----------------------------------------------------------------------
abort$card(short) "not enough availability";
*----------------------------------------------------------------------- * model *-----------------------------------------------------------------------
variables totalcost 'to be minimized' buy(i,s) 'orders to be placed at suppliers' use(s) 'supplier is used' ; integer variable buy; binary variable use; buy.up(i,s) = maxbuy(i,s);
equations objective 'minimize totalcost' meetdemand(i) 'distribute demand over suppliers' use_supplier(i,s) 'use=0 => buy=0' ;
objective.. totalcost =e= sum(s,shipcost(s)*use(s)) + sum((i,s),itemcost(i,s)*buy(i,s)); meetdemand(i).. sum(s, buy(i,s)) =e= demand(i); use_supplier(i,s).. buy(i,s) =l= maxbuy(i,s)*use(s);
model m /all/; solve m minimizing totalcost using mip;
display totalcost.l,use.l,buy.l; |