Group scheduling Scheduling tasks to actors (people, CPUs, machines etc) is a problem that one encounters very often in practice. In this small exercise, we practice how to solve such a problem by using recursive problem solving. More specifically, we solve the following problem: We are organizing a course and have n� tutorial groups. To run the groups, we are hiring m� teaching assistants. Due to other responsibilities, an assistant is not necessarily able to teach all possible tutorial groups but has a set of groups that s/he can teach. We call this set of possible groups the preferences of the assistant. Is it possible to assign each tutorial group one assistant in a way that (i) all the assistants' preferences are respected, and (ii) each assistant teaches at most one tutorial group?Needless to say, this a very simplified version of the problem; in real life, some groups need more assistants, some assistants can teach more groups, consecutive group times for an assistant should be avoided etc... Your tasks Implement the recursive part, marked with ??? in the scheduler.schedule method. 3-4 lines of code should be enough. Please use Scala to write code package groupScheduling: import groupSchedulingPreferences._ /** * A simple scheduler that assigns assistants to tutorial groups. */ /** * Schedule assistants to a set of tutorial groups. * Each tutorial group should have exactly one assistant and * each assistant can only teach at most one group. * In addition, assistants' preferences should be respected. * @param preferences the container object containing all the groups and assistants' preferences * @return An assignment from groups to assistants that fulfill the above conditions, or * None if it is not possible to assign an assistant to each group. */ def schedule[A, G](preferences: Preferences[A, G]): Option[Map[G, A]] = /* The inner function that does all the actual work. * @param freeGroups the set of groups that do not yet have an assistant * @param freeAssistants the set of assistants that have not been assigned to any group */ def inner(freeGroups: Set[G], freeAssistants: Set[A]): Option[Map[G, A]] = /* No free groups that lack an assistant? Return an empty group assignment. Base case.*/ if freeGroups.isEmpty then Some(Map[G, A]()) /* Are there more free groups than available assistants? No solution can be found*/ else if freeAssistants.size < freeGroups.size then None else /* Find a group that has a smallest number of assistants who can teach the group */ val chosenGroup = freeGroups.minBy(group => preferences.assistantsForGroup(group).intersect(freeAssistants).size) /* .. and all the assistants that can teach the chosen group */ val potentialAssistants = preferences.assistantsForGroup(chosenGroup).intersect(freeAssistants) /* No-one can take the group, therefore no schedule is possible. * Return None to indicate this. */ if potentialAssistants.isEmpty then None else /* Iterate over all potential assistants. * For each such assistant, (recursively) test if a solution can be found * in the case the assistant is assigned to chosenGroup; that is, test if there is a solution * when chosenGroup is removed from the free groups set and the assistant is removed from * the free assistants set. * If finding a solution to this reduced instance is possible, * set sol to this Some solution extended with the information that chosenGroup is being taught by that assistant. * If no such solution can be found, let sol be None */ var sol : Option[Map[G,A]] = None // YOUR SOLUTION HERE ??? sol // Return sol end if end inner inner(preferences.groups.toSet, preferences.assistants) end schedule /** * Test if sol is a valid solution to the scheduling problem, * meaning that all the groups are assigned an assistant and * each assistant teaches at most one group. */ def isValidSolution[A, G](sol: Map[G, A], prefs: Preferences[A, G]): (Boolean, String) = if sol.keySet != prefs.groups.toSet then (false, "The set of groups does not match") else sol.find((group, assistant) => !prefs.assistants.contains(assistant)) match case Some(group,assistant) => (false, s"Assistant '$assistant' is not mentioned in the original preferences") case None => sol.groupBy(_._2).iterator.find((_,assignment)=>assignment.size > 1) match case Some(assistant,_) => (false, s"Assistant '$assistant' is assigned to more than one group") case None => (true,"") end if end isValidSolution
Group scheduling Scheduling tasks to actors (people, CPUs, machines etc) is a problem that one encounters very often in practice. In this small exercise, we practice how to solve such a problem by using recursive problem solving. More specifically, we solve the following problem: We are organizing a course and have n� tutorial groups. To run the groups, we are hiring m� teaching assistants. Due to other responsibilities, an assistant is not necessarily able to teach all possible tutorial groups but has a set of groups that s/he can teach. We call this set of possible groups the preferences of the assistant. Is it possible to assign each tutorial group one assistant in a way that (i) all the assistants' preferences are respected, and (ii) each assistant teaches at most one tutorial group?Needless to say, this a very simplified version of the problem; in real life, some groups need more assistants, some assistants can teach more groups, consecutive group times for an assistant should be avoided etc... Your tasks Implement the recursive part, marked with ??? in the scheduler.schedule method. 3-4 lines of code should be enough. Please use Scala to write code package groupScheduling: import groupSchedulingPreferences._ /** * A simple scheduler that assigns assistants to tutorial groups. */ /** * Schedule assistants to a set of tutorial groups. * Each tutorial group should have exactly one assistant and * each assistant can only teach at most one group. * In addition, assistants' preferences should be respected. * @param preferences the container object containing all the groups and assistants' preferences * @return An assignment from groups to assistants that fulfill the above conditions, or * None if it is not possible to assign an assistant to each group. */ def schedule[A, G](preferences: Preferences[A, G]): Option[Map[G, A]] = /* The inner function that does all the actual work. * @param freeGroups the set of groups that do not yet have an assistant * @param freeAssistants the set of assistants that have not been assigned to any group */ def inner(freeGroups: Set[G], freeAssistants: Set[A]): Option[Map[G, A]] = /* No free groups that lack an assistant? Return an empty group assignment. Base case.*/ if freeGroups.isEmpty then Some(Map[G, A]()) /* Are there more free groups than available assistants? No solution can be found*/ else if freeAssistants.size < freeGroups.size then None else /* Find a group that has a smallest number of assistants who can teach the group */ val chosenGroup = freeGroups.minBy(group => preferences.assistantsForGroup(group).intersect(freeAssistants).size) /* .. and all the assistants that can teach the chosen group */ val potentialAssistants = preferences.assistantsForGroup(chosenGroup).intersect(freeAssistants) /* No-one can take the group, therefore no schedule is possible. * Return None to indicate this. */ if potentialAssistants.isEmpty then None else /* Iterate over all potential assistants. * For each such assistant, (recursively) test if a solution can be found * in the case the assistant is assigned to chosenGroup; that is, test if there is a solution * when chosenGroup is removed from the free groups set and the assistant is removed from * the free assistants set. * If finding a solution to this reduced instance is possible, * set sol to this Some solution extended with the information that chosenGroup is being taught by that assistant. * If no such solution can be found, let sol be None */ var sol : Option[Map[G,A]] = None // YOUR SOLUTION HERE ??? sol // Return sol end if end inner inner(preferences.groups.toSet, preferences.assistants) end schedule /** * Test if sol is a valid solution to the scheduling problem, * meaning that all the groups are assigned an assistant and * each assistant teaches at most one group. */ def isValidSolution[A, G](sol: Map[G, A], prefs: Preferences[A, G]): (Boolean, String) = if sol.keySet != prefs.groups.toSet then (false, "The set of groups does not match") else sol.find((group, assistant) => !prefs.assistants.contains(assistant)) match case Some(group,assistant) => (false, s"Assistant '$assistant' is not mentioned in the original preferences") case None => sol.groupBy(_._2).iterator.find((_,assignment)=>assignment.size > 1) match case Some(assistant,_) => (false, s"Assistant '$assistant' is assigned to more than one group") case None => (true,"") end if end isValidSolution
Computer Networking: A Top-Down Approach (7th Edition)
7th Edition
ISBN:9780133594140
Author:James Kurose, Keith Ross
Publisher:James Kurose, Keith Ross
Chapter1: Computer Networks And The Internet
Section: Chapter Questions
Problem R1RQ: What is the difference between a host and an end system? List several different types of end...
Related questions
Question
Group scheduling
Scheduling tasks to actors (people, CPUs, machines etc) is a problem that one encounters very often in practice.
Is it possible to assign each tutorial group one assistant in a way that (i) all the assistants' preferences are respected, and (ii) each assistant teaches at most one tutorial group?Needless to say, this a very simplified version of the problem; in real life, some groups need more assistants, some assistants can teach more groups, consecutive group times for an assistant should be avoided etc...
In this small exercise, we practice how to solve such a problem by using recursive problem solving. More specifically, we solve the following problem:
We are organizing a course and have n� tutorial groups. To run the groups, we are hiring m� teaching assistants. Due to other responsibilities, an assistant is not necessarily able to teach all possible tutorial groups but has a set of groups that s/he can teach. We call this set of possible groups the preferences of the assistant.Is it possible to assign each tutorial group one assistant in a way that (i) all the assistants' preferences are respected, and (ii) each assistant teaches at most one tutorial group?Needless to say, this a very simplified version of the problem; in real life, some groups need more assistants, some assistants can teach more groups, consecutive group times for an assistant should be avoided etc...
Your tasks
- Implement the recursive part, marked with ??? in the scheduler.schedule method. 3-4 lines of code should be enough.
- Please use Scala to write code
package groupScheduling:
import groupSchedulingPreferences._
/**
* A simple scheduler that assigns assistants to tutorial groups.
*/
/**
* Schedule assistants to a set of tutorial groups.
* Each tutorial group should have exactly one assistant and
* each assistant can only teach at most one group.
* In addition, assistants' preferences should be respected.
* @param preferences the container object containing all the groups and assistants' preferences
* @return An assignment from groups to assistants that fulfill the above conditions, or
* None if it is not possible to assign an assistant to each group.
*/
def schedule[A, G](preferences: Preferences[A, G]): Option[Map[G, A]] =
/* The inner function that does all the actual work.
* @param freeGroups the set of groups that do not yet have an assistant
* @param freeAssistants the set of assistants that have not been assigned to any group
*/
def inner(freeGroups: Set[G], freeAssistants: Set[A]): Option[Map[G, A]] =
/* No free groups that lack an assistant? Return an empty group assignment. Base case.*/
if freeGroups.isEmpty then Some(Map[G, A]())
/* Are there more free groups than available assistants? No solution can be found*/
else if freeAssistants.size < freeGroups.size then None
else
/* Find a group that has a smallest number of assistants who can teach the group */
val chosenGroup = freeGroups.minBy(group => preferences.assistantsForGroup(group).intersect(freeAssistants).size)
/* .. and all the assistants that can teach the chosen group */
val potentialAssistants = preferences.assistantsForGroup(chosenGroup).intersect(freeAssistants)
/* No-one can take the group, therefore no schedule is possible.
* Return None to indicate this. */
if potentialAssistants.isEmpty then None
else
/* Iterate over all potential assistants.
* For each such assistant, (recursively) test if a solution can be found
* in the case the assistant is assigned to chosenGroup; that is, test if there is a solution
* when chosenGroup is removed from the free groups set and the assistant is removed from
* the free assistants set.
* If finding a solution to this reduced instance is possible,
* set sol to this Some solution extended with the information that chosenGroup is being taught by that assistant.
* If no such solution can be found, let sol be None
*/
var sol : Option[Map[G,A]] = None
// YOUR SOLUTION HERE
???
sol // Return sol
end if
end inner
inner(preferences.groups.toSet, preferences.assistants)
end schedule
/**
* Test if sol is a valid solution to the scheduling problem,
* meaning that all the groups are assigned an assistant and
* each assistant teaches at most one group.
*/
def isValidSolution[A, G](sol: Map[G, A], prefs: Preferences[A, G]): (Boolean, String) =
if sol.keySet != prefs.groups.toSet then
(false, "The set of groups does not match")
else sol.find((group, assistant) => !prefs.assistants.contains(assistant)) match
case Some(group,assistant) =>
(false, s"Assistant '$assistant' is not mentioned in the original preferences")
case None => sol.groupBy(_._2).iterator.find((_,assignment)=>assignment.size > 1) match
case Some(assistant,_) =>
(false, s"Assistant '$assistant' is assigned to more than one group")
case None => (true,"")
end if
end isValidSolution
Expert Solution
This question has been solved!
Explore an expertly crafted, step-by-step solution for a thorough understanding of key concepts.
Step by step
Solved in 3 steps
Recommended textbooks for you
Computer Networking: A Top-Down Approach (7th Edi…
Computer Engineering
ISBN:
9780133594140
Author:
James Kurose, Keith Ross
Publisher:
PEARSON
Computer Organization and Design MIPS Edition, Fi…
Computer Engineering
ISBN:
9780124077263
Author:
David A. Patterson, John L. Hennessy
Publisher:
Elsevier Science
Network+ Guide to Networks (MindTap Course List)
Computer Engineering
ISBN:
9781337569330
Author:
Jill West, Tamara Dean, Jean Andrews
Publisher:
Cengage Learning
Computer Networking: A Top-Down Approach (7th Edi…
Computer Engineering
ISBN:
9780133594140
Author:
James Kurose, Keith Ross
Publisher:
PEARSON
Computer Organization and Design MIPS Edition, Fi…
Computer Engineering
ISBN:
9780124077263
Author:
David A. Patterson, John L. Hennessy
Publisher:
Elsevier Science
Network+ Guide to Networks (MindTap Course List)
Computer Engineering
ISBN:
9781337569330
Author:
Jill West, Tamara Dean, Jean Andrews
Publisher:
Cengage Learning
Concepts of Database Management
Computer Engineering
ISBN:
9781337093422
Author:
Joy L. Starks, Philip J. Pratt, Mary Z. Last
Publisher:
Cengage Learning
Prelude to Programming
Computer Engineering
ISBN:
9780133750423
Author:
VENIT, Stewart
Publisher:
Pearson Education
Sc Business Data Communications and Networking, T…
Computer Engineering
ISBN:
9781119368830
Author:
FITZGERALD
Publisher:
WILEY