Skip to content

Instantly share code, notes, and snippets.

@dlidstrom
Last active October 25, 2018 12:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dlidstrom/e44dd7ad716ba8aa2074909f539e1dec to your computer and use it in GitHub Desktop.
Save dlidstrom/e44dd7ad716ba8aa2074909f539e1dec to your computer and use it in GitHub Desktop.
Plan teachers week schedule
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
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