Bir Ulaştırma Probleminin GAMS’DE Modellenmesi
Merhaba, bu haftaki yazımda yine bir doğrusal programlama modellemesi yapacağız. Geçen hafta basit bir problemin nasıl modellendiğini görmüştük. Bu hafta biraz daha karmaşık bir problem çözeceğiz. Bir ulaştırma probleminin GAMS’de nasıl modellendiğini gelin birlikte inceleyelim.
Öncelikle problemimize bir bakalım.
Problemde, Edirne, İzmir ve Bursa’da bulunan fabrikalarda üretilen ürünler Malatya ve Diyarbakır’daki depolara sevk edilecektir. Fabrikaların kapasite miktarları, depoların talep miktarları ve fabrika-depo arasındaki mesafe bilgileri (kilometre cinsinden) aşağıdaki tabloda verilmiştir. Ayrıca nakliye ücreti her ürün için kilometre başına 0,08 TL olarak belirlenmiştir.
Malatya | Diyarbakır | Kapasite | |
Edirne | 1000 | 2690 | 1000 |
İzmir | 1250 | 1350 | 1500 |
Bursa | 1275 | 850 | 1200 |
Talep | 2300 | 1400 |
Problemin Matematiksel Modeli
Problemdeki karar değişkenlerimiz fabrikalardan depolara gönderilecek ürün sayısıdır.
Xij= i. fabrikadan, j. depoya gönderilen ürün sayısı. (i=1,2,3 j=1,2)
Amacımız ise taşıma maliyetinin minimum düzeyde olmasıdır. Bu durumda amaç fonksiyonu;
MinZ= ∑i∑j cij xij
Buradaki cij i fabrikasından j deposuna taşınan ürünün birim maliyetidir. Belirlenen nakliye 0,08 TL nakliye ücretinin tabloda verilen uzaklıklar ile çarpılması ile her şehir için bulunur. Örneğin, Edirne’den Malatya’ya taşınacak bir birim ürünün taşıma ücreti 0,08*1000=80TL olur.
X11+ X12≤1000 Edirne’deki fabrikanın kapasite kısıtı.
X21+ X22≤1500 İzmir’deki fabrikanın kapasite kısıtı.
X31+ X32≤1200 Bursa’daki fabrikanın kapasite kısıtı.
X11+ X21+ X31≥2300 Malatya’daki deponun talep kısıtı
X12+ X22+ X32≥1400 Diyarbakır’daki deponun talep kısıtı
Xij≥0 (i=1,2,3 j=1,2)
Problemin GAMS’de Modellenmesi
Bu problemde geçen hafta öğrendiğimiz fonksiyonların yanı sıra yeni birkaç fonksiyon kullanacağız. Bunlardan biri “Sets” fonksiyonu. Problemdeki indisleri tanımlamak için “Sets”i kullanıyoruz.
Problemimizde iki adet indisimiz var: i ve j. i indisi fabrikaları tanımlarken, j indisi de depoları tanımlamaktadır. i1 ile Edirne’deki, i2 ile İzmir’deki, i3 ile Bursa’daki fabrikayı ifade etmekteyiz. j indisi ile Malatya(j1) ve Diyarbakır(j2)’daki depoları tanımlarız Tanımlamalar iki “/” işareti arasına virgül ile ayrılarak yapılır.

Görsele baktığımızda fabrikaları tanımalarken / i1*i3/ şeklinde bir tanımlama yapmışız. Bazı durumlarda tanımlayacağımız indisler 1’den 50, 60 a kadar, hatta daha fazla olabiliyor. Bu gibi durumlarda tüm değerleri tek tek yazmamak için”*” işaretini kullanıyoruz. Bu i1’den i3’e kadar olan değerler demek oluyor. Başka bir örnek verecek olursak, i1*i10 yazıyorsa bu; i1,i2,i3,i4,i5,i6,i7,i8,i9,i10 demek oluyor.
GAMS’de Veri Girişi
İndislerin tanımlanmasından sonra problemde verilen verileri GAMS’e aktarmamız gerekiyor. GAMS’de veri girişini birkaç farklı şekilde yapabiliriz. Bu problemde bunlardan bazılarını göreceğiz.
İlk olarak problemde verilen kapasite ve talep verilerinin tanımlamalarını yapalım. Bunun için “Parameters” fonksiyonunu kullanmamız gerekiyor. K(i), fabrikaların kapasitesini, T(j)’de depoların taleplerini temsil edecek şekilde tanımlarız.

Burada tanımlama yaparken yine “/” işareti kullanılır. Tanımlamalar yapılırken sets ile tanımladığımız indislerden yararlanırız. Edirne(i1)’deki fabrikanın kapasitesi 1000 demekle için sadece i1 1000 şeklinde yazarız. Daha sonrasında depo taleplerini yine aynı şekilde tanımlarız ve daha sonrasında tanımlamayı bitirdiğimizi gösteren “;” işaretini kullanırız.
Bu işareti bir önceki derste de kullanmıştık. Bu tanımlamamızın bittiğini ve yeni bir tanımlama satırına geçtiğimizi gösteriyor diyebiliriz.
Table Fonksiyonu
Problemimizdeki diğer veriler ise iki şehir arasındaki uzaklık. Bu verilerin girişini yapmak için tıpkı problemde verilen tablo gibi bir tablodan yardım alırız yani “Table” fonksiyonunu kullanırız.

Burada önemli noktalardan bir tanesi tablo adını tanımlanmasıdır. “d(i,j)” tablomuzun ismini temsil ediyor. Başka bir yerde bu tablodaki verileri kullanarak bir işlem yapacaksak bu adı kullanmamız gerekiyor. Tabloyu oluştururken yine sets ile tanımladığımız indislerimizi kullanıyoruz. İ1’den j1’e olan uzaklığın 1000 olduğunu görüyoruz. Yani, Edirne ile Malatya arasındaki mesafe.
Scalar Fonksiyonu
Birde problemimizde tanımlanan birim ulaştırma maliyetimiz var. Bu maliyeti tanımlarken “scalar” kullanmamız gerekiyor. Tıpkı diğer tanımlamalarda olduğu gibi burada da, tanımlamamız “/” işaretlerinin arasına yapılıyor. Ondalık sayı tanımalarken virgül değil nokta kullanabiliriz.

Burada f bizim tanımladığımız scalar’ı yani 0,08 değerini tanımlıyor. Daha sonraki işlemlerde bu değeri kullanmak için f ‘i kullanacağız.
Problemin matematiksel modelini yazarken amaç fonksiyonunda cij şeklinde bir ulaştırma maliyeti tanımlamıştık. Bu maliyet hesaplanırken, belirlenen nakliye ücreti ile uzaklıklar çarpılıyordu. Çünkü cerilen ücret kilometre başınaydı. Yapılan bu işlemi GAMS’de de tanımlamamız gerekiyor. Bu tanımlamayı “parameters” fonksiyonu yardımı ile yapabiliriz.

Yukarıdaki şekilde de görüldüğü gibi cij olarak tanımlanan bir veriyi GAMS’de c(i,j) olarak gösterdik. Bu ifadeyi parametre olarak tanımladık. Daha sonrasında bunun neyi ifade ettiğini göstermek için bir işlem tanımladık. Önceden tanımladığımız f yani birim maliyet ile, yine daha önce tanımladığımız şehirler arasındaki uzaklıkları çarptık. Dikkat ederseniz burada, daha önce de bahsedildiği üzere verileri tanımladığımız ifadeleri kullandık. Tablonun adı ve maliyetin tanımlandığı harf gibi.
Buradan sonra kullanacağımız fonksiyonlar geçen hafta öğrendiğimiz fonksiyonlar ile aynı.

Burada variables, bağımsız değişkeni tanımlamaktadır. Problemdeki bağımsız değişkenimiz z, yani amaç fonksiyonumuzdur.
Positive variables ise pozitif değişkenlerimiz yani karar değişkenlerimiz(xij). xij şeklindeki bir karar değişkeni GAMS’de x(i,j) şeklinde yazılır. Pozitif olarak tanımlanmasının sebebi ise pozitiflik kısıtının olmasıdır.
Daha sonrasında eşitliklerimizi yazarız. Geçen haftada gördüğümüz gibi eşitliklerimizi yazmadan önce “equations” fonksiyonu ile bu eşitlikleri tanımlamamız gerekiyor.

