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 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); }