2 Ekim 2012

Doğrusal Programlama - Simpleks Metodu Algoritması C#


Biraz araştırdım ve eksik kaynak olduğunu düşündüğümden paylaşmak istedim. Simplex metodun algoritmasını öğrendim, sonra C# dilinde kodlayacaktım ki, birden karşıma Microsoft Solver Foundation kütüphanesi çıktı :) Hemen denedim, sonuçlar çok başarılı, lingo, lpsolve ve daha birçok solver ın kütüphaneleri ve apileri mevcut.

Gelelim programlama çözümlerine...
Zaten indirdiğinizde örnek kodlar var, C:\Users\username\Documents\Microsoft Solver Foundation\Samples
klasör dizininde.

Rastgele bir örnek oluşturalım,  maksimizasyon problemi olsun. Maksimizasyon problemim 24 saatlik dilim içerisinde Q[i] * F[i] nin maksimizasyonunu çözmeye çalışalım.
Koşullar:
Q[i] >=1.15
Q[i] <= 5.25
X[i+1] = X[i] - 2*Q[i] + 2*F[i]
olsun, (Sonuç çıkmayabilir, değerleri salladım ;)
F[i] sabit olsun, yani
F[0] = 1.00
F[1] = 1.25
F[2] = 1.15
....
F[23] = 1.45

X[0] başlangıç değerimiz 3000 olsun

başlayalım...Tabi ki en başta SimplexSolver nesnesi oluşturuyor:

SimplexSolver simplex = new SimplexSolver();

max = Qi * Fi    , i = 1,2,3...,24
burada maksimizasyonumuzun ne olduğunu tanımlıyoruz

int goal;
simplex.AddRow("goal", out goal);
for (int i = 0; i < Q.Length; i++) 
{ 
 simplex.SetCoefficient(goal, Q[i], F[i]); // max = Q[i] * F[i]
} 
simplex.AddGoal(goal, 1, false); // false = maximization, true = minimization

Eğer sabit değerlerimiz varsa, alt ve üst limitini aynı değer verilir, yoksa alt ve üst limtleri verilir.

simplex.SetBounds(X[0], 3000, 3000); // X[0] = 3000

for (int i = 0; i < 24; i++)
{
 varName = "Q" + i.ToString();
 simplex.AddVariable(varName, out Q[i]);
 simplex.SetBounds(Q[i], 1.15, 5.25);
}

X başka bir değişken ve maksimizasyon formülünün içinde yer almayan; fakat Q ya bağlı bir değer:
X[i+1] = X[i] -2* Q[i] + 2*F[i] gibiyse ve sabitimiz yoksa X[i+1] - X[i] + 2*Q[i] - 2*F[i] = 0 olarak düşünülür ya da sabitimiz varsa 0 yerine yazılır, mesela X[i+1] - X[i] + 2*Q[i]  = 2*F[i]

int[] row = new int[24];
for (int i = 0; i < 24; i++)
{        
 rowName = "row" + i.ToString();
 simplex.AddRow(rowName, out row[i]);
 simplex.SetBounds(row[i], 2 * F[i], 2 * F[i]); // >= <= ya da == olarak düşünülür
 simplex.SetCoefficient(row[i], X[i + 1], 1);
 simplex.SetCoefficient(row[i], X[i], -1);
 simplex.SetCoefficient(row[i], Q[i], 2);    
}

Buradan sonrasında problemi çözmek ve değerleri görmek istersek :


SimplexSolverParams p = new SimplexSolverParams(); 
p.UseExact = true; 
simplex.Solve(p); 
if (simplex.Result == LinearResult.Optimal) 
{
 Console.WriteLine((double)simplex.GetValue(Q[0]));
}

Umarım faydalı olmuştur, kolay gelsin...
yorumlarınızı eksik etmeyin :)

Bu Blogda Ara

İletişim

Ad

E-posta *

Mesaj *