private void btnHastaEkle_Click(object sender, EventArgs e) { DateTime DogumTarihi = dateDogumTar.Value; Hasta hasta = new Hasta { Adi = txtAdi.Text, Ucret = Convert.ToInt32(txtUcret.Text), DogumYili = DogumTarihi.Year, Cinsiyet = cmbCinsiyet.Text, }; hasta.YasHesapla(); hasta.IndirimliUcretHesapla(); dataGridView1.Rows.Add(hasta.Adi, hasta.DogumYili, hasta.Cinsiyet, hasta.Ucret, hasta.yas, hasta.IndirimliUcret); }
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(); } }
private void HastaAtamasiYapBestFitPeriyod(List <int> myHastaList) { atanacakhastalar.Clear(); if (myHastaList == null || myHastaList.Count == 0) //herhangi bir hasta listesi gelmemiş işe hepsi atanacak { foreach (Hasta hasta in Islemler.hastaListGun) { if (hasta.hastaID == 0) { continue; // sağlık merkezini atama } int konum; for (konum = 0; konum < atanacakhastalar.Count; konum++) //atama olasılığına göre liste yapıyor baştaki hastaların olasılığı daha yüksek { if (hasta.oncelik * hasta.bakimSuresi / (hasta.timeWindow.t2 - hasta.timeWindow.t1) > atanacakhastalar[konum].oncelik * atanacakhastalar[konum].bakimSuresi / (atanacakhastalar[konum].timeWindow.t2 - atanacakhastalar[konum].timeWindow.t1)) { break;//konum uygun yere gelmiş ise for kırılır } } atanacakhastalar.Insert(konum, hasta);//hasta atanma olasılığına göre uygun bir yere yerleştirildi } } //else //atanacak hastalistesi dışarıdan gödnerilmiş ise // foreach (Hasta hasta in Islemler.hastaListGun) // { // if (hasta.hastaID == 0) continue;// sağlık merkezini atama // int konum=0;//değer içerideki for döngüsünde değişiyor // foreach(int hastaID in myHastaList) // if(hastaID==hasta.hastaID) // for (konum = 0; konum < atanacakhastalar.Count; konum++) //atama olasılığına göre liste yapıyor baştaki hastaların olasılığı daha yüksek // { // if (hasta.oncelik * hasta.bakimSuresi / (hasta.timeWindow.t2 - hasta.timeWindow.t1) > atanacakhastalar[konum].oncelik * atanacakhastalar[konum].bakimSuresi / (atanacakhastalar[konum].timeWindow.t2 - atanacakhastalar[konum].timeWindow.t1)) // break;//konum uygun yere gelmiş ise for kırılır // } // atanacakhastalar.Insert(konum, hasta);//hasta atanma olasılığına göre uygun bir yere yerleştirildi // } else //atanacak hastalistesi dışarıdan gödnerilmiş ise { foreach (int hastaID in myHastaList) { Hasta hasta = null; for (int i = 0; i < Islemler.hastaListGun.Count; i++) { if (Islemler.hastaListGun[i].hastaID == hastaID) { hasta = Islemler.hastaListGun[i]; break;//hasta bilgisi bulundu } } int konum; for (konum = 0; konum < atanacakhastalar.Count; konum++) //atama olasılığına göre liste yapıyor baştaki hastaların olasılığı daha yüksek { if (hasta.oncelik * hasta.bakimSuresi / (hasta.timeWindow.t2 - hasta.timeWindow.t1) > atanacakhastalar[konum].oncelik * atanacakhastalar[konum].bakimSuresi / (atanacakhastalar[konum].timeWindow.t2 - atanacakhastalar[konum].timeWindow.t1)) { break;//konum uygun yere gelmiş ise for kırılır } } atanacakhastalar.Insert(konum, hasta);//hasta atanma olasılığına göre uygun bir yere yerleştirildi } } CryptoRandom rnd = new CryptoRandom(); Rota atanacagirota; while (atanacakhastalar.Count != 0) { int rnd1 = rnd.Next(0, atanacakhastalar.Count); //0-count-1 aralığında üretir int rndhasta = rnd.Next(0, rnd1 + 1); //liste başındaki bireylerin seçilme şansını arttırmak için ilk seçilen değer ile 0 arasında yeni bir konum Hasta secilenHasta = atanacakhastalar[rndhasta]; List <int> atanabilecekrotalar = new List <int>(); for (int i = 0; i < rotaListesi.Count; i++) { atanabilecekrotalar.Add(i); } bool atadim = false; while (atanabilecekrotalar.Count != 0) { int rndrota = rnd.Next(0, atanabilecekrotalar.Count); atanacagirota = _rotaListesi[rndrota]; //atanması için rastgele rota seçildi atadim = atanacagirota.AtamaYap(secilenHasta); //hasta rotaya atanmış ise true döner if (atadim) { break; //rotaya atanmış ise while ı kır } atanabilecekrotalar.RemoveAt(rndrota); //rotaya atanamadı ise o rotayı sil diğer rotlara bak } if (!atadim) //hasta herhangi bir rotaya atanmadıysa { atanamayanhastalar.Add(secilenHasta); return; //herhangi bir hasta rotaya atanamadıysa diğerlerine bakmak gereksiz } atanacakhastalar.RemoveAt(rndhasta); //seçilen hastayı tekrar atamasın diye listeden çıkar } }
private void HastaAtamasiYapBestFitEkip(List <int> myHastaList) { atanacakhastalar.Clear(); if (myHastaList == null || myHastaList.Count == 0) //herhangi bir hasta listesi gelmemiş işe hepsi atanacak { foreach (Hasta hasta in Islemler.hastaListGun) { if (hasta.hastaID == 0) { continue; // sağlık merkezini atama } atanacakhastalar.Add(hasta); } } else //atama yapılacak hasta listesi dışarıdan gönderildi ise sadece o hastalar için atama yapacak { foreach (Hasta hasta in Islemler.hastaListGun) { if (hasta.hastaID == 0) { continue; // sağlık merkezini atama } foreach (int hastaID in myHastaList) { if (hastaID == hasta.hastaID) { atanacakhastalar.Add(hasta); } } } } //burada atanması gereken hasta listesi elde edildi, aşağıda bu listedeki hastaların ataması yapılacak CryptoRandom rnd = new CryptoRandom(); int deger = 1; for (int s = 0; (atanacakhastalar.Count != 0 && s < hastaskilldongu); s++) { List <Hasta> altlist = new List <Hasta>(); int i = 0; while (i < atanacakhastalar.Count) { Hasta myhasta = atanacakhastalar[i]; int hastaskill = myhasta.skill; if ((hastaskill & deger) == deger)//hasta skill değer ile AND yapıldı { altlist.Add(myhasta); atanacakhastalar.RemoveAt(i); } else { i++;//kayıt silinirse bir geri geleceğinden sadece silmediğimizde artacak } } deger *= 2; while (altlist.Count > 0) { List <int> atanabilecekrotalar = new List <int>(); for (int j = 0; j < rotaListesi.Count; j++) { atanabilecekrotalar.Add(j); } bool atadim = false; Rota atanacagirota; int rndhasta = rnd.Next(0, altlist.Count);//0-count-1 aralığında üretir Hasta secilenHasta = altlist[rndhasta]; while (atanabilecekrotalar.Count != 0) { int rndrota = rnd.Next(0, atanabilecekrotalar.Count); atanacagirota = _rotaListesi[rndrota]; //atanması için rastgele rota seçildi atadim = atanacagirota.AtamaYap(secilenHasta); //hasta rotaya atanmış ise true döner if (atadim) { break; //rotaya atanmış ise while ı kır } atanabilecekrotalar.RemoveAt(rndrota); //rotaya atanamadı ise o rotayı sil diğer rotlara bak } if (!atadim) //hasta herhangi bir rotaya atanmadıysa { atanamayanhastalar.Add(secilenHasta); return; //herhangi bir hasta rotaya atanamadıysa diğerlerine bakmak gereksiz } altlist.RemoveAt(rndhasta); //seçilen hastayı tekrar atamasın diye listeden çıkar } } }
private void HastaAtamasiYapFirsfit(List <int> myHastaList) { atanacakhastalar.Clear(); if (myHastaList == null || myHastaList.Count == 0) //herhangi bir hasta listesi gelmemiş işe hepsi atanacak { foreach (Hasta hasta in Islemler.hastaListGun) { if (hasta.hastaID == 0) { continue; // sağlık merkezini atama } atanacakhastalar.Add(hasta); } } else //atama yapılacak hasta listesi dışarıdan gönderildi ise sadece o hastalar için atama yapacak { foreach (Hasta hasta in Islemler.hastaListGun) { if (hasta.hastaID == 0) { continue; // sağlık merkezini atama } for (int i = 0; i < myHastaList.Count; i++) { if (myHastaList[i] == hasta.hastaID) { atanacakhastalar.Add(hasta); } } } } //burada atanması gereken hasta listesi elde edildi, aşağıda bu listedeki hastaların ataması yapılacak CryptoRandom rnd = new CryptoRandom(); Rota atanacagirota; while (atanacakhastalar.Count != 0) { int rndhasta = rnd.Next(0, atanacakhastalar.Count);//0-count-1 aralığında üretir Hasta secilenHasta = atanacakhastalar[rndhasta]; List <int> atanabilecekrotalar = new List <int>(); for (int i = 0; i < rotaListesi.Count; i++) { atanabilecekrotalar.Add(i); } bool atadim = false; while (atanabilecekrotalar.Count != 0) //rastgele bir rotaı seçerek hastayı o rotaya atamaya çalışır { int rndrota = rnd.Next(0, atanabilecekrotalar.Count); atanacagirota = _rotaListesi[rndrota]; //atanması için rastgele rota seçildi atadim = atanacagirota.AtamaYap(secilenHasta); //hasta rotaya atanmış ise true döner if (atadim) { break; //rotaya atanmış ise while ı kır } atanabilecekrotalar.RemoveAt(rndrota); //rotaya atanamadı ise o rotayı sil diğer rotlara bak } if (!atadim) //hasta herhangi bir rotaya atanmadıysa { atanamayanhastalar.Add(secilenHasta); return; //herhangi bir hasta rotaya atanamadıysa diğerlerine bakmak gereksiz } atanacakhastalar.RemoveAt(rndhasta); //seçilen hastayı tekrar atamasın diye listeden çıkar } }
public void YeniNoktaEkleAraya(int index, Hasta hasta, int t1, int t2) { ziyaretSirasi.Insert(index, new Gen(hasta, t1, t2)); }
public void YeniNoktaEkleAraya(int index, Hasta hasta, TimeWindow tw) { ziyaretSirasi.Insert(index, new Gen(hasta, tw)); }
static public Uzaklik2 UzaklikGetir(Hasta hasta1, Hasta hasta2) { return(Islemler.distanceMatrix[new Tuple <int, int>(hasta1.hastaID, hasta2.hastaID)]); }
public Gen(Hasta hasta) { this.hasta = hasta; // GenCezaHesapla(); }
private void HastaAtamasiYapBestFitPeriyod(List <int> myHastaList) { //atanacak hastalar bir list bu listede hastalar atanması gereken önceliğe göre yerleştirilmiş //liste oluşturulurken hastanın atanması istenen periyoda atanma olasılığına bakılıyor, önceliği yüksek olanlar daha öne gelebiliyor atanacakhastalar.Clear(); if (myHastaList == null || myHastaList.Count == 0) //herhangi bir hasta listesi gelmemiş işe hepsi atanacak { foreach (Hasta hasta in Islemler.hastaListGun) { if (hasta.hastaID == 0) { continue; // sağlık merkezini atama } int konum; for (konum = 0; konum < atanacakhastalar.Count; konum++) //atama olasılığına göre liste yapıyor baştaki hastaların olasılığı daha yüksek { if (hasta.oncelik * hasta.bakimSuresi / (hasta.timeWindow.t2 - hasta.timeWindow.t1) > atanacakhastalar[konum].oncelik * atanacakhastalar[konum].bakimSuresi / (atanacakhastalar[konum].timeWindow.t2 - atanacakhastalar[konum].timeWindow.t1)) { break;//konum uygun yere gelmiş ise for kırılır } } atanacakhastalar.Insert(konum, hasta);//hasta atanma olasılığına göre uygun bir yere yerleştirildi } } else //atanacak hastalistesi dışarıdan gödnerilmiş ise { foreach (int hastaID in myHastaList) { Hasta hasta = null; for (int i = 0; i < Islemler.hastaListGun.Count; i++) { if (Islemler.hastaListGun[i].hastaID == hastaID) { hasta = Islemler.hastaListGun[i]; break;//hasta bilgisi bulundu } } int konum; for (konum = 0; konum < atanacakhastalar.Count; konum++) //atama olasılığına göre liste yapıyor baştaki hastaların olasılığı daha yüksek { //hastayı listedeki 1. hasta ile karşılaştırıp ondan daha öncelikli ise onun önüne ekler, bu şekilde önceki her hasta ile mukayeseye devam eder if (hasta.oncelik * hasta.bakimSuresi / (hasta.timeWindow.t2 - hasta.timeWindow.t1) > atanacakhastalar[konum].oncelik * atanacakhastalar[konum].bakimSuresi / (atanacakhastalar[konum].timeWindow.t2 - atanacakhastalar[konum].timeWindow.t1)) { break;//konum uygun yere gelmiş ise for kırılır } } atanacakhastalar.Insert(konum, hasta);//hasta atanma olasılığına göre uygun bir yere yerleştirildi } } CryptoRandom rnd = new CryptoRandom(); Rota atanacagirota; while (atanacakhastalar.Count != 0) { //rnd1 10 ise, rnd 0-10 aralığında olacaktır bu yöntem baştaki hastaların seçilme şansını artırır. int rnd1 = rnd.Next(0, atanacakhastalar.Count); //0-count-1 aralığında üretir int rndhasta = rnd.Next(0, rnd1 + 1); //liste başındaki bireylerin seçilme şansını arttırmak için ilk seçilen değer ile 0 arasında yeni bir konum Hasta secilenHasta = atanacakhastalar[rndhasta]; List <int> atanabilecekrotalar = new List <int>(); for (int i = 0; i < rotaListesi.Count; i++) { atanabilecekrotalar.Add(rotaListesi[i].ekip.ekipID); } bool atadim = false; while (atanabilecekrotalar.Count != 0) { int rndrota = rnd.Next(0, atanabilecekrotalar.Count); atanacagirota = EkibinRotasiniBul(atanabilecekrotalar[rndrota]); //atanması için rastgele rota seçildi atadim = atanacagirota.AtamaYap(secilenHasta); //hasta rotaya atanmış ise true döner if (atadim) { break; //rotaya atanmış ise while ı kır } atanabilecekrotalar.RemoveAt(rndrota); //rotaya atanamadı ise o rotayı sil diğer rotlara bak } if (!atadim) //hasta herhangi bir rotaya atanmadıysa { atanamayanhastalar.Add(secilenHasta); return; //herhangi bir hasta rotaya atanamadıysa diğerlerine bakmak gereksiz } atanacakhastalar.RemoveAt(rndhasta); //seçilen hastayı tekrar atamasın diye listeden çıkar } }
private void HastaAtamasiYapBestFitEkip(List <int> myHastaList) { //skillmap değiştiğinden dolayı bu yordam değiştirildi, //bu hali ile hasta skill gereksiniminde her bit için en kıt kaynağa sahip olanlar hasta nesnesinde belli //hasta.ekipihtiyacsira ya göre küçükten büyüğe sıralanacak ve öncelik öndeki hastalarda olacak şekilde seçim yapılacak atanacakhastalar.Clear(); if (myHastaList == null || myHastaList.Count == 0) //herhangi bir hasta listesi gelmemiş işe hepsi atanacak { foreach (Hasta hasta in Islemler.hastaListGun) { if (hasta.hastaID == 0) { continue; // sağlık merkezini atama } atanacakhastalar.Add(hasta); } } else //atama yapılacak hasta listesi dışarıdan gönderildi ise sadece o hastalar için atama yapacak { foreach (Hasta hasta in Islemler.hastaListGun) { if (hasta.hastaID == 0) { continue; // sağlık merkezini atama } foreach (int hastaID in myHastaList) { if (hastaID == hasta.hastaID) { atanacakhastalar.Add(hasta); } } } } //burada atanması gereken hasta listesi elde edildi, aşağıda bu listedeki hastaların ataması yapılacak for (int i = 0; i < atanacakhastalar.Count - 1; i++) { for (int j = i + 1; j < atanacakhastalar.Count; j++) { if (atanacakhastalar[i].ekipihtiyacsira > atanacakhastalar[j].ekipihtiyacsira) { //hastalarsıraya konuyor Hasta gecici = atanacakhastalar[i]; atanacakhastalar[i] = atanacakhastalar[j]; atanacakhastalar[j] = gecici; } } } CryptoRandom rnd = new CryptoRandom(); Rota atanacagirota; while (atanacakhastalar.Count != 0) { //rnd1 10 ise, rnd 0-10 aralığında olacaktır bu yöntem baştaki hastaların seçilme şansını artırır. int rnd1 = rnd.Next(0, atanacakhastalar.Count); //0-count-1 aralığında üretir int rndhasta = rnd.Next(0, rnd1 + 1); //liste başındaki bireylerin seçilme şansını arttırmak için ilk seçilen değer ile 0 arasında yeni bir konum Hasta secilenHasta = atanacakhastalar[rndhasta]; List <int> atanabilecekrotalar = new List <int>(); for (int i = 0; i < rotaListesi.Count; i++) { atanabilecekrotalar.Add(rotaListesi[i].ekip.ekipID); } bool atadim = false; while (atanabilecekrotalar.Count != 0) { int rndrota = rnd.Next(0, atanabilecekrotalar.Count); atanacagirota = EkibinRotasiniBul(atanabilecekrotalar[rndrota]); //atanması için rastgele rota seçildi atadim = atanacagirota.AtamaYap(secilenHasta); //hasta rotaya atanmış ise true döner if (atadim) { break; //rotaya atanmış ise while ı kır } atanabilecekrotalar.RemoveAt(rndrota); //rotaya atanamadı ise o rotayı sil diğer rotlara bak } if (!atadim) //hasta herhangi bir rotaya atanmadıysa { atanamayanhastalar.Add(secilenHasta); return; //herhangi bir hasta rotaya atanamadıysa diğerlerine bakmak gereksiz } atanacakhastalar.RemoveAt(rndhasta); //seçilen hastayı tekrar atamasın diye listeden çıkar } }