Sonuçlar ve Bu Model Nerede Yetmez
Ne kadar iyileşti, hangi varsayımlar tutmadı, üretimde ne değişir.
Blok Transfer · 6 / 7
Bu dizi bir sözle açılmıştı: sıfır yeni ürünle daha çok satış. Depodan tek koli çıkmadan, üretime tek kuruş verilmeden, yalnızca yanlış yerde duranı doğru yere taşıyarak. Şimdi hesabı verme vakti.
Referans senaryoda vericide coverMevcut stoğun satış hızına bölünmesiyle bulunan yeterlilik süresi; kaç haftalık satışı karşılayacağını söyler. en az 6 hafta; alıcı tavanı kapalı, yani alıcı yalnız rafı kırık ya da boş olan mağaza olabiliyor; alıcıda asgari haftalık satış 1 adet. Bu ayarda açgözlünün çıkardığı plan şu: 586 option, 99.029 adet, 32,68 milyon TL net etki. Çözücü aynı fotoğraftan 661 option, 109.100 adet ve 35,93 milyon TL çıkarıyor.
Aşağıdaki demoda kadranı çevirip bu sayıların eşiklerle nasıl değiştiğini kendiniz görebilirsiniz. İkinci yazıda Ali’nin tahtaya yazdığı iki sayı burada iki ayrı kadran: vericide asgari cover (6, 14, 18 ya da 26 hafta) ve alıcıda azami cover (kapalı, 3, 6 ya da 14 hafta). Üçüncü kadran yöntemi seçiyor: açgözlü ya da çözücü. Demo referans senaryonun açgözlü planıyla açılıyor. Kayıp satış yakalama satırındaki sayı bir kestirim; ne demek olduğunu birazdan açacağım.
- Taşınacak option
- 586
- Taşınan adet
- 99.029
- Açılan sevkiyat
- 340
- Stoğu boşalan mağaza
- 73
- Net kazanç (TL)
- 32.680.687,71
- Kayıp satış yakalama (%)
- 3,4
- Çözüm süresi (sn)
- 0,04
- Taşınacak option
- 661
- Taşınan adet
- 109.100
- Açılan sevkiyat
- 318
- Stoğu boşalan mağaza
- 77
- Net kazanç (TL)
- 35.934.123,1
- Kayıp satış yakalama (%)
- 3,6
- Çözüm süresi (sn)
- 54,702
- Taşınacak option
- 804
- Taşınan adet
- 126.098
- Açılan sevkiyat
- 456
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 45.822.639,86
- Kayıp satış yakalama (%)
- 4,4
- Çözüm süresi (sn)
- 0,03
- Taşınacak option
- 851
- Taşınan adet
- 133.150
- Açılan sevkiyat
- 456
- Stoğu boşalan mağaza
- 80
- Net kazanç (TL)
- 49.627.967,91
- Kayıp satış yakalama (%)
- 4,2
- Çözüm süresi (sn)
- 675,439
- Taşınacak option
- 717
- Taşınan adet
- 132.856
- Açılan sevkiyat
- 398
- Stoğu boşalan mağaza
- 80
- Net kazanç (TL)
- 57.133.383,18
- Kayıp satış yakalama (%)
- 3,9
- Çözüm süresi (sn)
- 0,038
- Taşınacak option
- 895
- Taşınan adet
- 137.163
- Açılan sevkiyat
- 479
- Stoğu boşalan mağaza
- 80
- Net kazanç (TL)
- 59.884.561,22
- Kayıp satış yakalama (%)
- 3,8
- Çözüm süresi (sn)
- 866,735
- Taşınacak option
- 753
- Taşınan adet
- 141.414
- Açılan sevkiyat
- 412
- Stoğu boşalan mağaza
- 77
- Net kazanç (TL)
- 64.528.094,14
- Kayıp satış yakalama (%)
- 3,6
- Çözüm süresi (sn)
- 0,045
- Taşınacak option
- 917
- Taşınan adet
- 145.006
- Açılan sevkiyat
- 438
- Stoğu boşalan mağaza
- 80
- Net kazanç (TL)
- 67.450.089,07
- Kayıp satış yakalama (%)
- 3,6
- Çözüm süresi (sn)
- 1.064,824
- Taşınacak option
- 443
- Taşınan adet
- 84.588
- Açılan sevkiyat
- 257
- Stoğu boşalan mağaza
- 71
- Net kazanç (TL)
- 29.467.476,73
- Kayıp satış yakalama (%)
- 2,7
- Çözüm süresi (sn)
- 0,016
- Taşınacak option
- 508
- Taşınan adet
- 92.830
- Açılan sevkiyat
- 245
- Stoğu boşalan mağaza
- 75
- Net kazanç (TL)
- 32.008.028,78
- Kayıp satış yakalama (%)
- 2,8
- Çözüm süresi (sn)
- 2,942
- Taşınacak option
- 599
- Taşınan adet
- 105.187
- Açılan sevkiyat
- 360
- Stoğu boşalan mağaza
- 78
- Net kazanç (TL)
- 40.828.440,59
- Kayıp satış yakalama (%)
- 3,4
- Çözüm süresi (sn)
- 0,022
- Taşınacak option
- 700
- Taşınan adet
- 116.312
- Açılan sevkiyat
- 344
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 44.160.598,48
- Kayıp satış yakalama (%)
- 3,4
- Çözüm süresi (sn)
- 147,118
- Taşınacak option
- 675
- Taşınan adet
- 122.371
- Açılan sevkiyat
- 405
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 52.914.637,9
- Kayıp satış yakalama (%)
- 3,3
- Çözüm süresi (sn)
- 0,026
- Taşınacak option
- 782
- Taşınan adet
- 127.905
- Açılan sevkiyat
- 439
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 57.529.812,95
- Kayıp satış yakalama (%)
- 3,1
- Çözüm süresi (sn)
- 469,994
- Taşınacak option
- 730
- Taşınan adet
- 135.093
- Açılan sevkiyat
- 433
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 60.783.553,47
- Kayıp satış yakalama (%)
- 3
- Çözüm süresi (sn)
- 0,028
- Taşınacak option
- 832
- Taşınan adet
- 137.327
- Açılan sevkiyat
- 438
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 63.980.996,48
- Kayıp satış yakalama (%)
- 2,9
- Çözüm süresi (sn)
- 814,686
- Taşınacak option
- 369
- Taşınan adet
- 77.519
- Açılan sevkiyat
- 207
- Stoğu boşalan mağaza
- 65
- Net kazanç (TL)
- 26.488.700,64
- Kayıp satış yakalama (%)
- 2,3
- Çözüm süresi (sn)
- 0,012
- Taşınacak option
- 419
- Taşınan adet
- 84.292
- Açılan sevkiyat
- 203
- Stoğu boşalan mağaza
- 70
- Net kazanç (TL)
- 28.717.507,48
- Kayıp satış yakalama (%)
- 2,4
- Çözüm süresi (sn)
- 1,926
- Taşınacak option
- 497
- Taşınan adet
- 93.334
- Açılan sevkiyat
- 302
- Stoğu boşalan mağaza
- 76
- Net kazanç (TL)
- 35.994.095,33
- Kayıp satış yakalama (%)
- 2,8
- Çözüm süresi (sn)
- 0,015
- Taşınacak option
- 553
- Taşınan adet
- 101.625
- Açılan sevkiyat
- 271
- Stoğu boşalan mağaza
- 76
- Net kazanç (TL)
- 38.533.599,34
- Kayıp satış yakalama (%)
- 2,9
- Çözüm süresi (sn)
- 3,49
- Taşınacak option
- 596
- Taşınan adet
- 111.516
- Açılan sevkiyat
- 361
- Stoğu boşalan mağaza
- 78
- Net kazanç (TL)
- 47.705.615,61
- Kayıp satış yakalama (%)
- 2,9
- Çözüm süresi (sn)
- 0,021
- Taşınacak option
- 714
- Taşınan adet
- 122.400
- Açılan sevkiyat
- 432
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 51.535.516,73
- Kayıp satış yakalama (%)
- 2,8
- Çözüm süresi (sn)
- 231,892
- Taşınacak option
- 690
- Taşınan adet
- 127.297
- Açılan sevkiyat
- 416
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 55.748.623,26
- Kayıp satış yakalama (%)
- 2,6
- Çözüm süresi (sn)
- 0,033
- Taşınacak option
- 787
- Taşınan adet
- 136.683
- Açılan sevkiyat
- 444
- Stoğu boşalan mağaza
- 79
- Net kazanç (TL)
- 58.829.810,93
- Kayıp satış yakalama (%)
- 2,6
- Çözüm süresi (sn)
- 344,37
- Taşınacak option
- 292
- Taşınan adet
- 67.342
- Açılan sevkiyat
- 155
- Stoğu boşalan mağaza
- 55
- Net kazanç (TL)
- 22.621.061,19
- Kayıp satış yakalama (%)
- 1,9
- Çözüm süresi (sn)
- 0,012
- Taşınacak option
- 323
- Taşınan adet
- 72.576
- Açılan sevkiyat
- 153
- Stoğu boşalan mağaza
- 60
- Net kazanç (TL)
- 24.124.686,66
- Kayıp satış yakalama (%)
- 1,9
- Çözüm süresi (sn)
- 0,917
- Taşınacak option
- 368
- Taşınan adet
- 77.582
- Açılan sevkiyat
- 219
- Stoğu boşalan mağaza
- 66
- Net kazanç (TL)
- 29.273.284,54
- Kayıp satış yakalama (%)
- 2,1
- Çözüm süresi (sn)
- 0,015
- Taşınacak option
- 403
- Taşınan adet
- 84.063
- Açılan sevkiyat
- 208
- Stoğu boşalan mağaza
- 69
- Net kazanç (TL)
- 31.201.406,42
- Kayıp satış yakalama (%)
- 2
- Çözüm süresi (sn)
- 1,618
- Taşınacak option
- 464
- Taşınan adet
- 92.572
- Açılan sevkiyat
- 284
- Stoğu boşalan mağaza
- 73
- Net kazanç (TL)
- 39.534.836,48
- Kayıp satış yakalama (%)
- 2
- Çözüm süresi (sn)
- 0,014
- Taşınacak option
- 527
- Taşınan adet
- 101.831
- Açılan sevkiyat
- 287
- Stoğu boşalan mağaza
- 76
- Net kazanç (TL)
- 41.922.719,33
- Kayıp satış yakalama (%)
- 2,2
- Çözüm süresi (sn)
- 12,655
- Taşınacak option
- 558
- Taşınan adet
- 111.401
- Açılan sevkiyat
- 348
- Stoğu boşalan mağaza
- 76
- Net kazanç (TL)
- 46.495.715,05
- Kayıp satış yakalama (%)
- 1,9
- Çözüm süresi (sn)
- 0,023
- Taşınacak option
- 607
- Taşınan adet
- 118.759
- Açılan sevkiyat
- 347
- Stoğu boşalan mağaza
- 77
- Net kazanç (TL)
- 48.815.904,57
- Kayıp satış yakalama (%)
- 2,1
- Çözüm süresi (sn)
- 254,991
Bütün kombinasyonlar sayfayla birlikte geldi; sunucuya hiç gidilmiyor.
İstanbul 18’in telefonuna dönelim
Dizinin ilk yazısı bir telefonla açılmıştı: İstanbul 18’de haki örgü kazağın S ve M bedenleri bitmiş, rafta yalnız L, XL ve XXL kalmıştı. Aynı kazaktan Malatya 1’de tam set duruyordu, 103 adet.
İki plan da aynı şeyi yapıyor: Malatya 1’in bloğunu, 103 kazağın tamamını İstanbul 18’e gönderiyor. Veli’nin o akşamki sorusu, “Malatya’nın kazağı niye İstanbul 18’e gitti de Ankara 3’e gitmedi?”, artık cevapsız değil; ama cevap pek parlak da değil. Terazide bu blok için üç mağaza tam aynı ağırlıkta: İstanbul 18, Ankara 3 ve İzmir 6, üçü de 8.428,74 TL. Açgözlü eşitliği dördüncü yazıdaki sıralama kuralıyla bozuyor, çözücü de aynı yeri seçiyor. Yani gerekçe “İstanbul 18 daha çok hak ediyordu” değil, “terazi eşit dedi, eşitliği yazılı bir kural bozdu”. Küçük bir cevap, ama savunulabilir; Veli’nin o akşam elinde olmayan da tam olarak buydu.
Karardan sonraki sekiz hafta bu bloğa ne dedi? Kestirime göre İstanbul 18’de o kazakta bedenini bulamayıp boş çıkacak müşteri 105 kişi; gerçek kayıpla 150. Malatya’nın bloğu bunun 87’sini kurtarıyor, gerçek kayıpla 93’ünü. Eksik kalan kısım bloğun şeklinden geliyor: S’den 13 kazak gidiyor ama S arayan 30 müşteri boş çıkacak; XXL’den 16 kazak gidiyor, XXL’de boş çıkacak olan üç kişi. Blok bölünmüyor, bedenleri ihtiyaca göre seçilmiyor; Malatya’nın rafında ne varsa o gidiyor.
Malatya müdürü de haksız değilmiş: bu 103 kazağın 52’si o sekiz haftada Malatya’da da satılacaktı. Bu sayı bir üst sınır, nedenini bir sonraki yazıda açacağım. Ama yön belli: iyi bir transferin bile bir bedeli var ve o bedeli verici öder.
Bu tek bir kazak. O pazartesi fotoğrafında böyle 2.687 kırıkBir option'ın beden setinin bozulması; ara bedenler tükenmiş, uçlar rafta kalmıştır. (mağaza, option) çifti vardı ve dürüst cevap şu: algoritma bunların hepsini çözmüyor.
| Açgözlü | Çözücü | |
|---|---|---|
| Alıcı olarak adreslenen kırık çift | 219 | 233 |
| Kırık seti verici yapan hareket | 0 | 0 |
İki bin altı yüz seksen yedinin iki yüz otuz üçü, yüzde 8,7. Geri kalanı neden değil? Dört sebep var ve dördü de matematiğin değil, gerçekliğin sınırı: o option’ın hiçbir mağazada verilebilecek fazlası yoktur, alıcının satış hızı eşiğin altındadır, taşımanın maliyeti kazancını yemektedir ya da alıcının yeri dolmuştur. Sonuncusu bu veride kâğıtta kalmıyor: çözücünün taşımadığı, puanı pozitif bloklardan 194’ü alıcısının kalan boşluğuna sığmıyor. Bir algoritmanın yapabileceği en dürüst şey, çözemediği yeri çözebildiği yerden ayırmaktır.
İkinci satır belki daha önemli: hiçbir hareket kırık bir seti verici
yapmıyor. Yani model derdi bir mağazadan alıp başka mağazaya taşımıyor. Bunu
çözücüye ayrıca kısıt olarak yazmadık; aday üretimi kırık rafı verici
saymıyor. Dördüncü yazıdaki sorgunun and not v.kirik satırı tam olarak bu.
Kural kısıt listesinde değil, aday kümesinin tanımında duruyor; üçüncü yazının
tezi burada da geçerli. İkinci yazıda Ali’nin “cover’ı kırıklıkla birlikte
okumazsan terazi tersine çalışır” cümlesinin kodda karşılığı budur.
İki yöntem yan yana
Dizinin dördüncü ve beşinci yazıları aynı problemi iki ayrı yoldan çözdü. Bütün ölçütlerle yan yana:
| Ölçüt | Açgözlü (SQL + döngü) | Çözücü (MIP + PuLP) |
|---|---|---|
| Taşınan option | 586 | 661 |
| Taşınan adet | 99.029 | 109.100 |
| Açılan sevkiyat | 340 (268’i tek option) | 318 (194’ü tek option) |
| Net kazanç | 32.680.688 TL | 35.934.123 TL |
| Çözüm süresi | 39,7 ms | 54,7 sn |
| En iyi plana uzaklık | kendi başına ölçemez | en fazla %0,18 |
| Kayıp satış yakalama (kestirim · gerçek kayıp) | %3,4 · %3,2 | %3,6 · %3,4 |
| Adreslenen kırık çift | 219 | 233 |
| Kurulum | yok | PuLP + CBC |
| “Neden bu hareket?” cevabı | tek satır | yok |
Paraya bakarsanız çözücü kazanıyor: 3.253.435 TL, yani yüzde 9,1. Bu farkın nereden geldiğini dördüncü yazıda görmüştük: kamyonlardan değil, mal seçiminden. Çözücü 22 rota az açıyor ve bunun değeri 11.000 TL; kalan 3.242.435 TL hangi kolinin hangi rafa gittiğinden geliyor.
Tablonun bir satırı ayrıca açıklanmayı hak ediyor: kayıp satış yakalama. İkinci yazıda tanımlamıştık: bu plan, karardan sonraki haftalarda gerçekten boş çıkacak müşterinin ne kadarını kurtarırdı? Boş çıkan müşteri kasaya uğramaz, hiçbir yerde kaydı yoktur; bu kayıp ölçülmez, kestirilir. Kestirimi Satış Kaybı dizisinin Basit yöntemi yapıyor. Lumoda sentetik bir zincir olduğu için verinin içinde gerçek kayıp da saklı duruyor; kestirimin ne kadar tuttuğunu onunla sınıyoruz. Tablodaki iki sayı bu yüzden: soldaki kestirim, sağdaki gerçek kayıp. Birbirine yakınlar ve iki yöntemi aynı sıraya koyuyorlar.
İkisi de çözücüye hiç girmiyor. Model ne kestirimi görüyor ne gerçeği; karar anından sonraki hiçbir satır ona verilmiyor. Bu sayılar yalnızca sonradan, planı tartmak için kullanılıyor.
Oranlar küçük ve bunun bir sebebi var. Payda zincirin o sekiz haftadaki bütün kaybı, kestirime göre 443.961 adet. Transfer ise yalnız bir yerde fazlası olan option’larda iş görür; hiçbir mağazada fazlası olmayan bir kazağın boş çıkan müşterisine hiçbir kamyon yetişemez. Açgözlü plan 99.029 adet taşıyıp bu kaybın 15.244 adedini kurtarıyor. Oran küçük, ama kurtarılan her adet rafın önünden eli boş dönecek bir müşteri.
Beklemediğim sonuç
Bu sonuç tabloda değil, kadranda çıktı. İkinci yazıda Ali tahtaya tek bir çizgi yerine iki sayı yazmıştı: biri vericideki bolluğun eşiği, öbürü alıcıdaki kıtlığın tavanı. Aynı stok fotoğrafını altı eşik takımıyla çalıştırınca çözücünün planı şöyle değişiyor:
| Eşik takımı | Taşınan option | Net kazanç | Kayıp satış yakalama (kestirim · gerçek kayıp) | Çözücünün durumu |
|---|---|---|---|---|
| verici ≥ 6 hafta · alıcı tavanı kapalı | 661 | 35.934.123 TL | %3,6 · %3,4 | toleransta, %0,18 |
| verici ≥ 6 hafta · alıcı ≤ 3 hafta | 851 | 49.627.968 TL | %4,2 · %3,7 | limit, %1,33 |
| verici ≥ 6 hafta · alıcı ≤ 6 hafta | 895 | 59.884.561 TL | %3,8 · %3,4 | limit, %5,24 |
| verici ≥ 14 hafta · alıcı ≤ 6 hafta | 782 | 57.529.813 TL | %3,1 · %2,7 | limit, %1,96 |
| verici ≥ 18 hafta · alıcı ≤ 14 hafta | 787 | 58.829.811 TL | %2,6 · %2,3 | limit, %1,71 |
| verici ≥ 26 hafta · alıcı ≤ 6 hafta | 527 | 41.922.719 TL | %2,2 · %1,9 | toleransta, %0,36 |
Son sütun çözücünün dürüstlük sütunu: yüzde, planın olası en iyi plandan en
fazla ne kadar uzak olduğu. Altı satırın dördünde çözücü emniyet için
koyduğumuz düğüm sınırına takıldı ve limit bayrağıyla döndü. O planlar iyi
ama kanıtlanmamış; hiçbirine “en iyi plan” demiyorum.
Şimdi ilk ve üçüncü satıra bakın: aralarında tek bir kadran dönüyor, verici eşiği yerinde duruyor. Alıcı tavanını kapalıdan altı haftaya açmak plana 234 hareket ekliyor ve net kazancı 23.950.438 TL büyütüyor: yüzde 66,7, kabaca üçte iki. Aynı hamlede kayıp satış yakalama (iki ondalıkla) kestirimle %3,62’den %3,83’e çıkıyor, gerçek kayıpla %3,40’tan %3,36’ya iniyor. Yani yerinde sayıyor. Açgözlü planda da tablo aynı: para %74,8 büyüyor, yakalama iki ölçüde de yarım puandan az kıpırdıyor.
Pelin tabloyu görünce ikinci yazıdaki sorusuna dönüyor:
— Tavanı açınca iki yüzden fazla hareket ekleniyor, para üçte iki büyüyor. Bu kadar mal kımıldıyor da boş çıkan müşteri nasıl fark etmiyor?
Ali’nin cevabı kısa:
— Çünkü tavan açılınca alıcı listesine giren mağazaların seti kırık değil. Rafları dolu değil ama boş da değil; müşteri bugün bedenini buluyor. Oraya yolladığın koli iyi satar, ciroyu da büyütür; terazi o yüzden ona yüksek puan veriyor. Ama o rafın önünde bedenini bulamayıp boş çıkacak müşteri az. Para o raflarda, boş çıkan müşteri başka raflarda.
— O zaman müşteriyi düşünen tavanı kapalı mı tutmalı? diyor Pelin.
— Onu da söyleyemem, diyor Ali. İkinci satıra bak. Tavanı yalnız üç haftaya açınca hem para artıyor hem yakalama; bitmek üzere olan raf, birkaç hafta sonra boş çıkacak müşterinin rafıdır. Altı haftaya açınca o artış geri gidiyor. Para ile müşteri aynı kadranda duruyor ama birlikte dönmüyor.
Çözücü yanlış bir şey yapmadı. Ona ne dediysek onu yaptı: net kazancı büyüt. Boş çıkan müşteriyi hiç duymadı bile; o ölçütü ona hiç söylemedik. Yakalamanın kadranla bir artıp bir azalması bundan: model onu kovalamıyor. Yakalanan kısım, paranın peşinden giden planın yolda denk geldiği kısım.
Bu dizinin en pahalı cümlesi bu olabilir: amaç fonksiyonuna yazmadığınız şey, sizin için yoktur. Optimizasyonun tehlikesi yanlış cevap vermesi değil, sorduğunuz soruya titizlikle cevap verirken sormadığınız soruyu sessizce bir kenara bırakmasıdır. Önceliğiniz müşterinin aradığını bulmasıysa, bunu amaç fonksiyonuna yazmanız gerekir; yoksa modeliniz onu umursamaz. Umursamadığı şey bazen artar, bazen azalır; ikisi de tesadüftür.
Tablonun dördüncü ve beşinci satırları, ikinci yazıda gördüğümüz karşılaştırma ve aynı dersin başka bir yüzü. Verici eşiğini yükseltip alıcı tavanını gevşetmek kâğıtta temkinli görünür. Sonuçta kamyon yine doluyor: 18/14 planı 14/6 planından beş hareket fazla, daha çok adet taşıyor ve %2,3 daha çok kazandırıyor. Ama kayıp satış yakalama kestirimle %3,10’dan %2,65’e, gerçek kayıpla %2,72’den %2,31’e iniyor. Ali’nin “hiçbir şey çözmeyen koliler” dediği bunlar: para biraz artıyor, kurtarılan müşteri azalıyor.
Peki hangisini kurmalı?
Kesin bir cevabı yok, ama karar birkaç soruya indirgenebilir.
Açgözlü yöntem yeter, eğer sabit maliyetler (kamyon, koli, mal kabul) toplamın yanında küçükse; kararlar birbirini az kısıtlıyorsa; ekipte optimizasyon bakacak kimse yoksa; ve verilen kararın tek satırla savunulabilmesi sizin için “en iyi”den daha değerliyse.
Çözücü gerekir, eğer rota veya parti maliyetleri ağırsa; kapasiteler gerçekten kilitliyorsa; kararlar birbirine bağımlıysa; ve kaybınızın büyüklüğünü bilmek istiyorsanız.
Son madde en önemlisi ve dördüncü yazının kapanışıydı: %90,9’u biz biliyoruz, çünkü ikisini de kurup ölçtük. Yalnızca birini çalıştıran bir zincir, sonucunun %90,9 mu yoksa %70 mi olduğunu bilemez. Bu yüzden üçüncü bir seçenek daha var ve çoğu zaman en akıllısı odur: ikisini birden kurun, farkı ölçün, sonra hangisini yaşatacağınıza karar verin. Fark küçükse basit olanı üretimde tutarsınız; ama artık bilerek tutuyorsunuzdur. Lumoda’nın bu haftasında fark küçük değil: üç milyon TL’den fazla.
Ölçmenin de bir sınırı var. Yukarıdaki tablonun dört satırında çözücü kanıt üretmeden durdu. Orada açgözlüyle arasındaki farkı ölçtüğünüzde açgözlünün en iyi plandan uzaklığını eksik ölçersiniz; gerçek açık biraz daha büyük olabilir. Ne kadar büyük olabileceği de bellidir: çözücünün bıraktığı boşluk kadar, en fazla %5,24.
Varsayımlar ve bu model nerede yetmez
Dizi boyunca dağıttığım dürüstlük maddelerini tek yerde topluyorum. Hiçbiri gizli değil; hepsi bilinçli sadeleştirme.
Kazanç kâr değil, ciro etkisidir. Terazi liste fiyatıyla kuruldu, alış maliyeti düşülmedi. Tablodaki TL rakamları “yer değiştiren ciro”dur. Lumoda’da marj ürüne göre değişiyor; üçüncü yazıda ölçtük, teraziyi kârla kurunca plan değişiyor ama kâr yalnız binde birkaç artıyor.
Blok bölünmez, tek hedefe gider. Bir mağazadan alınan stok ikiye ayrılmıyor. İstanbul 18’in kazağında bunun bedelini gördük: XXL’den gereğinden fazla, S’den gereğinden az gitti. Bölünebilir dağıtım ayrı bir problem ve kendi yazısını hak ediyor.
Ufuk sabit sekiz hafta. Veride sezon takvimi var; karar anı sezonun ortasında, indirimden önce ve sekiz haftalık ufuk indirim başlamadan kapanıyor. Ama ikinci yazıdaki “raf ömrü kadranı”, yani sezon sonu yaklaştıkça terazinin taşımaya yatması, modelde yok. Gerçek kurulumda ufuk option başına değişir ve indirim takvimine bağlanır. Takvim veride durduğu için bu bir veri eksiği değil, sıradaki adım.
Soğuma yalnız iki haftaya bakıyor. Kural depodan da mağazadan da gelen bütün varışları görüyor; karar anında 11.250 raf soğumada, 21’ine mal başka bir mağazadan gelmiş. Ama bir malın sezon boyunca kaç kere taşındığını saymıyor. Bunun bedelini bir sonraki yazıda konuşacağız.
Talep sansürlü ölçülüyor. Kırık setli mağazanın gerçek talebi ölçtüğümüzden yüksektir. En çok yardıma muhtaç mağaza, modelin gözünde olduğundan sönük görünür. Bu dizide düzeltmedik; modelin neye dayandığı bulanıklaşmasın istedik. Sıradaki adım ise belli: hızı sansürlü satıştan değil, karar anına kadarki kaybı da kestiren bir kestiriciden almak.
Kapasite adet bazlı. Metrekare, reyon ve askı ayrı ayrı modellenmiyor; kapasite mağazanın geçmişte fiilen taşıdığı yükten ölçülüyor. Bu veride kapasite gerçekten bağlıyor, o yüzden tanımı en çok tartışılacak varsayım bu.
Determinizm ücretsiz gelmiyor. Aynı veriyle iki koşunun aynı planı vermesi kendiliğinden olmuyor: hem açgözlü sıralamada, hem çözücünün değişken adlandırmasında, hem de aday tablosunun satır sırasında ayrı ayrı sağlanması gerekti. Üçünden birini kaçırdığınızda bu size hata olarak değil, “geçen hafta başka söylüyordu” olarak geri döner.
Üretimde ne değişir
Gerçek bir zincirde bu modelin şekli aynı kalır, ayrıntısı değişir. Ürün hiyerarşisi daha derindir; mağazalar grup ve bölge taşır; “şu iki mağaza arasında transfer olmaz” gibi şirkete özel kurallar vardır; sevkiyat takvimi haftanın belirli günlerine bağlıdır. Bunların hepsi ya aday kümesinin tanımına ya da kısıt listesine eklenir. Üçüncü yazının cümlesi burada da geçerlidir: modelin en önemli kısmı çoğu zaman yazmadığınız kısıtlardır.
Bir de ölçek meselesi var. Lumoda 80 mağaza ve 1.870 option’lı bir zincir ve
model kurmanın genelde “gerçek zincirde karşınıza çıkar” diye ertelenen
dertleri bu veride zaten yaşanıyor. Referans ayarda çözücü 54,7 saniyede
toleransın içinde duruyor; kadranın çoğu ayarında ise dakikalarca koşup
limit bayrağıyla dönüyor. Zaman limiti, limit bayrağı ve “kanıtlanmamış ama iyi”
çözümle çalışmak burada bir dipnot değil, işin kendisi. Gerçek bir zincirde
mağaza ve ürün sayısı bunun da üstündedir.
Gerçek kurulumda eklenen kısıtlar
Yukarıdaki modelde dört kısıt var. Gerçek bir zincirde bu liste hep uzar ve uzayan kısımlar genelde aynı yerlerden gelir. Sık istenenleri, bizim modelde karşılığı olup olmadığıyla birlikte topladım:
| Kısıt | Ne işe yarar | Bizde |
|---|---|---|
| Alıcı kapasitesi | Mağazanın deposu ve rafı sonsuz değil | var |
| Minimum koli | İki adet için kamyon kaldırılmaz | var |
| Gönderici alt sınırı | Vericiyi soymamak: elinde en az şu kadar hafta kalsın | yok |
| Stok şişme tavanı | Alıcıya taşıdıktan sonra cover’ı şu haftayı geçmesin | yok |
| Kargo/rota sayısı | Bir mağaza en çok kaç mağazaya gönderir, kaç mağazadan alır | yok |
| Maksimum koli / araç hacmi | Bir sevkiyata sığacak adet, ağırlık, hacim | yok |
| Sevkiyat takvimi | Transfer yalnız belirli günlerde, belirli hatlar üzerinden | yok |
| Bölge ve grup kuralları | “Şu iki mağaza arasında transfer olmaz”, franchise sınırları | kısmen (line kuralı) |
| Tekrar transfer soğuması | Aynı malı iki hafta üst üste oradan oraya taşımamak | var (bütün varışlar) |
| Taşıma sayısı tavanı | Bir mal sezon boyunca en çok kaç kez taşınır | yok |
Üçü özellikle sık atlanır ve atlandığında plan sahada uygulanamaz hâle gelir.
Gönderici alt sınırı. Bizim modelde blok, vericinin stoğunun tamamıdır; verici o option’da sıfıra iner. Lumoda’da bu kabul edilebilir görünüyor, çünkü verici zaten cover eşiğini aşmış, yani yavaş satan bir raf. Ama İstanbul 18’in kazağında gördük: Malatya o sekiz haftada bloğun yarısını kendisi de satabilirdi. Gerçek zincirde mağaza müdürü “benim de müşterim var” der ve haklıdır: pratikte vericide belirli bir hafta karşılığı bırakılır. Bu, bloğu bölmek demektir ve modeli sürekli miktar kararına yaklaştırır.
Stok şişme tavanı. Model alıcıya taşımayı sever, çünkü kazanç orada görünür. Ama alıcıda da bir doyma noktası vardır: sekiz haftalık talebi karşılayan mağazaya on altı haftalık mal göndermek bir sonraki haftanın ölü stoğunu üretir. Kapasite kısıtı bunu ancak kabaca engeller; asıl koruma alıcının transfer sonrası cover’ına konan üst sınırdır.
Kargo/rota sayısı. Beşinci yazıda rotaları saydık: çözücü 318, açgözlü 340 sevkiyat açıyor ve açgözlünün 268 sevkiyatı tek bir option taşımak için açılıyor. Gerçek lojistikte bu sayının bir tavanı vardır (“bir mağaza haftada en çok üç yere gönderir”). Tavanı modele yazdığınızda çözücü rotaları daha da birleştirmek zorunda kalır ve iki yöntem arasındaki fark büyür, çünkü açgözlü yöntem bu kısıtı ancak sonradan eleyerek uygulayabilir; çözücü ise plan kurarken hesaba katar.
Son bir uyarı: her yeni kısıt çözüm uzayını daraltır, yani beklenen kazancı düşürür. Bu bir kayıp değil, dürüstlüktür; kısıtsız modelin vaat ettiği para zaten uygulanamayacak bir planın parasıdır. Asıl soru “kısıt eklersem ne kaybederim” değil, “bu kısıt gerçek mi, yoksa alışkanlık mı” sorusudur.
Baştaki soru burada kapanıyor
Altı yazı önce bir mağaza müdürünün telefonuyla başladık, bir Excel dosyası ve akşam dokuzda gelen “neden bu kırkı seçtik, bilmiyorum” itirafıyla devam ettik. Sonra teraziyi kurduk, sembollere çevirdik, iki ayrı yoldan çözdük ve sonunda ikisini tarttık.
Geriye kalan tek cümle şu: bu işin zor kısmı algoritma değildi. Zor kısım, kararın nasıl verildiğini yavaş çekimde izleyip yazabilmekti. Onu yazabildiğinizde hangi yöntemi seçtiğiniz neredeyse bir detay; ve seçiminizi artık savunabiliyorsunuz 🙂
Bu listenin ilk maddesini bir sonraki yazı devralıyor: buradaki rakamlar hâlâ ciro cinsinden ve onları paraya çevirmek o yazının işi. Orada modelin kendisi hakkında da bir şey öğreneceğiz: ne varsaydığını ve verinin ne dediğini.