Bu hafta öğreneceğimiz yeni fonksiyonlardan bir tanesi “sum” yani toplam fonksiyonu. Hatırlarsanız geçen hafta işlem yaparken normal bir şekilde işlem işaretlerini kullanmıştık, “+”,”-“, hatta çarpım işlemi için “*” kullanıldığını söylemiştik. Bu ifadeleri kullanarak yazdığımız eşitliklere açık form deniyor. Eğer “sum” gibi fonksiyonlar kullanarak eşitlikleri yazıyorsak bu kapalı form oluyor. Bu hafta kapalı formu öğreneceğiz.
İlk olarak amaç fonksiyonunu tanımlayalım;

Z, amaç fonksiyonumuzu temsil ediyordu. Geçen haftaki yazımızda eşitliklerin GAMS’de nasıl yazıldığını öğrenmiştik. Eşittir ifadesinden sonra sum yazıp bir parantez açıyoruz. Bu parantez içerisine fonksiyonun ne yapmasını istiyorsak onu yazacağız. İkinci bir parantez daha açıyoruz ve açılan bu paranteze i,j yazıp kapatıyoruz. Bunun sebebi bu fonksiyonun hem i hemde j değerlerini kullanmasını istememiz. Sonrasında bir virgül ifadesi ekleyerek amaç fonksiyonundaki işlemi yazmamız gerekiyor. (Amaç fonksiyonu maliyetler çarpı karar değişkenleriydi.) Örneğin i=1 (Edirne) j=1 (Malatya) için ulaştırma maliyeti hesaplanacak ve bu değer x11 (Edirne’den Malatya’ya gidecek ürün sayısı) ifadesi ile çarpılacak, bu işlem tüm indisler için gerçekleşip hepsi toplanacak.
Yine aynı şekilde kısıt tanımlamalarımızda da “sum” fonksiyonunu kullandık.

Problemimizde iki tane kısıtımız vardı kapasite ve talep kısıtı. Daha öncesinde fabrikaların kapasitelerini K(i) ile depoların taleplerini de T(j) ile tanımlamıştık.
Amaç fonksiyonunu yazarken olduğu gibi sum fonksiyonunu yazdıktan sonra hangi indis için değişiklik yapacağını yazarız. İlk eşitlikte j indisini yazmışız bu da demek oluyor ki i=1 indisi için sırasıyla j=1 ve j=2 değerlerini yazıp bunların toplamını K(1) (Edirne’deki Fabrikanın kapasitesi) değerine eşitleyecek. Yani birinci fabrikanın, birinci ve ikinci depoya göndereceği ürün miktarlarının toplamı birinci fabrikanın kapasitesini geçmemeli diyoruz. Bunu her fabrika için yapıyor. Aynı şekilde depo içinde tanımlama yapıyoruz.
Tüm tanımlamalarımız tamamlandığına göre problemimizi çözdürebiliriz.

GAMS Çözüm Çıktısı

Yukarıdaki görselde “Objective Value” kısmında bize amaç fonksiyonumuzun değerini göstermiş. Ayrıca problem ile ilgili adı, türü, maksimizasyon, minimizasyon gibi özet bilgileri de görebiliyoruz.
Peki, fabrikalardan depolara gönderilen ürün sayısı ne kadar ? Bu sorunun cevabını,

listesindeki SolVAR seçeneğinden x değerini seçerek görebiliriz. Seçtikten sonra karşımıza aşağıdaki görselde görülen bölüm açılır.

Burada “Level” problemde kullanılan değişken değerlerini göstermektedir. Bu, örneğin x12 değeri için ne kullandığı anlamına gelmektedir. Lower ve Upper ise bu değerlerin alabileceği en az ve en yüksek seviyeleri göstermektedir. Görüldüğü üzere kullanılan değerlerden daha az değerler kullanılarak problem çözülemez ancak daha yüksek değerler kullanılabilir. Fakat bu durum maliyette de değişmeye neden olur. Amacımız minimum maliyet.
Sonuç olarak;
Edirne’den Malatya’ya 1000,
İzmir’den Malatya’ya 1300,
İzmir’den Diyarbakır’a 200,
Bursa’dan Diyarbakır’a 1200,
adet ürün gönderilirse minimum maliyetimiz 313.200 TL olacaktır.
Örnek Dosya’yı İndirmek için İkona Tıklayınız:
Kaynakça;
- Hamdy A. Taha, Yöneylem Araştırması.