/// <summary> /// Összeadja a megoldottnak tekintett feladatok időtartamát és megvizsgálja, hogy belefér-e a 8 órás munkaidőbe az új elem /// </summary> /// <param name="szint">Ahányadik helyre keressük a megfelelő elemet</param> /// <returns></returns> public bool Fk(int szint, Feladat f, TimeInterval kuszob) { //Mivel mindig ugyan azzal a megoldás tömbbel számolunk, nem kell paraméterként megadni //ha még nincs megoldás, akkor bármit betehetünk if (megoldas.Count == 0) { return(true); } TimeInterval SZUM = new TimeInterval(0, 0); SZUM.AddObjectValue(f.Idotartam); int i = 0; //ha egy korábbi szinten már választottuk ezt, akkor nem rakhatjuk bele if (megoldas.Contains(f)) { return(false); } //az aktuális megoldás elemszámáig megyünk feltéve, hogy a az összeg <= 8 óránál while (i < megoldas.Count && (SZUM.CompareTo(kuszob) == -1 || SZUM.CompareTo(kuszob) == 0)) { //alternatív += a SZUM-hoz SZUM.AddObjectValue(megoldas[i].Idotartam); i++; } //visszatérésként megvizsgáljuk, hogy a szum értéke <=-e a korláttal, //azaz a mostani elemet hozzáadva beleférünk-e a 8 órába return(SZUM.CompareTo(kuszob) == -1 || SZUM.CompareTo(kuszob) == 0); }
public void Parse(string[] read, List <Feladat> feladatok, StreamReader sr, Office o) { if (read.Length >= 3) { //mivel a konstruktorból dobunk hibát, így meg kell adni az SR-t is, hogy a hiba bezárhassa a file-t Feladat tempFeladat = new Feladat(read, sr); o.UjFeladatotHozzaad(tempFeladat, feladatok); } else { //a user kihagyta a ;-z string temp = ""; foreach (string s in read) { temp += s; } throw new UserInputException(temp, sr); } }
public void UjFeladatotHozzaad(Feladat f, List <Feladat> feladatok) { feladatok.Add(f); }
/// <summary> /// Újra osztja a feladatokat az optimális megoldást tartalmazó tömb éppen beszúrt elemeiből /// </summary> /// <param name="helper">Az új elemig eltelt idő</param> /// <param name="endOfWorkHours">Ekkora van vége a munkanapnak</param> /// <param name="i">Az iterátor, mely az éppen beszúrt elemre mutat</param> /// /// <param name="exchangedFeladat">A cserélt feladatra mutat, ha nincs ilyen, akkor null</param> void FeladatokatUjraoszt(TimeInterval helper, TimeInterval endOfWorkHours, int i, Feladat exchangedFeladat) { //tehát ha maradt még idő: if (helper.CompareTo(endOfWorkHours) < 0) { //generálunk két listát //az egyik azokat az eseményeket fogja tartalmazni, amik az optimálisban az új feladat után vannak List <Feladat> tovabbiFeladatok = new List <Feladat>(); //ha valamilyen elem HELYÉRE szúrtuk be az újat, akkor ezt az elemet hozzáadjuk a listához if (exchangedFeladat != null) { tovabbiFeladatok.Add(exchangedFeladat); } //mivel az i most oda mutat, ahol az új elem van, minden további elemet átmásolunk ide egy új iterátorral for (int j = i + 1; j < opt.Count; j++) { tovabbiFeladatok.Add(opt[j]); } //a másik az optimális elosztást, ha van ilyen List <Feladat> optimalisUj = new List <Feladat>(); TimeInterval ujIdobeosztasKuszob = new TimeInterval(endOfWorkHours - helper); //majd BT-el megpróbáljuk beosztani őket megoldas = new List <Feladat>(); //ezután kivesszük a most berakott elem után az összeset, hogy az optimálisat adjuk majd vissza opt.RemoveRange(i + 1, opt.Count - (i + 1)); BackTrack(0, tovabbiFeladatok, optimalisUj, ujIdobeosztasKuszob); //ha volt optimális megoldás if (optimalisUj.Count > 0) { //akkor azt hozzáadjuk a valódi optimálishoz opt.AddRange(optimalisUj); //kiszedjük a most berakott elemeket az új elem miatt vizsgálandó elemek között tovabbiFeladatok.RemoveAll(feladat => optimalisUj.Contains(feladat)); //majd megnézzük, hogy maradt-e elem if (tovabbiFeladatok.Count > 0) { //ha igen, őket visszatesszük a napi feladatok közé, hogy egy későbbi alkalomkor fel lehessen őket dolgozni napiFeladatok.AddRange(tovabbiFeladatok); } } } }
public void SurgosFeladatokHozzaadasa() { Console.WriteLine("A szimuláció megkezdése előtt lehetőség van új feladatokat megadni,\nmellyel szimulálható egy-egy új sürgős feladat érkezése.\nA feladatok prioritása kötött, azonban az időtartamon és a feladat teljesítéséért járó fizetségen kívül\nmeg kell adni annak érkezési időpontját is."); Console.WriteLine("Kíván új feladatokat hozzáadni? (y/n)"); char choice = Console.ReadKey().KeyChar; if (choice == 'y' || choice == 'Y') { List <SurgosFeladat> s = new List <SurgosFeladat>(); Console.WriteLine("\nAdja meg az új feladatokat a következő szintaxist alkalmazva (NYERESÉG;ÓRA:PERC(időtartam);ÓRA:PERC(kezdés ideje))\nHa egy feladat megadásával végzett, üssön ENTER-t. Ha nem kíván több feladatot megadni, gépelje be az 'n' karaktert és üssön ENTER-t."); string ujFeladatok = ""; do { ujFeladatok = Console.ReadLine(); if (ujFeladatok != "n") { string[] split = ujFeladatok.Split(';'); string[] textInput = new string[split.Length - 1]; for (int j = 0; j < split.Length - 1; j++) { textInput[j] = split[j]; } s.Add(new SurgosFeladat(textInput, split[split.Length - 1])); } } while (ujFeladatok != "n"); TimeInterval endOfWorkHours = new TimeInterval(8, 0); //erre azért van szükség, hogy ha nem 8-kor kezdődik a munka, el lehessen tárolni mást is, a munkaidő kezdetét kell itt megadni endOfWorkHours.AddObjectValue(Constants.Korlat); //a munkaidő kezdetéhez hozzáadunk 8 órát //ha a felhasználó olyan elemet adott meg, ami megelőzi az ÁLLÍTHATÓ munkaidő kezdetét, vagy a 8 órás munkaidő után érkezik, azokat kivesszük s.RemoveAll(f => (f.TimeOfStart.CompareTo(StartOfWorkDay) < 0) || f.TimeOfStart.CompareTo(endOfWorkHours) > 0); //ha több esemény is érkezik ugyan abban az időben, akkor csak az 1. előfordulást hajtjuk végre //egy LINQ paranccsal eltávolítjuk az összes azonos időben érkező feladatot //kivéve persze az eseményt magát, mivel nem override-oltuk az Equals-t, //objektumként hasonlítja össze az elemeket, azaz referencia szerint for (int inc = 0; inc < s.Count; inc++) { s.RemoveAll(f => !f.Equals(s[inc]) && f.TimeOfStart.CompareTo(s[inc].TimeOfStart) == 0); } int i = 0; //ha a felhasználó felcseréli az érkező feladatok sorrendjét (például: előbb írja, hogy érkezik egy 12:00-kor, majd beírja, hogy 8:00-kor is érkezett előtte) s.Sort(); //az összes új feladatra meg kell néznünk, hogy hogyan befolyásolják az eredeti listát for (int l = 0; l < s.Count; l++) { //az összehasonlítás miatt van erre szükség: értéke az az időpont, amikor végeznénk a feladattal, ha pontosan akkor kezdenénk el, amikor megérkezik //erre azért van szükség, hogy kiszűrhessük azokat a feladatokat, amiket a kezdeti időponttól már nem lehetne megoldani TimeInterval comparer = new TimeInterval(0, 0); comparer.AddObjectValue(s[l].Idotartam); comparer.AddObjectValue(s[l].TimeOfStart); //ha a kezdezi időponttól kezdve beleférünk a 8 órába... if (comparer.CompareTo(endOfWorkHours) < 0) { i = 0; TimeInterval helper = new TimeInterval(8, 0); //addig megy, amíg van elem az optimálisban és amíg a segéd értéke meg nem haladja az új elem kezdetét while (i < opt.Count && helper.CompareTo(s[l].TimeOfStart) < 0) { helper.AddObjectValue(opt[i].Idotartam); i++; } //erre a fél óra miatt van szükség TimeInterval temp = new TimeInterval(30); //értéke az a maximális időpont, ameddig elkezdhetjük az új feladatot (kezdeti + fél óra) temp.AddObjectValue(s[l].TimeOfStart); //temp.AddObjectValue(offset); //ha a feladat megérkezésétől számítva fél órán belül el tudjuk kezdni, mert addigra lejár egy feladat if (helper.CompareTo(temp) < 0 || helper.CompareTo(temp) == 0) { //akkor beszúrjuk a megfelelő feladat mögé opt.Insert(i, s[l]); //ezután meg kell nézni, hogy az új esemény utáni feladatokat hogyan lehet a legoptimálisabban elosztani (ha lehet) //ezért, ha maradt még idő, BackTrack-el újraosztjuk az eseményeket a következő módszerrel: helper.AddObjectValue(s[l].Idotartam); //az ideiglenes tömbben null-ra állítjuk a feladatot, remove-olni nem lehet, mert megváltozik az enumeration s[l] = null; //újraosztjuk a feladatokat FeladatokatUjraoszt(helper, endOfWorkHours, i, null); } //ha nem tudjuk fél órán belül elkezdeni, de azért nem mert épp akkor egy feladat folyamatban van... else { /*a Beadandó pdf-jében szereplő 6-os feladat szerint: *"A nap folyamán bármikor jöhet újabb sürgős feladat, amit fél órán belül el kell kezdenünk * megvalósítani." Azonban a Beadandó korábbi feladataiból kiderül, hogy minden sürgős feladatot * meg kellene oldani, így tehát ha éppen sürgős feladatot hajtunk végre, akkor nem oldható meg a feladat, * az új elem pedig végül a kivételek közé kerül majd. Ha nem sürgős...*/ //az i most arra az elemre mutat, ami előtt van az a hely, ahová be akarjuk szúrni az új elemet //ha ezen a helyen nem sürgős feladat van... if (opt[i - 1].Prioritas != Prioritas.Surgos) { //figyelembe kell venni, hogy az optba beletettük az új elemet... Console.WriteLine("Félbeszkítottuk: {0}, mert sürgős feladat érkezett!", opt[i - 1].ToString()); helper.AddObjectValue(s[l].Idotartam); //...de kivettük a régit helper.SubtractObjectValue(opt[i - 1].Idotartam); Feladat csereltFeladat = opt[i - 1]; /*a cserélt feladat idejéből ki kell vonnunk azt az időt, amit eltöltöttünk már vele * Ezt a következőképpen lehet: * ha a helperből kivonjuk a cserélt időtartamát, akkor megkapjuk, hogy a cseréltet mikor kezdtük el * ha az új feladat érkezési idejéből ezt kivonjuk, megkapjuk, hogy mennyi ideje tartott a feladat, mikor az új megjött * ezt kell kivonni a cseréltből * Azaz: ha 8:15-kor kezdtünk el egy nem sürgős feladatot, de 8:20-kor jött egy sürgős, * akkor a már belekezdett feladat 5 perccel rövidebb lesz*/ TimeInterval calculation = new TimeInterval(helper - csereltFeladat.Idotartam); csereltFeladat.Idotartam.SubtractObjectValue(new TimeInterval(s[l].TimeOfStart - calculation)); //az új feladatot ide szúrjuk majd be, felülírva a korábbi feladatot opt[i - 1] = s[l]; s[l] = null; calculation = null; //végül újraosztjuk a feladatokat úgy, hogy a módosított feladatot is átadjuk FeladatokatUjraoszt(helper, endOfWorkHours, i - 1, csereltFeladat); } } } } //mivel null-okkal jelöltük az összes megoldott elemet, ezeket most kivesszük s.RemoveAll(feladat => feladat == null); //ha van benne még elem, azokat nem tudtuk megoldani, így kivételt generálunk if (s.Count > 0) { throw new UjSurgosFeladatException(s); } } else if (choice == 'n' || choice == 'N') { Console.WriteLine("\nA szimuláció változatlanul fog lefutni!"); return; } }