Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // -----------------------------------------------------------------------
- // <copyright file="Searcher.cs" company="BME-AUT">
- // Author: Végh Ladislav
- // Date: 2012-04-18
- // </copyright>
- // -----------------------------------------------------------------------
- namespace Tervezo
- {
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
- /// <summary>
- /// Class that implements the problem solving algorithms
- /// </summary>
- public class Searcher
- {
- /// <summary>
- /// Manager for the person objects
- /// </summary>
- private PersonManager pm;
- /// <summary>
- /// Manager for the demand objects
- /// </summary>
- private DemandManager dm;
- /// <summary>
- /// Manager for the assignment objects
- /// </summary>
- private AssignmentManager am;
- /// <summary>
- /// Initializes a new instance of the <see cref="Searcher"/> class.
- /// Constructor with the PersonManager and the DemandManager
- /// </summary>
- /// <param name="pm">The personmagager object</param>
- /// <param name="dm">The demandmanager object</param>
- public Searcher(PersonManager pm, DemandManager dm)
- {
- AssignmentManager.Initialize();
- this.pm = pm;
- this.dm = dm;
- this.am = AssignmentManager.Instance;
- }
- /// <summary>
- /// Search algorithm with a Bacgroundworker to report progress
- /// </summary>
- /// <param name="bw">The backgroundworker object to report progress</param>
- /// <returns>True if the solving was successfull</returns>
- public bool Search(BackgroundWorker bw)
- {
- Demand tempdm;
- TimeSlot tempts;
- TimeSlotManager tsm = TimeSlotManager.GetInstance();
- // Iterate over demands
- int actualtimeslot = 0;
- foreach (var item in this.dm.GetNext())
- {
- // Timeslot
- tempts = item.Key;
- // priorities
- foreach (var inneritem in item.Value)
- {
- bw.ReportProgress(++actualtimeslot);
- tempdm = inneritem.Value;
- // Console.WriteLine(tempts.ToString());
- // Iterate over skills
- foreach (KeyValuePair<string, int> kvp in tempdm.GetNext())
- {
- string skillname = kvp.Key;
- Skill tempskill = new Skill();
- tempskill[skillname] = 1;
- int num = kvp.Value;
- // Get enough empoloyees
- // Assign them
- for (int i = 0; i < num; i++)
- {
- //////try to get an available person
- ////Person tempp = pm.GetPersonWithStatus(tempts, tempskill, Status.MustWork);
- //////if available not found search in Hours done workers
- //////if (tempp == null) tempp = Repair(tempts, tempskill, 0);
- //////if cannot repair no result found
- ////if (tempp == null) tempp = pm.GetPersonWithStatus(tempts, tempskill, Status.Available);
- ////if (tempp == null) tempp = pm.GetPersonWithStatus(tempts, tempskill, Status.FreeTimeCanWork);
- ////if (tempp == null) return false;
- Person tempp = null;
- for (int numofskills = 1; numofskills <= Skill.Ids.Count && tempp == null; numofskills++)
- {
- tempp = this.pm.GetPersonWithStatus(tempts, tempskill, Status.MustWork, numofskills);
- if (tempp == null)
- {
- tempp = this.pm.GetPersonWithStatus(tempts, tempskill, Status.FreeTimeCanWork, numofskills);
- }
- if (tempp == null && tsm.IsThereEnoughContinuousTimeSlots(tempts.TimeSlotID, Properties.Settings.Default.MinMinuteToWork))
- {
- tempp = this.pm.GetPersonWithStatus(tempts, tempskill, Status.Available, numofskills);
- }
- }
- if (tempp == null)
- {
- tempp = this.Repair(tempts, tempskill, tempdm, 0);
- }
- if (tempp == null)
- {
- return false;
- }
- Assignment tempass = new Assignment(tempp, tempdm, tempts, tempskill);
- this.am.Add(tempass);
- tempp.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Assigned);
- }
- }
- }
- }
- return true;
- }
- /// <summary>
- /// Another searcher func
- /// </summary>
- /// <param name="bw">The backgroundworker referenc</param>
- /// <returns>True if solved, false else</returns>
- public bool Search2(BackgroundWorker bw)
- {
- int assignments = 0;
- foreach (var timeslot in TimeSlotManager.GetInstance())
- {
- foreach (var skillname in Skill.Ids.Values)
- {
- for (int num = DemandManager.Instance[timeslot][skillname]; num > 0; num--)
- {
- assignments += AssignPerson(timeslot, skillname);
- bw.ReportProgress(assignments);
- }
- }
- }
- return true;
- }
- public int AssignPerson(TimeSlot ts, String skillname)
- {
- TimeSlotManager tsm = TimeSlotManager.GetInstance();
- Skill tempskill = new Skill();
- tempskill[skillname] = 1;
- // Ha van 4-8 ora kozt dolgozo
- for (int numOfSkills = 1; numOfSkills <= this.pm.MaxNumberOfSkills; numOfSkills++)
- {
- Person tempperson = this.pm.GetPersonWithStatus(ts, tempskill, Status.FreeTimeCanWork, numOfSkills);
- // 0-4 ora kozt dolgozot keres
- if (tempperson == null)
- {
- int NumberOfReqTimeSlots = 0;
- // ha van elegendo timeslot megszakitas nelkul
- if (tsm.IsThereEnoughContinuousTimeSlots(ts.TimeSlotID, Properties.Settings.Default.MinMinuteToWork))
- {
- NumberOfReqTimeSlots = tsm.GetTimeSlotsInRange(tsm.GetIndexByID(ts.TimeSlotID), Properties.Settings.Default.MinMinuteToWork - tsm.GetLengthOfTimeSlots());
- TimeSlot tsend = tsm[tsm.GetIndexByID(ts.TimeSlotID) + NumberOfReqTimeSlots];
- foreach (var item in this.pm.GetPerson(ts, tsend, tempskill, numOfSkills, Status.Available))
- {
- if (tsm.GetIndexByID(ts.TimeSlotID) < tsm.GetIndexByID(tsend.TimeSlotID))
- {
- if (AssignedDuring(tsm[tsm.GetIndexByID(ts.TimeSlotID)], tsend, item, tempskill)) return Properties.Settings.Default.MinMinuteToWork / tsm.GetLengthOfTimeSlots();
- }
- else
- {
- //beosztani mert eleg egy TS + matrix update
- Assignment tempass = new Assignment(item, ts, tempskill);
- this.am.Add(tempass);
- DemandManager.Instance[ts][skillname]--;
- item.SetAvailability(tsm.GetIndexByID(ts.TimeSlotID), Status.Assigned);
- return 1;
- }
- }
- }
- // nincs folyamatos 4 ora, vagy nincs ember akit be lehetne osztani 4 folyamatos orara adott skillel kezdve
- // keresunk tulorazot (8-12)
- tempperson = this.pm.GetPersonWithStatus(ts, tempskill, Status.ExtraTimeCanWork);
- //van ember de visszamenoleg cserelni kell hogy meglegyen a 4 ora
- if (tempperson == null)
- {
- //todo visszakeresest + cseret kitalalni
- }
- else
- {
- //beosztani + matrix update
- Assignment tempass = new Assignment(tempperson, ts, tempskill);
- this.am.Add(tempass);
- DemandManager.Instance[ts][skillname]--;
- tempperson.SetAvailability(tsm.GetIndexByID(ts.TimeSlotID), Status.Assigned);
- return 1;
- }
- }
- else
- {
- //beosztani + matrix update
- Assignment tempass = new Assignment(tempperson, ts, tempskill);
- this.am.Add(tempass);
- DemandManager.Instance[ts][skillname]--;
- tempperson.SetAvailability(tsm.GetIndexByID(ts.TimeSlotID), Status.Assigned);
- return 1;
- }
- }
- return 0;
- }
- public Boolean AssignedDuring(TimeSlot tsStart, TimeSlot tsEnd, Person per, Skill sk)
- {
- List<string> skills = new List<string>();
- TimeSlotManager tsm = TimeSlotManager.GetInstance();
- TimeSlot tempts = tsStart;
- while (tsm.GetIndexByID(tempts.TimeSlotID) <= tsm.GetIndexByID(tsEnd.TimeSlotID))
- {
- if (DemandManager.Instance[tempts][sk.ToString()] > 0) skills.Add(sk.ToString());
- else
- {
- Boolean found = false;
- foreach (var item in per.Skill.EnumerateSkills())
- {
- if (DemandManager.Instance[tempts][item] > 0)
- {
- skills.Add(item);
- found = true;
- break;
- }
- }
- if (found == false) return false;
- }
- if ((tsm.GetIndexByID(tempts.TimeSlotID) + 1) < tsm.Count) tempts = tsm[tsm.GetIndexByID(tempts.TimeSlotID) + 1];
- else break;
- }
- //update matrix, create assignments
- TimeSlot tempts2 = tsStart;
- foreach (var item in skills)
- {
- Skill tempskill = new Skill();
- tempskill[item] = 1;
- Assignment tempass = new Assignment(per, tempts2, tempskill);
- this.am.Add(tempass);
- DemandManager.Instance[tempts2][item]--;
- per.SetAvailability(tsm.GetIndexByID(tempts2.TimeSlotID), Status.Assigned);
- if ((tsm.GetIndexByID(tempts2.TimeSlotID) + 1) < tsm.Count) tempts2 = tsm[tsm.GetIndexByID(tempts2.TimeSlotID) + 1];
- else break;
- }
- return true;
- }
- /// <summary>
- /// Returns the fully filled assignment manager object
- /// </summary>
- /// <returns>The filled assignmentManager</returns>
- public AssignmentManager GetAssingments()
- {
- return this.am;
- }
- /// <summary>
- /// Tries to switch an already assigned person to another person.
- /// </summary>
- /// <param name="tempts">In which timeslot to switch</param>
- /// <param name="tempskill">On which skill try to find an already assigned person</param>
- /// <param name="tempdm">Which demand</param>
- /// <param name="depth">Maximum number of depth of the recursion</param>
- /// <returns>A person who was assigned, but switched with another person. The returned person now can do the required job.</returns>
- public Person Repair(TimeSlot tempts, Skill tempskill, Demand tempdm, int depth)
- {
- // Recursion depth
- if (depth > 2)
- {
- return null;
- }
- TimeSlotManager tsm = TimeSlotManager.GetInstance();
- Person otherPer = null;
- Person person = null;
- ////for (int numofskills = 1; numofskills <= 10 && tempp == null; numofskills++)
- ////{
- //// tempp = pm.GetPersonWithStatus(tempts, tempskill, Status.Assigned, numofskills);
- ////}
- // Search in already assigned persons
- foreach (var tempp in this.pm.GetPerson(tempts, tempskill, Status.Assigned))
- {
- Skill otherskill = null;
- Demand otherdemand = null;
- foreach (var item in this.am.List(tempp))
- {
- if (item.TimeSlot.TimeSlotID == tempts.TimeSlotID)
- {
- // The assigned persons current assignments skill and demand
- otherskill = item.Skill;
- otherdemand = item.Demand;
- break;
- }
- }
- if (otherskill == null)
- {
- continue;
- }
- otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.MustWork);
- if (otherPer == null)
- {
- otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.FreeTimeCanWork);
- }
- // solves testset 3 but somebodies works only 2 hours
- if (otherPer == null)
- {
- otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.Available);
- }
- // doesnot solve testset3 but makes sure nobody works less then 4 hours
- ////if ((otherPer == null) &&(tsm.IsThereEnoughContinuousTimeSlots(tempts.TimeSlotID,Properties.Settings.Default.MinMinuteToWork))) otherPer = pm.GetPersonWithStatus(tempts, otherskill, Status.Available);
- ////if (otherPer == null) otherPer = Repair(tempts, otherskill, otherdemand, ++depth);
- if (otherPer == null)
- {
- continue;
- }
- Assignment tempass = new Assignment(otherPer, otherdemand, tempts, otherskill);
- this.am.Add(tempass);
- otherPer.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Assigned);
- this.am.DeleteAssignment(tempdm, tempp, tempts);
- tempp.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Available);
- person = tempp;
- break;
- }
- if (person == null || otherPer == null)
- {
- foreach (var tempp in this.pm.GetPerson(tempts, tempskill, Status.Assigned))
- {
- Skill otherskill = null;
- Demand otherdemand = null;
- foreach (var item in this.am.List(tempp))
- {
- if (item.TimeSlot.TimeSlotID == tempts.TimeSlotID)
- {
- otherskill = item.Skill;
- otherdemand = item.Demand;
- break;
- }
- }
- if (otherskill == null)
- {
- continue;
- }
- otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.MustWork);
- if (otherPer == null)
- {
- otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.FreeTimeCanWork);
- }
- // solves testset3
- if (otherPer == null)
- {
- otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.Available);
- }
- // doesnt solve testset3 but nobody works less then 4 hours
- ////if ((otherPer == null) && (tsm.IsThereEnoughContinuousTimeSlots(tempts.TimeSlotID, Properties.Settings.Default.MinMinuteToWork))) otherPer = pm.GetPersonWithStatus(tempts, otherskill, Status.Available);
- if (otherPer == null)
- {
- otherPer = this.Repair(tempts, otherskill, otherdemand, ++depth);
- }
- if (otherPer == null)
- {
- continue;
- }
- Assignment tempass = new Assignment(otherPer, otherdemand, tempts, otherskill);
- this.am.Add(tempass);
- otherPer.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Assigned);
- this.am.DeleteAssignment(tempdm, tempp, tempts);
- tempp.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Available);
- person = tempp;
- break;
- }
- }
- if (person == null)
- {
- return null;
- }
- if (otherPer == null)
- {
- return null;
- }
- return person;
- }
- /*public Person Repair(TimeSlot tempts, Skill tempskill, int depth)
- {
- if (depth > 3) return null;
- Person tempp = null;
- foreach (Person tempper in pm.GetPerson(tempts, tempskill, Status.HoursDone))
- {
- Person anotherPerson = null;
- TimeSlot tsToFree = null;
- Demand otherDemand = null;
- Skill otherSkill = null;
- //get when tempper works
- foreach (Assignment ass in am.List(tempper))
- {
- //if the timeslot is not in given day skip
- if (ass.TimeSlot.Day != tempts.Day) continue;
- //find anoother available worker on that timeslot
- anotherPerson = pm.GetPerson(ass.TimeSlot, ass.Skill);
- //if found satisfying person break else continue on another timeslot
- if (anotherPerson != null)
- {
- tsToFree = ass.TimeSlot;
- otherDemand = ass.Demand;
- otherSkill = ass.Skill;
- break;
- }
- }
- //if found another worker free tempper
- if (anotherPerson != null)
- {
- tempper.SetAvailability(tsToFree.GetIndex(), Status.Available);
- Assignment corrector = new Assignment(anotherPerson, otherDemand, tsToFree, otherSkill);
- am.Add(corrector);
- anotherPerson.SetAvailability(tsToFree.GetIndex(), Status.Assigned);
- am.DeleteAssignment(otherDemand, tempper, tsToFree);
- //assign tempper to now
- tempp = tempper;
- break;
- }
- }
- if(tempp==null)
- {
- foreach (Person tempper in pm.GetPerson(tempts, tempskill, Status.HoursDone))
- {
- foreach (Assignment ass in am.List(tempper))
- {
- if (ass.TimeSlot.Day != tempts.Day) continue;
- tempp = Repair(ass.TimeSlot, ass.Skill, depth+1);
- if (tempp != null)
- {
- tempper.SetAvailability(ass.TimeSlot.GetIndex(), Status.Available);
- Assignment corrector = new Assignment(tempp, ass.Demand, ass.TimeSlot, ass.Skill);
- am.Add(corrector);
- tempp.SetAvailability(ass.TimeSlot.GetIndex(), Status.Assigned);
- am.DeleteAssignment(ass.Demand, tempper, ass.TimeSlot);
- tempp = tempper;
- break;
- }
- }
- if (tempp != null) break;
- }
- }
- return tempp;
- }*/
- }
- }
Add Comment
Please, Sign In to add comment