Last active
October 25, 2018 12:08
-
-
Save dlidstrom/e44dd7ad716ba8aa2074909f539e1dec to your computer and use it in GitHub Desktop.
Plan teachers week schedule
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Monday Tuesday Wednesday Thursday Friday Saturday | |
0 Mike Katie Ali Mike Katie Ali | |
1 Mike Mike Mike Mike Mike Mike | |
2 Katie Mike Mike Katie Mike Ali | |
3 Mike Katie Katie Mike Katie Ali | |
4 Katie Katie Mike Katie Katie Katie | |
5 Katie Ali Katie Katie Ali | |
6 Ali Ali Ali Ali Ali | |
7 Ali Mike Katie Ali Mike | |
Runtime: 00:00:00.1063270 | |
Backtracks: 125 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Csp | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Decider.Csp.BaseTypes; | |
using Decider.Csp.Global; | |
using Decider.Csp.Integer; | |
public static class Program | |
{ | |
public static void Main() | |
{ | |
try | |
{ | |
var teachers = new[] { "Mike", "Katie", "Ali" }; | |
var numberOfTeachers = teachers.Length; | |
var hours = Enumerable.Range(0, 8).ToList(); | |
var dayNames = new[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; | |
var monday = new List<VariableInteger>(); | |
var tuesday = new List<VariableInteger>(); | |
var wednesday = new List<VariableInteger>(); | |
var thursday = new List<VariableInteger>(); | |
var friday = new List<VariableInteger>(); | |
var saturday = new List<VariableInteger>(); | |
foreach (var period in hours) | |
{ | |
monday.Add(new VariableInteger(string.Format("Monday {0}", period), 1, numberOfTeachers)); | |
tuesday.Add(new VariableInteger(string.Format("Tuesday {0}", period), 1, numberOfTeachers)); | |
wednesday.Add(new VariableInteger(string.Format("Wednesday {0}", period), 1, numberOfTeachers)); | |
thursday.Add(new VariableInteger(string.Format("Thursday {0}", period), 1, numberOfTeachers)); | |
friday.Add(new VariableInteger(string.Format("Friday {0}", period), 1, numberOfTeachers)); | |
if (period < 5) | |
{ | |
saturday.Add(new VariableInteger(string.Format("Saturday {0}", period), 1, numberOfTeachers)); | |
} | |
} | |
var weekdays = new[] { monday, tuesday, wednesday, thursday, friday }.ToList(); | |
var days = new[] { monday, tuesday, wednesday, thursday, friday, saturday }.ToList(); | |
var week = days.SelectMany(x => x).ToList(); | |
var constraints = new List<IConstraint>(); | |
// No teacher teaches more than 3 hours per weekday | |
foreach (var teacher in Enumerable.Range(1, numberOfTeachers)) | |
{ | |
foreach (var day in weekdays) | |
{ | |
constraints.Add(new ConstraintInteger(day. | |
Select(x => x == teacher). | |
Aggregate((x, y) => x + y) <= 3)); | |
} | |
} | |
// No teacher teaches for more than two consecutive hours | |
foreach (var day in days) | |
{ | |
for (var window = 0; window < day.Count - 2; ++window) | |
{ | |
var threeHourWindow = day.Skip(window).Take(3).ToList(); | |
var q1 = threeHourWindow[0] != threeHourWindow[1] | | |
threeHourWindow[0] != threeHourWindow[2] | | |
threeHourWindow[1] != threeHourWindow[2]; | |
constraints.Add(new ConstraintInteger(q1)); | |
} | |
} | |
// No teacher teaches more than 16 hours per week | |
foreach (var teacher in Enumerable.Range(1, numberOfTeachers)) | |
{ | |
IEnumerable<ExpressionInteger> innerIq = week. | |
Select(x => x == teacher); | |
ExpressionInteger iq = innerIq | |
.Aggregate((x, y) => x + y) <= 16; | |
var q2 = new ConstraintInteger(iq); | |
constraints.Add(q2); | |
} | |
// No teacher has more than 3 morning sessions (first session) | |
// select the morning sessions | |
for (int window = 0; window < days.Count - 2; window++) | |
{ | |
var threeMorningSessions = days.Skip(window).Take(3).Select(x => x.First()).ToList(); | |
constraints.Add(new AllDifferentInteger(threeMorningSessions)); | |
} | |
// No teacher has more than 3 evening sessions (last session) | |
for (int window = 0; window < days.Count - 2; window++) | |
{ | |
var threeEveningSessions = days.Skip(window).Take(3).Select(x => x.Last()).ToList(); | |
constraints.Add(new AllDifferentInteger(threeEveningSessions)); | |
} | |
IState<int> state = new StateInteger(week, constraints); | |
state.StartSearch(out StateOperationResult searchResult); | |
Console.Write(' '); | |
for (int i = 0; i < days.Count; i++) | |
{ | |
var day = days[i]; | |
Console.Write("{0,10}", dayNames[i]); | |
} | |
Console.WriteLine(); | |
for (int hour = 0; hour < hours.Count; hour++) | |
{ | |
Console.Write(hour); | |
for (int i = 0; i < days.Count; i++) | |
{ | |
if (days[i].Count > hour) | |
{ | |
Console.Write("{0,10}", teachers[days[i][hour].Value - 1]); | |
} | |
else | |
{ | |
Console.Write(new string(' ', 10)); | |
} | |
} | |
Console.WriteLine(); | |
} | |
Console.WriteLine("Runtime:\t{0}\nBacktracks:\t{1}\n", state.Runtime, state.Backtracks); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment