Advertisement
Guest User

Untitled

a guest
May 16th, 2018
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 6.04 KB | None | 0 0
  1. package ui
  2.  
  3. import java.io.File
  4.  
  5. import io.xmlParser
  6. import domain._
  7.  
  8. object Main extends App {
  9.  
  10.   def run() = {
  11.     // Load the xml files
  12.     //val scheduleInfo = xmlParser.load(new File("xml/scheduleInfo.xml"))
  13.     val scheduleInfo = xmlParser.load(new File("xml/scheduleInfoMileStone2.xml"))
  14.  
  15.     // Read nurses
  16.     val nurses = for (sInfo <- scheduleInfo) yield {
  17.       sInfo.nurses
  18.     }
  19.  
  20.     // Read schedule periods
  21.     val schedulePeriods = for (sInfo <- scheduleInfo) yield {
  22.       sInfo.schedulingPeriods
  23.     }
  24.  
  25.     // Read constraints
  26.     val constraints = for (sInfo <- scheduleInfo) yield {
  27.       sInfo.constraints
  28.     }
  29.  
  30.     // Get constraints
  31.     val maxShiftsPerDay = constraints.get.head.maxShiftsPerDay
  32.     val minRestDays = constraints.get.head.minRestDaysPerWeek
  33.     val daysConstraint = 7 - minRestDays
  34.  
  35.     // Returning the shift schedule
  36.     val result = getSchedule(nurses.get, schedulePeriods.get, maxShiftsPerDay, daysConstraint)
  37.  
  38.     val count = result.filter(x => !x.toString.equals("None"))
  39.     println(count.size)
  40.     println(result)
  41.  
  42.   }
  43.  
  44.   // Milestone 2
  45.  
  46.   def combineScheduleWithDaysOfWeek(schedule: List[Object]) : List[List[Object]] = {
  47.     val week = List(1, 2, 3, 4, 5, 6, 7)
  48.  
  49.     val comb = for (
  50.       _ <- week;
  51.       s <- schedule
  52.     ) yield s
  53.  
  54.     comb.combinations(7).toList
  55.   }
  56.  
  57.   def goCheckRestDaysConstraint(days: List[Object], week: List[Object], constraint: Int): Option[Object] = days match {
  58.     case (day :: days) => {
  59.       val result = checkRestDaysConstraint(day, days, constraint)
  60.  
  61.       if(result.equals(None)) None else goCheckRestDaysConstraint(days, week, constraint)
  62.     }
  63.     case Nil => Option(week)
  64.   }
  65.  
  66.   def checkWeeksConstraint(weeks : List[List[Object]], constraint: Int) : List[Object] = weeks match {
  67.     case (week :: weeks) => {
  68.       val result = goCheckRestDaysConstraint(week, week, constraint)
  69.       result :: checkWeeksConstraint(weeks,constraint)
  70.     }
  71.     case Nil => List()
  72.   }
  73.  
  74.   def checkRestDaysConstraint(schedule: Object, rest: List[Object], constraint: Int): Option[Object] = {
  75.       val bool = checkNurseConstraint(schedule.asInstanceOf[List[List[Schedule]]].flatten, rest, constraint)
  76.       if (bool.contains(true)) None else Option(schedule)
  77.   }
  78.  
  79.   // Milestone 1
  80.  
  81.   // Obter os nurses de acordo com o role do NurseRequirement
  82.   def getNursesByRole(nurses: Seq[Nurse], requirement: NurseRequirement, forbid: Seq[Nurse]): List[Seq[Schedule]] = {
  83.     val filteredNurses = nurses.filter(_.roles.contains(requirement.role)).filterNot(forbid.contains(_))
  84.  
  85.     val assignedNurses = for (n <- filteredNurses) yield Schedule(n, requirement.role)
  86.  
  87.     assignedNurses.combinations(requirement.number).toList
  88.   }
  89.  
  90.   // Remover Nurses duplicados
  91.   def removeDuplicates(head: Seq[Schedule], rest: Seq[Schedule]): Boolean = {
  92.     head.exists(s => rest.toString().contains(s.nurse.name))
  93.   }
  94.  
  95.   // Combinar as listas de nurses com roles diferentes
  96.   def combineLists(head: Seq[Schedule], rest: List[Seq[Schedule]]): List[Seq[Object]] = rest match {
  97.     case Nil => List()
  98.     case (h :: t) => {
  99.       if (removeDuplicates(head, h)) combineLists(head, t) else {
  100.         val listCombined = head ++ h
  101.  
  102.         listCombined :: combineLists(head, t)
  103.       }
  104.     }
  105.   }
  106.  
  107.   def combine(nurses: Seq[List[Seq[Schedule]]]): List[Seq[Seq[Object]]] = nurses match {
  108.     case h :: t => {
  109.       val result = for (n <- h) yield {
  110.         for (l <- t) yield combineLists(n, l)
  111.       }
  112.  
  113.       combine(t) ::: result
  114.     }
  115.     case Nil => List()
  116.   }
  117.  
  118.   // Obter o escalonamento para os NurseRequirement definidos
  119.   def go(nurses: Seq[Nurse], reqs: Seq[NurseRequirement]): Seq[Object] = {
  120.     val m = reqs.map(r => getNursesByRole(nurses, r, List()))
  121.  
  122.     if (reqs.size == 1) m.flatten else {
  123.       val result = combine(m).flatten
  124.  
  125.       result.flatten
  126.     }
  127.   }
  128.  
  129.   def addTwoLists(first: Seq[Object], second: Seq[Object]): Seq[List[Object]] = {
  130.     for (
  131.       f <- first;
  132.       s <- second
  133.     ) yield {
  134.       f :: s :: Nil
  135.     }
  136.   }
  137.  
  138.   def shiftCombinations(schedule: Seq[Seq[Object]]): Seq[Object] = schedule match {
  139.     case Nil => List()
  140.     case h :: t :: tm => {
  141.       val result = addTwoLists(h, t)
  142.       shiftCombinations(result :: tm)
  143.     }
  144.     case h :: Nil => List(h).flatten
  145.   }
  146.  
  147.   def checkNurseConstraint(n: Object, rest: Object, constraint: Int): Seq[Boolean] = {
  148.     for (o <- n.asInstanceOf[List[Schedule]]) yield {
  149.       val count = rest.toString.sliding(o.nurse.name.size).count(_ == o.nurse.name)
  150.       if (count >= constraint) true else false
  151.     }
  152.   }
  153.  
  154.   def checkConstraints(original: Object, result: Object, constraint: Int): Option[Object] = result match {
  155.     case (h: Object) :: (t: Object) => {
  156.       val bool = checkNurseConstraint(h, t, constraint)
  157.       if (bool.contains(true)) {
  158.         None
  159.       } else {
  160.         checkConstraints(original, t, constraint)
  161.       }
  162.  
  163.     }
  164.     case Nil => Option(original)
  165.   }
  166.  
  167.   def getSchedule(nurses: Seq[Nurse], periods: Seq[SchedulingPeriod], maxShiftsPerDay: Int, minRestDays: Int): Seq[Object] = {
  168.     val results = for (p <- periods) yield go(nurses, p.nurseRequirements)
  169.  
  170.     val combined = shiftCombinations(results)
  171.  
  172.     if (periods.size > 2) {
  173.       val sh = flattenShift(combined)
  174.       val constraints = for (shift <- sh) yield checkConstraints(shift, shift, maxShiftsPerDay)
  175.       val result = constraints.flatten
  176.  
  177.       val combineSchedule = combineScheduleWithDaysOfWeek(result)
  178.  
  179.       checkWeeksConstraint(combineSchedule, minRestDays)
  180.  
  181.     } else {
  182.       val constraints = for (shift <- combined) yield checkConstraints(shift, shift, maxShiftsPerDay)
  183.       val result = constraints.flatten.toList
  184.  
  185.       val combineSchedule = combineScheduleWithDaysOfWeek(result)
  186.  
  187.       checkWeeksConstraint(combineSchedule, minRestDays)
  188.     }
  189.   }
  190.  
  191.   def flattenShift(sch: Seq[Object]): List[Object] = sch match {
  192.     case ((h: List[Object]) :: (t: List[Object])) :: tm => {
  193.       (h ++ t).toList :: flattenShift(tm)
  194.     }
  195.     case Nil => List()
  196.   }
  197.  
  198.   run
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement