public void ToplamUzaklikHesapla() { //rota ile yapılan toplam uzaklık değeri metre ve dakika cinsinden ikisni de hesaplar Uzaklik2 tUzaklik = new Uzaklik2(); for (int i = 0; i < ziyaretSirasi.Count - 1; i++) { Gen g1 = ziyaretSirasi[i]; Gen g2 = ziyaretSirasi[i + 1]; if (g1.hasta.hastaID == g2.hasta.hastaID) { continue; } Uzaklik2 uzaklik = Islemler.UzaklikGetir(g1.hasta.hastaID, g2.hasta.hastaID); // Uzaklik2 uzaklik = Islemler.distanceMatrix[new Tuple<int, int>(g1.hasta.hastaID, g2.hasta.hastaID)]; tUzaklik.dakika += uzaklik.dakika; //bakım zamanı mecburi bir maliyet ve değiştirilemeyeceğinden zaman maliyetine eklenmedi, aşağıdaki kod ile kolayca eklenebilir //fakat GA nın azaltma imkanının olmadığı bir değerin fitness fonksiyonunu eklimememesi için bakım durumu eklenmedi sadce yolculuk zamanı eklendi //yolculuk zamanın eklenmesindeki ana sebep ise 1,2,3 gibi bir sıralama ile 1,3,2 gibi sıralamada tesr yön de trafik sıkışıklığı yada daha çok ışık gibi sebeplerden kaçınmak tUzaklik.dakika += g1.hasta.bakimSuresi; //Tek bir deney için eklendi daha sonr akapatılacak bakim süresini de ekle tUzaklik.metre += uzaklik.metre; } _toplamUzaklik = tUzaklik; }
private void listBox2_SelectedIndexChanged(object sender, EventArgs e) { if (!Islemler.InternetVarmi()) { MessageBox.Show("Internet bağlantısında sorun var\nRotalar oluşturulur ama düzgün çizilemez"); } ListBox lb = (ListBox)sender; if (!(lb.SelectedItems.Count > 0)) { return; //seçim yoksa işlem yapma } if (secim_ga_gredy == 1) //ga ile route lar oluştu ise { int rota = lb.SelectedIndex; RouteCiz(ga.IyiList[nesil].kromozom.rotaListesi[rota], renkG, penwidth); } else if (secim_ga_gredy == 2)//gredy ile route lar oluştu ise { int rota = lb.SelectedIndex; RouteCiz(nga.rotaList[rota], renkG, penwidth); } else if (secim_ga_gredy == 3)//Yüklenen Rotadan çiziliyordur { int rota = lb.SelectedIndex; RouteCiz(Islemler.rotaLoadList[rota], renkG, penwidth); } else { return;//yukarıdaki 3 değerde seçilmemiş ise işlem yapma } }
private void SagaKaymaHesapla(int indis) { int miktar = 0; double kaymaCeza = 0; if (indis == 0 || indis == ziyaretSirasi.Count - 1) { return; //sağlık merkezi ise çık } for (int i = ziyaretSirasi.Count - 2; i >= indis; i--) //sondan 1. kayıttan başla indise kadar hesapla, son kayıt sağlık merkezi olduğundan o kayamaz { Gen gen1 = ziyaretSirasi[i]; // Gen gen2 = ziyaretSirasi[i + 1]; //gen1' in sağa kayabileceği en son nokta bulunur, bu noktadan daha sağa kayması mümkün değil //gen1 sağa doğru kaydığında gen1 den çıkış arı gen1-gen2 yolculuk süresinin g2.t1 den küçük eşit olması gerekir //formülde +miktar kısmı bir önceki adımda g2 sağa kaymış ise bu değerin dikkate alınması içindir int sonperiyod = gen2.atandigiTimeWindow.t1 - Islemler.UzaklikGetir(gen1, gen2).dakika + miktar; //kayabileceği en son nokta int maxkayma = sonperiyod - gen1.atandigiTimeWindow.t2; //sağa kayabileceği maksimum noktadır int kayma = Islemler.HastaKayabilecegiPeriyod(gen1.hasta); //hastanın sağa ne kadar esneyebileceğini bulur //kayma için hem en dipi hemde mümkün olanı hesapla hangisi daha küçük ise ancak o kadar kayabilir if (maxkayma < kayma) { kayma = maxkayma; // } kaymaCeza = (miktar * kaymaCeza + kayma * Islemler.CezaPuanlari[Cezalar.hastaIstenmeyenPeriyod] * gen1.hasta.oncelik) / (miktar + kayma); miktar = kayma;//kayan miktar toplama eklendi } sagaKayma.miktar = miktar; sagaKayma.kaymaCeza = kaymaCeza; }
private void SolaKaymaHesapla(int indis) { int miktar = 0; double kaymaCeza = 0; if (indis == 0 || indis == ziyaretSirasi.Count - 1) { return; //sağlık merkezi ise çık } for (int i = 1; i <= indis; i++) //1 den başlamasının sebebi 0 da sağlık merkezi var { Gen gen1 = ziyaretSirasi[i - 1]; // Gen gen2 = ziyaretSirasi[i]; //gen2' nin sola en fazla kayabileceği dip nokta bulunuyor, bu noktadan daha sola kayması mümkün değil //gen1 t2+aradaki uzaklık değeri olarak hesaplandı fakat kayma buraya kadar yapılamayabilir //formüldeki -miktar işlemi eğer solundaki daha önce sola kaydırılmış ise bunu da dikkate alır. int dipperiyod = gen1.atandigiTimeWindow.t2 + Islemler.UzaklikGetir(gen1, gen2).dakika - miktar; //kayabileceği en erken konta int dipkayma = gen2.atandigiTimeWindow.t1 - dipperiyod; //kayma miktarıdır. int kayma = Islemler.HastaKayabilecegiPeriyod(gen2.hasta); //hastanın sola ne kadar esneyebileceğini bulur -miktar işlemi önceki kaymayı da dahil etmek için //kayma için hem en dipi hemde mümkün olanı hesapla hangisi daha küçük ise ancak o kadar kayabilir if (dipkayma < kayma) { kayma = dipkayma; // } kaymaCeza = (miktar * kaymaCeza + kayma * Islemler.CezaPuanlari[Cezalar.hastaIstenmeyenPeriyod] * gen2.hasta.oncelik) / (miktar + kayma); miktar = kayma;//kayan miktar toplama eklendi } solaKayma.miktar = miktar; solaKayma.kaymaCeza = kaymaCeza; }
private void Form1_Load(object sender, EventArgs e) { Islemler.CezaPuanlariniBelirle(); this.WindowState = FormWindowState.Maximized; Islemler.gunID = 1; //ay_gün_yıl var distancematr = Islemler.distanceMatrix; List <Ekip> ekiplist = Islemler.ekipListGun; List <Hasta> hastalist = Islemler.hastaListGun; // MarkerEkleHepsi(Islemler.gunID); HaritaKonumlan(); GunDoldur(comboBox2); ilkAtamaDoldur(comboBox1); // Islemler.HastaEkipYule("01.01.2019"); // Islemler.tarih = "03.01.2019"; //distancematr = Islemler.distanceMatrix; //Uzaklik u1 = distancematr[new Tuple<int, int>(hastalist[0].hastaID, hastalist[1].hastaID)]; }
private void buttonGuncelle_Click(object sender, EventArgs e) { try { int dakika = Int32.Parse(textDakika.Text); int metre = Int32.Parse(textMetre.Text); int hastaPeriyod = Int32.Parse(textHastaZaman.Text); int ekipPeriyod = Int32.Parse(textEkipZaman.Text); int skill = Int32.Parse(textHastaPersonelSkill.Text); int ekipFazlaMesai = Int32.Parse(textEkipFazlaMesai.Text); int ekipOgleArasi = Int32.Parse(textEkipOgleArasi.Text); int sapmaMetre = Int32.Parse(textEkipMesafeSapma.Text); int sapmaDakika = Int32.Parse(textEkipZamanSapma.Text); Islemler.CezaPuanlariniBelirle(dakika, metre, hastaPeriyod, ekipPeriyod, skill, ekipFazlaMesai, ekipOgleArasi, sapmaMetre, sapmaDakika); MessageBox.Show("GA ceza değerleri güncellendi"); this.Close(); } catch { MessageBox.Show("Ceza değerleri tamsayı olmalıdır"); } }
public void AtamalariYap() { //ekip seç ekipe ait rotayı doldur sonra bu ekibi sil, diğer ekibi seç while (_ekipList.Count > 0 && _hastaList.Count > 1) //while ya hasta listesi biterse yada ataacak ekip kalmaz ise boşalır { Ekip secilenekip = EkipSec(); //en uygun ekibi seçer Rota myrota = new Rota(); //yeni bir rota başlattı myrota.ekip = secilenekip; //rotanın ekibi atandı if (myrota.ekip == null) { break; //programda runtime de bir hata olup ekip seçilemez ise kırılmasın diy eeklendi: algoritmaya bir etkisi yok } //ekip rotaya atandığı için rota başlangıç ve bitiş periyodları ekibe ait zaman periyodları olarak ayarlanıyor myrota.ziyaretSirasi[0].atandigiTimeWindow.t1 = secilenekip.sabahMesai.t1; //başlangıç noktası myrota.ziyaretSirasi[0].atandigiTimeWindow.t2 = secilenekip.sabahMesai.t1; myrota.ziyaretSirasi[myrota.ziyaretSirasi.Count - 1].atandigiTimeWindow.t1 = secilenekip.ogleMesai.t2; //bitiş noktası myrota.ziyaretSirasi[myrota.ziyaretSirasi.Count - 1].atandigiTimeWindow.t2 = secilenekip.ogleMesai.t2; int periyod = myrota.ekip.sabahMesai.t1; //rota için başlangıç periyodu, ekibin sabah mesai başlangıcı int nokta = 0; //rota başlangıç noktası her zaman 0. nokta, 0 sağlık merkezi bool ziyaretedilebilirvarmi = true; int saglikmerkezi = 0; Hasta eskihasta = _hastaList[nokta]; while (ziyaretedilebilirvarmi) //seçilen ekip için uygun noktaları bularak gredy olarak atamalar yapacak { ziyaretedilebilirvarmi = false; //ziyaret edilebilir nokta bulamaz ise false kalsın diye güncellendi Hasta kararverilenhasta = null; int fark = Islemler.M; //fark değeri başlangıcta büyük bir değer alındı int t1 = 0; //atama yapılacak zç1 değeri int t2 = 0; //zç2 int atamaicint1 = 0; int atamaicint2 = 0; //aşağıdaki for tüm hasta listesini dolaşarak atama için en uygun hastayı bulur // atanabilecek hasta bulursa ziyaretedilebilirvarmı true olur for (int j = 1; j < _hastaList.Count; j++)//hasta listesi-1 kadar döngü ile mevcut hastalar taranıyor { Hasta yenihasta = _hastaList[j]; if (eskihasta == yenihasta) { continue; //aynı hasta için işlem yapmamalı } int eskihastayenihastauzaklik = Islemler.UzaklikGetir(eskihasta.hastaID, yenihasta.hastaID).dakika; int yenihastasaglikmerkeziuzaklik = Islemler.UzaklikGetir(yenihasta.hastaID, saglikmerkezi).dakika; int m1 = periyod + eskihastayenihastauzaklik + yenihasta.bakimSuresi; int m2 = m1 + yenihastasaglikmerkeziuzaklik; //son noktadan sonra sağlık merkezine gidilebiliyormu bool skillyeterli = (myrota.ekip.skill & yenihasta.skill) == yenihasta.skill; //skill ziayaret için yeteliyse true, değilse false if (periyod + eskihastayenihastauzaklik > yenihasta.timeWindow.t1) //yeni hasta ziyaretinin başlaması gereken t1 değeri { t1 = periyod + eskihastayenihastauzaklik; } else { t1 = yenihasta.timeWindow.t1; } t2 = t1 + yenihasta.bakimSuresi; //yeni hasta t2 zamanı, hasta ziyaretinin bittiği time windows bool mesaisarkmasiyok = !myrota.MesaiSarkmasiVar2(t1, t2); //rotada bu t1, t2 atamasında mesai sarkması varmı bakılıyor, dönen değer değillendi if (skillyeterli && mesaisarkmasiyok && m1 <= yenihasta.timeWindow.t2 && m2 <= myrota.ekip.ogleMesai.t2) { //koşul sağlanmış ise ziyaret edilebilece bir hasta noktası var demektir. bu duurmda farklara bakılacak ziyaretedilebilirvarmi = true; //ziyaret edilebilir bir nokta bulunduğundan true, hiç nokta bulamaz ise false olarak kalmaya devam edecek int yenifark = yenihasta.timeWindow.t1 - (periyod + eskihastayenihastauzaklik); //bu formül ekibin en az bekleme yapacağı hastayı seçer eğer negatif ise hasta ziyareti hasta zç1 başladıkatn sonra başlayacaktır if (yenifark < fark) { fark = yenifark; kararverilenhasta = yenihasta; nokta = j;//en düşük farka sahip olan noktayı bulmak için fark değei küçüldüğünde nokta güncelleniyor atamaicint1 = t1; atamaicint2 = t2; } } } if (ziyaretedilebilirvarmi) //rotaya yeni bir hasta daha eklenebilir mi? { //****burada nokta değerine ait hastayı rotaya ekle**** myrota.YeniNoktaEkleAraya(myrota.ziyaretSirasi.Count - 1, kararverilenhasta, atamaicint1, atamaicint2);//fark değiri en düşük olan hasta rotaya eklendi myrota.KaydirmaUygula(); periyod = atamaicint2; //t2 de yeni yapılan ziyaretin bitişi var eskihasta = kararverilenhasta; _hastaList.Remove(kararverilenhasta); //hasta rotaya eklendiği için ziyaret listesinden çıkarıldı // i = nokta;//arama başlangıç için yeni i değeri nokta oldu } else { //ziyaret edilebilecek hasta bulunamadı demektir //bu durumda son rota için artık yeni hasta eklenemez anlamına gelir //bu rota rotalistesine eklenecek //seçilen ekip ekip listten silinecek _rotaList.Add(myrota); //myrota için artık atanacak yeni hasta yok demektir _ekipList.Remove(secilenekip); //myrota için belirlenen ekip için atanacak yeni hasta yok tekrar seçilmemesi çin listeden silindi } } myrota.ToplamUzaklikHesapla(); } }
public void AtamalariYap_onceki2() { //daha önce yazılmıştı artık kullanılmıyor //ekip seç ekipe ait rotayı doldur sonra bu ekibi sil, diğer ekibi seç while (_ekipList.Count > 0 && _hastaList.Count > 1) { Ekip secilenekip = EkipSec(); //en uygun ekibi seçer Rota myrota = new Rota(); //yeni bir rota başlattı myrota.ekip = secilenekip; //rotanın ekibi atandı int periyod = myrota.ekip.sabahMesai.t1; //rota için başlangıç periyodu, ekibin sabah mesai başlangıcı int nokta = 0; //rota başlangıç noktası her zaman 0. nokta, 0 sağlık merkezi int i = 0; //hasta listesindeki ilk hasta Id si bool ziyaretedilebilirvarmi = true; while (ziyaretedilebilirvarmi) //seçilen ekip için uygun noktaları bularak gredy olarak atamalar yapacak { ziyaretedilebilirvarmi = false; //ziyaret edilebilir nokta bulamaz ise false kalsın diye güncellendi int fark = Islemler.M; //fark değeri başlangıcta büyük bir değer alındı int t1 = 0; //atama yapılacak zç1 değeri int t2 = 0; //zç2 //aşağıdaki for tüm hasta listesini dolaşarak atama için en uygun hastayı bulur // atanabilecek hasta bulursa ziyaretedilebilirvarmı true olur for (int j = 1; j < _hastaList.Count; j++)//hasta listesi-1 kadar döngü ile mevcut hastalar taranıyor { if (i == j) { continue; //en son hasta } int m1 = periyod + Islemler.UzaklikGetir(_hastaList[i].hastaID, _hastaList[j].hastaID).dakika + _hastaList[j].bakimSuresi; int m2 = m1 + Islemler.UzaklikGetir(_hastaList[j].hastaID, _hastaList[0].hastaID).dakika; //son noktadan sonra sağlık merkezine gidilebiliyormu bool skillyeterli = (myrota.ekip.skill & _hastaList[j].skill) == _hastaList[j].skill; //skill ziayaret için yeteliyse true, değilse false bool mesaisarkmasiyok = !myrota.MesaiSarkmasiVar(t1, t2); //rotada bu t1, t2 atamasında mesai sarkması varmı bakılıyor, dönen değer değillendi if (skillyeterli && mesaisarkmasiyok && m1 < _hastaList[j].timeWindow.t2 && m2 < myrota.ekip.ogleMesai.t2) { //koşul sağlanmış ise ziyaret edilebilece bir hasta noktası var demektir. bu duurmda farklara bakılacak ziyaretedilebilirvarmi = true; //ziyaret edilebilir bir nokta bulunduğundan true, hiç nokta bulamaz ise false olarak kalmaya devam edecek int yenifark = _hastaList[j].timeWindow.t1 - (periyod + Islemler.UzaklikGetir(_hastaList[i].hastaID, _hastaList[j].hastaID).dakika); if (yenifark < fark) { fark = yenifark; nokta = j; //en düşük farka sahip olan noktayı bulmak için fark değei küçüldüğünde nokta güncelleniyor if (m1 > _hastaList[j].timeWindow.t1) //ziyaret edilecek hastaya ulaşıldığında ziyaret başlayacak { t1 = m1; //eğer hastaya ulaşma zamanı ile hastanın istediği zç1 kıyaslayarak büyük olanını seçiyor } else { t1 = _hastaList[j].timeWindow.t1; //eğer hastaya ulaşma zamanı t1 den önce ise ziyaret t1 de başlayacak, bu durumda ekip beklemiş sayılır } t2 = t1 + _hastaList[j].bakimSuresi; //ziyaret bitişi için gereken t2 zamanı, t2=t1+bakim } } } if (ziyaretedilebilirvarmi) //rotaya yeni bir hasta daha eklenebilir mi? { //****burada nokta değerine ait hastayı rotaya ekle**** myrota.YeniNoktaEkleAraya(myrota.ziyaretSirasi.Count - 1, _hastaList[nokta], t1, t2); //fark değiri en düşük olan hasta rotaya eklendi periyod = t2; //t2 de yeni yapılan ziyaretin bitişi var _hastaList.RemoveAt(nokta); //hasta rotaya eklendiği için ziyaret listesinden çıkarıldı i = nokta; //arama başlangıç için yeni i değeri nokta oldu } else { //ziyaret edilebilecek hasta bulunamadı demektir //bu durumda son rota için artık yeni hasta eklenemez anlamına gelir //bu rota rotalistesine eklenecek //seçilen ekip ekip listten silinecek _rotaList.Add(myrota); //myrota için artık atanacak yeni hasta yok demektir _ekipList.Remove(secilenekip); //myrota için belirlenen ekip için atanacak yeni hasta yok tekrar seçilmemesi çin listeden silindi } } } if (_hastaList.Count <= 1) { MessageBox.Show("atamalar tamam"); } else { MessageBox.Show("atamalar yapılamadı"); } }
public void AtamalariYap_onceki() { //ekip seç ekipe ait rotayı doldur sonra bu ekibi sil, diğer ekibi seç bool atamalartamam = false; while (true) { Ekip secilenekip = EkipSec(); Rota myrota = new Rota(); myrota.ekip = secilenekip; int periyod = myrota.ekip.sabahMesai.t1; int nokta = 0; //rota başlangıç noktası her zaman 0. nokta, 0 sağlık merkezi int i = 0; //hasta listesindeki ilk hasta Id si bool ziyaretedilebilirvarmi = false; int fark = Islemler.M; int t1 = 0; //zç1 int t2 = 0; //zç2 //aşağıdaki for tüm hasta listesini dolaşarak atama için en uygun hastayı bulur // atanabilecek hasta bulursa ziyaretedilebilirvarmı true olur for (int j = 1; j < _hastaList.Count; j++) { int m1 = periyod + Islemler.UzaklikGetir(_hastaList[i].hastaID, _hastaList[j].hastaID).dakika + _hastaList[j].bakimSuresi; int m2 = m1 + Islemler.UzaklikGetir(_hastaList[j].hastaID, _hastaList[0].hastaID).dakika; if (m1 > _hastaList[j].timeWindow.t1) //ziyaret edilecek hastaya ulaşıldığında ziyaret başlayacak { t1 = m1; //eğer hastaya ulaşma zamanı t1(ZÇ1) den daha sonra ise } else { t1 = _hastaList[j].timeWindow.t1; //eğer hastaya ulaşma zamanı t1 den önce ise ziyaret t1 de başlayacak } t2 = t1 + _hastaList[j].bakimSuresi; //ziyaret bitişi gereken t2 zamanı, t2=t1+bakim bool skillyeterli = (myrota.ekip.skill & _hastaList[j].skill) != _hastaList[j].skill; bool mesaisarkmasiyok = !myrota.MesaiSarkmasiVar(t1, t2); //rotada bu t1, t2 atamasında mesai sarkması varmı bakılıyor, dönen değer değillendi if (skillyeterli && mesaisarkmasiyok && m1 < _hastaList[j].timeWindow.t2 && m2 < myrota.ekip.ogleMesai.t2) { ziyaretedilebilirvarmi = true; int yenifark = _hastaList[j].timeWindow.t1 - (periyod + Islemler.UzaklikGetir(i, _hastaList[j].hastaID).dakika); if (yenifark < fark) { fark = yenifark; nokta = j;//nokta dizinin indisi bu indissteki değeri rotaya eklemek gerek } } } if (ziyaretedilebilirvarmi) //rotaya yeni bir hasta daha eklenebilir mi? { //****burada nokta değerine ait hastayı rotaya ekle**** myrota.YeniNoktaEkleAraya(myrota.ziyaretSirasi.Count - 1, _hastaList[nokta], t1, t2); if (_hastaList[i].timeWindow.t1 > periyod + Islemler.UzaklikGetir(_hastaList[i].hastaID, _hastaList[nokta].hastaID).dakika) { periyod = _hastaList[i].timeWindow.t1; } else { periyod = periyod + Islemler.UzaklikGetir(_hastaList[i].hastaID, _hastaList[nokta].hastaID).dakika; } _hastaList.RemoveAt(nokta); //hasta rotaya eklendiği için listeden çıkarıldı i = nokta; //arama başlangıç için yeni i değeri nokta oldu } else { //ziyaret edilebilecek hasta bulunamadı demektir //bu durumda son rota için artık yeni hasta eklenemez anlamına gelir //bu rota rotalistesine eklenecek //seçilen ekip ekip listten silinecek //eğer hala listede hasta varsa count>1 (0 nolu hasta sağlık merkezi o silinmiyor), while dönmeye devam edecek _rotaList.Add(myrota); //myrota için artık atanacak yeni hasta yok demektir _ekipList.Remove(secilenekip); //myrota için belirlenen ekip için atanacak yeni hasta yok tekrar seçilmemesi çin listeden silindi //atanacak hasta yoksa count=1 atama tamamlanmış demektir break ile çıkılır //atanacak hasta kaldıysa fakat ekiplist te ekip kalmadıyda atamalar başarılamamış demektir break ile çıkılır //atanacak hasta varsa fakat ekiplistte ekip varsa yeni rota başlatılır, üstteki 2 durum değilse bu duurmdur if (_hastaList.Count <= 1) { atamalartamam = true; break;//while kırıldı } if (_hastaList.Count > 1 && _ekipList.Count == 0) { atamalartamam = false; break;//while kırıldı atamalar tamamlanamadı } //akış buraya gelmiş ise while dönmeye devam eder } } if (atamalartamam) { MessageBox.Show("atamalar tamam"); } else { MessageBox.Show("atamalar yapılamadı"); } }
public void EkipCezaGuncelle(Rota rota) { /* ************ Yazması çok zahmetli bir yordam, değişiklik yapılacaksa dikkatli incele * eğer yavaş çalışmaya sebep olursa döngü yapısındki ifelse yapılarını elden geçir * Ekibe atanan ziyaret noktalarını tarayarak hatalı ve * istenmeyen noktaları cezalandırır, * fazla mesasi * istenmeyen periyod * öğle arası ihlaline bakar */ if (rota.ziyaretSirasi.Count <= 2)//rotada hasya yok demektir { return; } int fazlamesai = 0; int oglearasiihlali = 0; Gen ilkZiyaret = rota.ziyaretSirasi[1]; //ilk nokta Gen sonZiyaret = rota.ziyaretSirasi[rota.ziyaretSirasi.Count - 2]; //sonZiyaret nokta bool sabahmesaisivar = false; if (this.sabahMesai.t2 - sabahMesai.t1 > 0) { sabahmesaisivar = true; } bool oglemesaisivar = false; if (this.ogleMesai.t2 - ogleMesai.t1 > 0) { oglemesaisivar = true; } /* * ilk hasta ziyaretinin mesai başlamdan önce planlanması durumunu kontrol ediyor * aşağıdaki ilk if eğer ilk hasta sabah mesaisinde ise, * else if ise eğer ilk hasta öğle mesaisinde ise çalışır. * else if olaki ekibin hiç sabah mesaisi yoksa gideceği ilk hastanın öğle mesaisinden sonra olması gerekir * else if in çalışması için hastanın sabah mesaisini pas geçmesi gerek */ if (sabahmesaisivar && (this.sabahMesai.t1 + Islemler.UzaklikGetir(0, ilkZiyaret.hasta.hastaID).dakika > ilkZiyaret.atandigiTimeWindow.t1)) { fazlamesai += this.sabahMesai.t1 + Islemler.UzaklikGetir(0, ilkZiyaret.hasta.hastaID).dakika - ilkZiyaret.atandigiTimeWindow.t1; } else if (oglemesaisivar && (this.ogleMesai.t1 + Islemler.UzaklikGetir(0, ilkZiyaret.hasta.hastaID).dakika > ilkZiyaret.atandigiTimeWindow.t1)) { fazlamesai += this.ogleMesai.t1 + Islemler.UzaklikGetir(0, ilkZiyaret.hasta.hastaID).dakika - ilkZiyaret.atandigiTimeWindow.t1; } /* * son hasta ziyaretinin mesai bittikten sonra planlanması durumu * aşağığıdaki if, if else yukarıdaki yapıya benzer burada son ziyaret için mesai bitişi kontrol edildi * öğle mesaisi yoksa son hastanın sabah son mesai saatini aşmaması gerekir */ if (oglemesaisivar && (sonZiyaret.atandigiTimeWindow.t2 + Islemler.UzaklikGetir(sonZiyaret.hasta.hastaID, 0).dakika > this.ogleMesai.t2)) { fazlamesai += sonZiyaret.atandigiTimeWindow.t2 + Islemler.UzaklikGetir(sonZiyaret.hasta.hastaID, 0).dakika - this.ogleMesai.t2; } else if (sabahmesaisivar && (sonZiyaret.atandigiTimeWindow.t2 + Islemler.UzaklikGetir(sonZiyaret.hasta.hastaID, 0).dakika > this.sabahMesai.t2)) { fazlamesai += sonZiyaret.atandigiTimeWindow.t2 + Islemler.UzaklikGetir(sonZiyaret.hasta.hastaID, 0).dakika - this.sabahMesai.t2; } /* * ziyaret öğle arasına sarkmış ise * öğle arasına sarkmada 4 durum var, her durum ayrı bir if,ile değerlendirilecek * 1) ziyaret.t1<oglearası.t1 AND ziyaret.t2> between oglearası * 2) ziyaret.t1 between öğlearası AND ziyaret.t2>Öğlearası.t2 * 3) ziyaret.t1 between öglearası AND ziyaret.t2 between öglearası * 4) ziyaret.t1<oglerası.t1 AND ziyaret.t2>oglearası.t2 */ int oa_t1 = this.sabahMesai.t2; //ekibin öğle arası başlangıcı int oa_t2 = this.ogleMesai.t1; //ekibin öğle arası bitişi for (int i = 1; i < rota.ziyaretSirasi.Count - 1; i++) //ziyaret sırasındaki hastalara bakar ilk ve son hasta ya bakmaz sağlık merkezi { Gen g1 = rota.ziyaretSirasi[i]; //i. hasta Gen g2 = rota.ziyaretSirasi[i + 1]; int zi_t1 = rota.ziyaretSirasi[i].atandigiTimeWindow.t1; //ziyaret.t1 int zi_t2 = rota.ziyaretSirasi[i].atandigiTimeWindow.t2; int dakika = Islemler.UzaklikGetir(rota.ziyaretSirasi[i], rota.ziyaretSirasi[i + 1]).dakika; //i, i+1 arasındaki uzaklığın dakika cinsinden değeri if (zi_t1 >= oa_t1 && zi_t1 <= oa_t2 && zi_t2 + dakika > oa_t2) //2.durum { oglearasiihlali += oa_t2 - zi_t1; break; //ziyaret öğle arasını geçtiğine göre dögünn devamı na gerek yok } else if (zi_t1 <= oa_t1 && zi_t2 >= oa_t2) //4.durum { oglearasiihlali += oa_t2 - oa_t1; break; //ziyaret öğle arasını geçtipine göre döngünün devamına gerek yok } else if (zi_t1 <= oa_t1 && zi_t2 + dakika > oa_t1) //1.durum (zi_t1 <= oa_t1 && zi_t2 + dakika > oa_t1 && zi_t2 + dakika <= oa_t2) { oglearasiihlali += zi_t2 + dakika - oa_t1; } else if (zi_t1 >= oa_t1 && zi_t1 <= oa_t2 && zi_t2 + dakika >= oa_t1 && zi_t2 + dakika <= oa_t2) //3.durum { oglearasiihlali += zi_t2 + dakika - zi_t1; } } _ekipCeza = fazlamesai * Islemler.CezaPuanlari[Cezalar.ekipFazlaMesaiPeriyod] + oglearasiihlali * Islemler.CezaPuanlari[Cezalar.oglearasiihlali]; }
private bool SagaKaydir(int konum, int kaymamiktari) { //Önceki atamaları sola doğru kaydırmaya çalışır eğer kaydırma işlemi başarılı olacaksa //geriye true değer döner. //burada amaçi 0[0,0]-1[40,70]-0[540-540] gibi bir ziyaret için 1 nolu hastayı eğer mümkün ise sola doğru kaydırmaktır //hasta zaman çerçevesi bozulmuyor ise sola kaydırmaya izin verilebilir. //kodlar iteratif yazıldı, recursive yazılsa daha kolay yazılırdı ama iteratif olan kod recursive göre daha az bellek kullanır bool kayabilir = false; int nokta1 = konum; int nokta2 = konum; while (true) { //kayamaması için 2 ihtimal var //1 kayma işlemi salık merkezine kadar kalmıştır, sağlıkmerkezi bakımı 0 olduğundan kayma yapılamaz //2 kayması istenen geni kullanan hastanın timewindovu kayma işlemini karşılamıyordur. Gen gen1 = ziyaretSirasi[nokta1]; if (gen1.hasta.hastaID == 0)//0. konuma kadar gelmiş isek 0. konumasla kayamayacağından false olur { kayabilir = false; break; } nokta2 = nokta1 + 1; Gen gen2 = ziyaretSirasi[nokta2]; if (gen1.atandigiTimeWindow.t2 + kaymamiktari > gen1.hasta.timeWindow.t2 + Islemler.HastaKayabilecegiPeriyod(gen1.hasta.oncelik)) { //yukarıdaki if kayamama durumunu kontrol eder //bu koşul gerçekleş miş ise hasta izin verilen time window dışına kayıyordur izin verme kayabilir = false; break; } //kayma yapılabilecek durumda ise kod burada //kyenikayma mikkari eğer 0 veya daha küçük ise soldaki diğer genlerin kaymasına gerek kalmadan kayma tamamlandı int yenikaymamikari = kaymamiktari - (gen2.atandigiTimeWindow.t1 - (gen1.atandigiTimeWindow.t2 + Islemler.UzaklikGetir(gen1, gen2).dakika)); gen1.sagakaymaperiyod = kaymamiktari; if (yenikaymamikari <= 0) { //ilgili gen kaydığı halde soldaki diğer genlerin kaymasına gerek kalmamış ise kayma işlemi tamamlanmıştır kayabilir = true; break; } kaymamiktari = yenikaymamikari; //algoritma tekrar başa döneceğinden yeni kayma miktarı güncellendi nokta1 = nokta2; //noktalar bir sola doğru kaydırıldı } if (kayabilir) { for (int i = konum; i < nokta2; i++) //kayması için işaretlenen genler sağa doğru kaydırıldı { ziyaretSirasi[i].atandigiTimeWindow.t2 += ziyaretSirasi[i].sagakaymaperiyod; ziyaretSirasi[i].atandigiTimeWindow.t1 += ziyaretSirasi[i].sagakaymaperiyod; } } return(kayabilir); }