Guest User

Untitled

a guest
Oct 22nd, 2018
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.88 KB | None | 0 0
  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. }
Add Comment
Please, Sign In to add comment