daily pastebin goal
9%
SHARE
TWEET

Untitled

a guest Oct 22nd, 2018 66 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // -----------------------------------------------------------------------
  2. // <copyright file="Searcher.cs" company="BME-AUT">
  3. // Author: VĂ©gh Ladislav
  4. // Date: 2012-04-18
  5. // </copyright>
  6. // -----------------------------------------------------------------------
  7.  
  8. namespace Tervezo
  9. {
  10.     using System;
  11.     using System.Collections.Generic;
  12.     using System.ComponentModel;
  13.     using System.Linq;
  14.     using System.Text;
  15.  
  16.     /// <summary>
  17.     /// Class that implements the problem solving algorithms
  18.     /// </summary>
  19.     public class Searcher
  20.     {
  21.         /// <summary>
  22.         /// Manager for the person objects
  23.         /// </summary>
  24.         private PersonManager pm;
  25.  
  26.         /// <summary>
  27.         /// Manager for the demand objects
  28.         /// </summary>
  29.         private DemandManager dm;
  30.  
  31.         /// <summary>
  32.         /// Manager for the assignment objects
  33.         /// </summary>
  34.         private AssignmentManager am;
  35.  
  36.         /// <summary>
  37.         /// Initializes a new instance of the <see cref="Searcher"/> class.
  38.         /// Constructor with the PersonManager and the DemandManager
  39.         /// </summary>
  40.         /// <param name="pm">The personmagager object</param>
  41.         /// <param name="dm">The demandmanager object</param>
  42.         public Searcher(PersonManager pm, DemandManager dm)
  43.         {
  44.             AssignmentManager.Initialize();
  45.             this.pm = pm;
  46.             this.dm = dm;
  47.             this.am = AssignmentManager.Instance;
  48.         }
  49.  
  50.         /// <summary>
  51.         /// Search algorithm with a Bacgroundworker to report progress
  52.         /// </summary>
  53.         /// <param name="bw">The backgroundworker object to report progress</param>
  54.         /// <returns>True if the solving was successfull</returns>
  55.         public bool Search(BackgroundWorker bw)
  56.         {
  57.             Demand tempdm;
  58.             TimeSlot tempts;
  59.             TimeSlotManager tsm = TimeSlotManager.GetInstance();
  60.  
  61.             // Iterate over demands
  62.             int actualtimeslot = 0;
  63.             foreach (var item in this.dm.GetNext())
  64.             {
  65.                 // Timeslot
  66.                 tempts = item.Key;
  67.  
  68.                 // priorities
  69.                 foreach (var inneritem in item.Value)
  70.                 {
  71.                     bw.ReportProgress(++actualtimeslot);
  72.                     tempdm = inneritem.Value;
  73.  
  74.                     // Console.WriteLine(tempts.ToString());
  75.                     // Iterate over skills
  76.                     foreach (KeyValuePair<string, int> kvp in tempdm.GetNext())
  77.                     {
  78.                         string skillname = kvp.Key;
  79.                         Skill tempskill = new Skill();
  80.                         tempskill[skillname] = 1;
  81.                         int num = kvp.Value;
  82.  
  83.                         // Get enough empoloyees
  84.                         // Assign them
  85.                         for (int i = 0; i < num; i++)
  86.                         {
  87.                             //////try to get an available person
  88.                             ////Person tempp = pm.GetPersonWithStatus(tempts, tempskill, Status.MustWork);
  89.                             //////if available not found search in Hours done workers
  90.                             //////if (tempp == null) tempp = Repair(tempts, tempskill, 0);
  91.                             //////if cannot repair no result found
  92.                             ////if (tempp == null) tempp = pm.GetPersonWithStatus(tempts, tempskill, Status.Available);
  93.                             ////if (tempp == null) tempp = pm.GetPersonWithStatus(tempts, tempskill, Status.FreeTimeCanWork);
  94.                             ////if (tempp == null) return false;
  95.                             Person tempp = null;
  96.                             for (int numofskills = 1; numofskills <= Skill.Ids.Count && tempp == null; numofskills++)
  97.                             {
  98.                                 tempp = this.pm.GetPersonWithStatus(tempts, tempskill, Status.MustWork, numofskills);
  99.                                 if (tempp == null)
  100.                                 {
  101.                                     tempp = this.pm.GetPersonWithStatus(tempts, tempskill, Status.FreeTimeCanWork, numofskills);
  102.                                 }
  103.  
  104.                                 if (tempp == null && tsm.IsThereEnoughContinuousTimeSlots(tempts.TimeSlotID, Properties.Settings.Default.MinMinuteToWork))
  105.                                 {
  106.                                     tempp = this.pm.GetPersonWithStatus(tempts, tempskill, Status.Available, numofskills);
  107.                                 }
  108.                             }
  109.  
  110.                             if (tempp == null)
  111.                             {
  112.                                 tempp = this.Repair(tempts, tempskill, tempdm, 0);
  113.                             }
  114.  
  115.                             if (tempp == null)
  116.                             {
  117.                                 return false;
  118.                             }
  119.  
  120.                             Assignment tempass = new Assignment(tempp, tempdm, tempts, tempskill);
  121.                             this.am.Add(tempass);
  122.                             tempp.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Assigned);
  123.                         }
  124.                     }
  125.                 }
  126.             }
  127.  
  128.             return true;
  129.         }
  130.  
  131.         /// <summary>
  132.         /// Another searcher func
  133.         /// </summary>
  134.         /// <param name="bw">The backgroundworker referenc</param>
  135.         /// <returns>True if solved, false else</returns>
  136.         public bool Search2(BackgroundWorker bw)
  137.         {
  138.             int assignments = 0;
  139.             foreach (var timeslot in TimeSlotManager.GetInstance())
  140.             {
  141.                 foreach (var skillname in Skill.Ids.Values)
  142.                 {
  143.                     for (int num = DemandManager.Instance[timeslot][skillname]; num > 0; num--)
  144.                     {
  145.                         assignments += AssignPerson(timeslot, skillname);
  146.                         bw.ReportProgress(assignments);
  147.                     }
  148.                 }
  149.             }
  150.        
  151.             return true;
  152.         }
  153.  
  154.         public int AssignPerson(TimeSlot ts, String skillname)
  155.         {
  156.             TimeSlotManager tsm = TimeSlotManager.GetInstance();
  157.             Skill tempskill = new Skill();
  158.             tempskill[skillname] = 1;
  159.             // Ha van 4-8 ora kozt dolgozo
  160.             for (int numOfSkills = 1; numOfSkills <= this.pm.MaxNumberOfSkills; numOfSkills++)
  161.             {
  162.                 Person tempperson = this.pm.GetPersonWithStatus(ts, tempskill, Status.FreeTimeCanWork, numOfSkills);
  163.                 // 0-4 ora kozt dolgozot keres
  164.                 if (tempperson == null)
  165.                 {
  166.                     int NumberOfReqTimeSlots = 0;
  167.                     // ha van elegendo timeslot megszakitas nelkul
  168.                     if (tsm.IsThereEnoughContinuousTimeSlots(ts.TimeSlotID, Properties.Settings.Default.MinMinuteToWork))
  169.                     {
  170.                         NumberOfReqTimeSlots = tsm.GetTimeSlotsInRange(tsm.GetIndexByID(ts.TimeSlotID), Properties.Settings.Default.MinMinuteToWork - tsm.GetLengthOfTimeSlots());
  171.                         TimeSlot tsend = tsm[tsm.GetIndexByID(ts.TimeSlotID) + NumberOfReqTimeSlots];
  172.                         foreach (var item in this.pm.GetPerson(ts, tsend, tempskill, numOfSkills, Status.Available))
  173.                         {
  174.                             if (tsm.GetIndexByID(ts.TimeSlotID) < tsm.GetIndexByID(tsend.TimeSlotID))
  175.                             {
  176.                                 if (AssignedDuring(tsm[tsm.GetIndexByID(ts.TimeSlotID)], tsend, item, tempskill)) return Properties.Settings.Default.MinMinuteToWork / tsm.GetLengthOfTimeSlots();
  177.                             }
  178.                             else
  179.                             {
  180.                                 //beosztani mert eleg egy TS + matrix update
  181.                                 Assignment tempass = new Assignment(item, ts, tempskill);
  182.                                 this.am.Add(tempass);
  183.                                 DemandManager.Instance[ts][skillname]--;
  184.                                 item.SetAvailability(tsm.GetIndexByID(ts.TimeSlotID), Status.Assigned);
  185.                                 return 1;
  186.                             }
  187.                         }
  188.                     }
  189.                     // nincs folyamatos 4 ora, vagy nincs ember akit be lehetne osztani 4 folyamatos orara adott skillel kezdve
  190.                     // keresunk tulorazot (8-12)
  191.                     tempperson = this.pm.GetPersonWithStatus(ts, tempskill, Status.ExtraTimeCanWork);
  192.                     //van ember de visszamenoleg cserelni kell hogy meglegyen a 4 ora
  193.                     if (tempperson == null)
  194.                     {
  195.                         //todo visszakeresest + cseret kitalalni
  196.                     }
  197.                     else
  198.                     {
  199.                         //beosztani + matrix update
  200.                         Assignment tempass = new Assignment(tempperson, ts, tempskill);
  201.                         this.am.Add(tempass);
  202.                         DemandManager.Instance[ts][skillname]--;
  203.                         tempperson.SetAvailability(tsm.GetIndexByID(ts.TimeSlotID), Status.Assigned);
  204.                         return 1;
  205.                     }
  206.                 }
  207.                 else
  208.                 {
  209.                     //beosztani + matrix update
  210.                     Assignment tempass = new Assignment(tempperson, ts, tempskill);
  211.                     this.am.Add(tempass);
  212.                     DemandManager.Instance[ts][skillname]--;
  213.                     tempperson.SetAvailability(tsm.GetIndexByID(ts.TimeSlotID), Status.Assigned);
  214.                     return 1;
  215.                 }
  216.             }
  217.             return 0;
  218.         }
  219.  
  220.         public Boolean AssignedDuring(TimeSlot tsStart, TimeSlot tsEnd, Person per, Skill sk)
  221.         {
  222.             List<string> skills = new List<string>();
  223.             TimeSlotManager tsm = TimeSlotManager.GetInstance();
  224.             TimeSlot tempts = tsStart;
  225.             while (tsm.GetIndexByID(tempts.TimeSlotID) <= tsm.GetIndexByID(tsEnd.TimeSlotID))
  226.             {
  227.                 if (DemandManager.Instance[tempts][sk.ToString()] > 0) skills.Add(sk.ToString());
  228.                 else
  229.                 {
  230.                     Boolean found = false;
  231.                     foreach (var item in per.Skill.EnumerateSkills())
  232.                     {
  233.                         if (DemandManager.Instance[tempts][item] > 0)
  234.                         {
  235.                             skills.Add(item);
  236.                             found = true;
  237.                             break;
  238.                         }
  239.                     }
  240.                     if (found == false) return false;
  241.                 }
  242.                 if ((tsm.GetIndexByID(tempts.TimeSlotID) + 1) < tsm.Count) tempts = tsm[tsm.GetIndexByID(tempts.TimeSlotID) + 1];
  243.                 else break;
  244.             }
  245.             //update matrix, create assignments
  246.             TimeSlot tempts2 = tsStart;
  247.             foreach (var item in skills)
  248.             {
  249.                 Skill tempskill = new Skill();
  250.                 tempskill[item] = 1;
  251.                 Assignment tempass = new Assignment(per, tempts2, tempskill);
  252.                 this.am.Add(tempass);
  253.                 DemandManager.Instance[tempts2][item]--;
  254.                 per.SetAvailability(tsm.GetIndexByID(tempts2.TimeSlotID), Status.Assigned);
  255.                 if ((tsm.GetIndexByID(tempts2.TimeSlotID) + 1) < tsm.Count) tempts2 = tsm[tsm.GetIndexByID(tempts2.TimeSlotID) + 1];
  256.                 else break;
  257.             }
  258.             return true;
  259.         }
  260.  
  261.         /// <summary>
  262.         /// Returns the fully filled assignment manager object
  263.         /// </summary>
  264.         /// <returns>The filled assignmentManager</returns>
  265.         public AssignmentManager GetAssingments()
  266.         {
  267.             return this.am;
  268.         }
  269.  
  270.         /// <summary>
  271.         /// Tries to switch an already assigned person to another person.
  272.         /// </summary>
  273.         /// <param name="tempts">In which timeslot to switch</param>
  274.         /// <param name="tempskill">On which skill try to find an already assigned person</param>
  275.         /// <param name="tempdm">Which demand</param>
  276.         /// <param name="depth">Maximum number of depth of the recursion</param>
  277.         /// <returns>A person who was assigned, but switched with another person. The returned person now can do the required job.</returns>
  278.         public Person Repair(TimeSlot tempts, Skill tempskill, Demand tempdm, int depth)
  279.         {
  280.             // Recursion depth
  281.             if (depth > 2)
  282.             {
  283.                 return null;
  284.             }
  285.  
  286.             TimeSlotManager tsm = TimeSlotManager.GetInstance();
  287.             Person otherPer = null;
  288.             Person person = null;
  289.             ////for (int numofskills = 1; numofskills <= 10 && tempp == null; numofskills++)
  290.             ////{
  291.             ////    tempp = pm.GetPersonWithStatus(tempts, tempskill, Status.Assigned, numofskills);
  292.             ////}
  293.  
  294.             // Search in already assigned persons
  295.             foreach (var tempp in this.pm.GetPerson(tempts, tempskill, Status.Assigned))
  296.             {
  297.                 Skill otherskill = null;
  298.                 Demand otherdemand = null;
  299.                 foreach (var item in this.am.List(tempp))
  300.                 {
  301.                     if (item.TimeSlot.TimeSlotID == tempts.TimeSlotID)
  302.                     {
  303.                         // The assigned persons current assignments skill and demand
  304.                         otherskill = item.Skill;
  305.                         otherdemand = item.Demand;
  306.                         break;
  307.                     }
  308.                 }
  309.  
  310.                 if (otherskill == null)
  311.                 {
  312.                     continue;
  313.                 }
  314.  
  315.                 otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.MustWork);
  316.                 if (otherPer == null)
  317.                 {
  318.                     otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.FreeTimeCanWork);
  319.                 }
  320.  
  321.                 // solves testset 3 but somebodies works only 2 hours
  322.                 if (otherPer == null)
  323.                 {
  324.                     otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.Available);
  325.                 }
  326.  
  327.                 // doesnot solve testset3 but makes sure nobody works less then 4 hours
  328.                 ////if ((otherPer == null) &&(tsm.IsThereEnoughContinuousTimeSlots(tempts.TimeSlotID,Properties.Settings.Default.MinMinuteToWork))) otherPer = pm.GetPersonWithStatus(tempts, otherskill, Status.Available);
  329.                 ////if (otherPer == null)  otherPer = Repair(tempts, otherskill, otherdemand, ++depth);
  330.                 if (otherPer == null)
  331.                 {
  332.                     continue;
  333.                 }
  334.  
  335.                 Assignment tempass = new Assignment(otherPer, otherdemand, tempts, otherskill);
  336.                 this.am.Add(tempass);
  337.                 otherPer.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Assigned);
  338.                 this.am.DeleteAssignment(tempdm, tempp, tempts);
  339.                 tempp.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Available);
  340.                 person = tempp;
  341.                 break;
  342.             }
  343.  
  344.             if (person == null || otherPer == null)
  345.             {
  346.                 foreach (var tempp in this.pm.GetPerson(tempts, tempskill, Status.Assigned))
  347.                 {
  348.                     Skill otherskill = null;
  349.                     Demand otherdemand = null;
  350.                     foreach (var item in this.am.List(tempp))
  351.                     {
  352.                         if (item.TimeSlot.TimeSlotID == tempts.TimeSlotID)
  353.                         {
  354.                             otherskill = item.Skill;
  355.                             otherdemand = item.Demand;
  356.                             break;
  357.                         }
  358.                     }
  359.  
  360.                     if (otherskill == null)
  361.                     {
  362.                         continue;
  363.                     }
  364.  
  365.                     otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.MustWork);
  366.                     if (otherPer == null)
  367.                     {
  368.                         otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.FreeTimeCanWork);
  369.                     }
  370.  
  371.                     // solves testset3
  372.                     if (otherPer == null)
  373.                     {
  374.                         otherPer = this.pm.GetPersonWithStatus(tempts, otherskill, Status.Available);
  375.                     }
  376.  
  377.                     // doesnt solve testset3 but nobody works less then 4 hours
  378.                     ////if ((otherPer == null) && (tsm.IsThereEnoughContinuousTimeSlots(tempts.TimeSlotID, Properties.Settings.Default.MinMinuteToWork))) otherPer = pm.GetPersonWithStatus(tempts, otherskill, Status.Available);
  379.                     if (otherPer == null)
  380.                     {
  381.                         otherPer = this.Repair(tempts, otherskill, otherdemand, ++depth);
  382.                     }
  383.  
  384.                     if (otherPer == null)
  385.                     {
  386.                         continue;
  387.                     }
  388.  
  389.                     Assignment tempass = new Assignment(otherPer, otherdemand, tempts, otherskill);
  390.                     this.am.Add(tempass);
  391.                     otherPer.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Assigned);
  392.                     this.am.DeleteAssignment(tempdm, tempp, tempts);
  393.                     tempp.SetAvailability(tsm.GetIndexByID(tempts.TimeSlotID), Status.Available);
  394.                     person = tempp;
  395.                     break;
  396.                 }
  397.             }
  398.  
  399.             if (person == null)
  400.             {
  401.                 return null;
  402.             }
  403.  
  404.             if (otherPer == null)
  405.             {
  406.                 return null;
  407.             }
  408.            
  409.             return person;
  410.         }
  411.  
  412.         /*public Person Repair(TimeSlot tempts, Skill tempskill, int depth)
  413.         {
  414.             if (depth > 3) return null;
  415.             Person tempp = null;
  416.             foreach (Person tempper in pm.GetPerson(tempts, tempskill, Status.HoursDone))
  417.             {
  418.                 Person anotherPerson = null;
  419.                 TimeSlot tsToFree = null;
  420.                 Demand otherDemand = null;
  421.                 Skill otherSkill = null;
  422.                 //get when tempper works
  423.                 foreach (Assignment ass in am.List(tempper))
  424.                 {
  425.                     //if the timeslot is not in given day skip
  426.                     if (ass.TimeSlot.Day != tempts.Day) continue;
  427.                     //find anoother available worker on that timeslot
  428.                     anotherPerson = pm.GetPerson(ass.TimeSlot, ass.Skill);
  429.                     //if found satisfying person break else continue on another timeslot
  430.                     if (anotherPerson != null)
  431.                     {
  432.                         tsToFree = ass.TimeSlot;
  433.                         otherDemand = ass.Demand;
  434.                         otherSkill = ass.Skill;
  435.                         break;
  436.                     }
  437.                 }
  438.                 //if found another worker free tempper
  439.                 if (anotherPerson != null)
  440.                 {
  441.                     tempper.SetAvailability(tsToFree.GetIndex(), Status.Available);
  442.                     Assignment corrector = new Assignment(anotherPerson, otherDemand, tsToFree, otherSkill);
  443.                     am.Add(corrector);
  444.                     anotherPerson.SetAvailability(tsToFree.GetIndex(), Status.Assigned);
  445.                     am.DeleteAssignment(otherDemand, tempper, tsToFree);
  446.                     //assign tempper to now
  447.                     tempp = tempper;
  448.                     break;
  449.                 }
  450.             }
  451.             if(tempp==null)
  452.             {
  453.                 foreach (Person tempper in pm.GetPerson(tempts, tempskill, Status.HoursDone))
  454.                 {
  455.                     foreach (Assignment ass in am.List(tempper))
  456.                     {
  457.                         if (ass.TimeSlot.Day != tempts.Day) continue;
  458.                         tempp = Repair(ass.TimeSlot, ass.Skill, depth+1);
  459.                         if (tempp != null)
  460.                         {
  461.                             tempper.SetAvailability(ass.TimeSlot.GetIndex(), Status.Available);
  462.                             Assignment corrector = new Assignment(tempp, ass.Demand, ass.TimeSlot, ass.Skill);
  463.                             am.Add(corrector);
  464.                             tempp.SetAvailability(ass.TimeSlot.GetIndex(), Status.Assigned);
  465.                             am.DeleteAssignment(ass.Demand, tempper, ass.TimeSlot);
  466.                             tempp = tempper;
  467.                             break;
  468.                         }
  469.                     }
  470.                     if (tempp != null) break;
  471.                 }
  472.             }
  473.             return tempp;
  474.         }*/
  475.     }
  476. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top