Sonuç

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.

Gönderen mağazada asgari cover (hafta)
Alıcı mağazada azami cover (hafta)
Çözüm yöntemi
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 çift219233
Kırık seti verici yapan hareket00

İ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çütAçgözlü (SQL + döngü)Çözücü (MIP + PuLP)
Taşınan option586661
Taşınan adet99.029109.100
Açılan sevkiyat340 (268’i tek option)318 (194’ü tek option)
Net kazanç32.680.688 TL35.934.123 TL
Çözüm süresi39,7 ms54,7 sn
En iyi plana uzaklıkkendi başına ölçemezen fazla %0,18
Kayıp satış yakalama (kestirim · gerçek kayıp)%3,4 · %3,2%3,6 · %3,4
Adreslenen kırık çift219233
KurulumyokPuLP + CBC
“Neden bu hareket?” cevabıtek satıryok

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 optionNet kazançKayıp satış yakalama (kestirim · gerçek kayıp)Çözücünün durumu
verici ≥ 6 hafta · alıcı tavanı kapalı66135.934.123 TL%3,6 · %3,4toleransta, %0,18
verici ≥ 6 hafta · alıcı ≤ 3 hafta85149.627.968 TL%4,2 · %3,7limit, %1,33
verici ≥ 6 hafta · alıcı ≤ 6 hafta89559.884.561 TL%3,8 · %3,4limit, %5,24
verici ≥ 14 hafta · alıcı ≤ 6 hafta78257.529.813 TL%3,1 · %2,7limit, %1,96
verici ≥ 18 hafta · alıcı ≤ 14 hafta78758.829.811 TL%2,6 · %2,3limit, %1,71
verici ≥ 26 hafta · alıcı ≤ 6 hafta52741.922.719 TL%2,2 · %1,9toleransta, %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ıtNe işe yararBizde
Alıcı kapasitesiMağazanın deposu ve rafı sonsuz değilvar
Minimum koliİki adet için kamyon kaldırılmazvar
Gönderici alt sınırıVericiyi soymamak: elinde en az şu kadar hafta kalsınyok
Stok şişme tavanıAlıcıya taşıdıktan sonra cover’ı şu haftayı geçmesinyok
Kargo/rota sayısıBir mağaza en çok kaç mağazaya gönderir, kaç mağazadan alıryok
Maksimum koli / araç hacmiBir sevkiyata sığacak adet, ağırlık, hacimyok
Sevkiyat takvimiTransfer yalnız belirli günlerde, belirli hatlar üzerindenyok
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şımamakvar (bütün varışlar)
Taşıma sayısı tavanıBir mal sezon boyunca en çok kaç kez taşınıryok

Üçü ö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.

Yazan: Sabri Suyunu