Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package ui
- import java.io.File
- import io.xmlParser
- import domain._
- object Main extends App {
- def run() = {
- // Load the xml files
- //val scheduleInfo = xmlParser.load(new File("xml/scheduleInfo.xml"))
- val scheduleInfo = xmlParser.load(new File("xml/scheduleInfoMileStone2.xml"))
- // Read nurses
- val nurses = for (sInfo <- scheduleInfo) yield {
- sInfo.nurses
- }
- // Read schedule periods
- val schedulePeriods = for (sInfo <- scheduleInfo) yield {
- sInfo.schedulingPeriods
- }
- // Read constraints
- val constraints = for (sInfo <- scheduleInfo) yield {
- sInfo.constraints
- }
- // Get constraints
- val maxShiftsPerDay = constraints.get.head.maxShiftsPerDay
- val minRestDays = constraints.get.head.minRestDaysPerWeek
- val daysConstraint = 7 - minRestDays
- // Returning the shift schedule
- val result = getSchedule(nurses.get, schedulePeriods.get, maxShiftsPerDay, daysConstraint)
- val count = result.filter(x => !x.toString.equals("None"))
- println(count.size)
- println(result)
- }
- // Milestone 2
- def combineScheduleWithDaysOfWeek(schedule: List[Object]) : List[List[Object]] = {
- val week = List(1, 2, 3, 4, 5, 6, 7)
- val comb = for (
- _ <- week;
- s <- schedule
- ) yield s
- comb.combinations(7).toList
- }
- def goCheckRestDaysConstraint(days: List[Object], week: List[Object], constraint: Int): Option[Object] = days match {
- case (day :: days) => {
- val result = checkRestDaysConstraint(day, days, constraint)
- if(result.equals(None)) None else goCheckRestDaysConstraint(days, week, constraint)
- }
- case Nil => Option(week)
- }
- def checkWeeksConstraint(weeks : List[List[Object]], constraint: Int) : List[Object] = weeks match {
- case (week :: weeks) => {
- val result = goCheckRestDaysConstraint(week, week, constraint)
- result :: checkWeeksConstraint(weeks,constraint)
- }
- case Nil => List()
- }
- def checkRestDaysConstraint(schedule: Object, rest: List[Object], constraint: Int): Option[Object] = {
- val bool = checkNurseConstraint(schedule.asInstanceOf[List[List[Schedule]]].flatten, rest, constraint)
- if (bool.contains(true)) None else Option(schedule)
- }
- // Milestone 1
- // Obter os nurses de acordo com o role do NurseRequirement
- def getNursesByRole(nurses: Seq[Nurse], requirement: NurseRequirement, forbid: Seq[Nurse]): List[Seq[Schedule]] = {
- val filteredNurses = nurses.filter(_.roles.contains(requirement.role)).filterNot(forbid.contains(_))
- val assignedNurses = for (n <- filteredNurses) yield Schedule(n, requirement.role)
- assignedNurses.combinations(requirement.number).toList
- }
- // Remover Nurses duplicados
- def removeDuplicates(head: Seq[Schedule], rest: Seq[Schedule]): Boolean = {
- head.exists(s => rest.toString().contains(s.nurse.name))
- }
- // Combinar as listas de nurses com roles diferentes
- def combineLists(head: Seq[Schedule], rest: List[Seq[Schedule]]): List[Seq[Object]] = rest match {
- case Nil => List()
- case (h :: t) => {
- if (removeDuplicates(head, h)) combineLists(head, t) else {
- val listCombined = head ++ h
- listCombined :: combineLists(head, t)
- }
- }
- }
- def combine(nurses: Seq[List[Seq[Schedule]]]): List[Seq[Seq[Object]]] = nurses match {
- case h :: t => {
- val result = for (n <- h) yield {
- for (l <- t) yield combineLists(n, l)
- }
- combine(t) ::: result
- }
- case Nil => List()
- }
- // Obter o escalonamento para os NurseRequirement definidos
- def go(nurses: Seq[Nurse], reqs: Seq[NurseRequirement]): Seq[Object] = {
- val m = reqs.map(r => getNursesByRole(nurses, r, List()))
- if (reqs.size == 1) m.flatten else {
- val result = combine(m).flatten
- result.flatten
- }
- }
- def addTwoLists(first: Seq[Object], second: Seq[Object]): Seq[List[Object]] = {
- for (
- f <- first;
- s <- second
- ) yield {
- f :: s :: Nil
- }
- }
- def shiftCombinations(schedule: Seq[Seq[Object]]): Seq[Object] = schedule match {
- case Nil => List()
- case h :: t :: tm => {
- val result = addTwoLists(h, t)
- shiftCombinations(result :: tm)
- }
- case h :: Nil => List(h).flatten
- }
- def checkNurseConstraint(n: Object, rest: Object, constraint: Int): Seq[Boolean] = {
- for (o <- n.asInstanceOf[List[Schedule]]) yield {
- val count = rest.toString.sliding(o.nurse.name.size).count(_ == o.nurse.name)
- if (count >= constraint) true else false
- }
- }
- def checkConstraints(original: Object, result: Object, constraint: Int): Option[Object] = result match {
- case (h: Object) :: (t: Object) => {
- val bool = checkNurseConstraint(h, t, constraint)
- if (bool.contains(true)) {
- None
- } else {
- checkConstraints(original, t, constraint)
- }
- }
- case Nil => Option(original)
- }
- def getSchedule(nurses: Seq[Nurse], periods: Seq[SchedulingPeriod], maxShiftsPerDay: Int, minRestDays: Int): Seq[Object] = {
- val results = for (p <- periods) yield go(nurses, p.nurseRequirements)
- val combined = shiftCombinations(results)
- if (periods.size > 2) {
- val sh = flattenShift(combined)
- val constraints = for (shift <- sh) yield checkConstraints(shift, shift, maxShiftsPerDay)
- val result = constraints.flatten
- val combineSchedule = combineScheduleWithDaysOfWeek(result)
- checkWeeksConstraint(combineSchedule, minRestDays)
- } else {
- val constraints = for (shift <- combined) yield checkConstraints(shift, shift, maxShiftsPerDay)
- val result = constraints.flatten.toList
- val combineSchedule = combineScheduleWithDaysOfWeek(result)
- checkWeeksConstraint(combineSchedule, minRestDays)
- }
- }
- def flattenShift(sch: Seq[Object]): List[Object] = sch match {
- case ((h: List[Object]) :: (t: List[Object])) :: tm => {
- (h ++ t).toList :: flattenShift(tm)
- }
- case Nil => List()
- }
- run
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement