public void SchedulingThePresenterInAPreferredTimeslotIfPossible_1Presenter3Slots1Presentation() { int expectedTimeslot = 2; var preferredTimeslotIds = new int[] { expectedTimeslot }; var presenter = Presenter.Create(1, "Test Presenter", new int[] { }, preferredTimeslotIds); var sessions = new SessionsCollection(); sessions.Add(1, null, presenter); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(new Timeslot() { Id = 1 }); timeslots.Add(new Timeslot() { Id = 2 }); timeslots.Add(new Timeslot() { Id = 3 }); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); Assert.Equal(expectedTimeslot, assignments.Single().TimeslotId); }
public void NotAssigningASessionToARoomWhenItIsNotAvailableInTimesdlot2() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(3)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10, 2)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var assignments = engine.Process(sessions, rooms, timeslots); var checkAssignment = assignments.Where(a => a.RoomId == 2 && a.TimeslotId == 2).SingleOrDefault(); assignments.WriteSchedule(); if (checkAssignment == null) Assert.Null(checkAssignment); else Assert.Null(checkAssignment.SessionId, "No session should have been assigned to room 2 during timeslot 2."); }
public void FindingTheOnlyValidTimeslotForASessionWithChainedDependencies() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); var session1 = sessions.Add(1, null, Presenter.Create(1)); var session2 = sessions.Add(2, null, Presenter.Create(3)); var session3 = sessions.Add(3, null, Presenter.Create(1)); var session4 = sessions.Add(4, null, Presenter.Create(2)); var session5 = sessions.Add(5, null, Presenter.Create(2)); var session6 = sessions.Add(6, null, Presenter.Create(2)); session5.AddDependency(session6); session4.AddDependency(session5); var rooms = new List <Room>(); rooms.Add(Room.Create(1)); rooms.Add(Room.Create(2)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1, 8.5)); timeslots.Add(Timeslot.Create(2, 9.75)); timeslots.Add(Timeslot.Create(3, 11.0)); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); var testAssignment = assignments.Single(a => a.SessionId == 4); Assert.That(testAssignment.TimeslotId, Is.EqualTo(3), "Session 4 must be in the 3rd timeslot"); }
// TODO: Document /// <summary> /// /// </summary> /// <param name="sessions"></param> public static void Validate(this IEnumerable <Entities.Session> sessions) { if (sessions == null) { throw new ArgumentNullException(nameof(sessions)); } if (sessions.Count() == 0) { throw new ArgumentException("You must have at least one session"); } if (sessions.Select(s => s.Id).Distinct().Count() != sessions.Count()) { throw new ArgumentException("Session Ids must be unique"); } if (sessions.Count(s => s.Presenters == null || s.Presenters.Count() < 1) > 0) { throw new ArgumentException("Every session must have at least one presenter."); } var presentations = new SessionsCollection(sessions); if (presentations.HaveCircularDependencies()) { throw new DependencyException("Sessions may not have circular dependencies."); } VerifyPresenterAvailabilities(sessions); }
public void ThrowingNoFeasibleSolutionIfAvailableTimeslotsForAMultiPresenterSessionDontIntersect() { // 2 presenters for one session where neither // is available to present when the other is available var presenter1 = Presenter.Create(1, new int[] { 2 }); var presenter2 = Presenter.Create(2, new int[] { 1 }); var sessions = new SessionsCollection(); sessions.Add(1, null, presenter1, presenter2); var rooms = new List <Room>() { Room.Create(1, 10) }; var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var engine = (null as IConferenceOptimizer).Create(); Assert.Throws <Exceptions.NoFeasibleSolutionsException>(() => engine.Process(sessions, rooms, timeslots)); }
public void FindingTheOnlyValidTimeslotForASessionWithChainedDependencies() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); var session1 = sessions.Add(1, null, Presenter.Create(1)); var session2 = sessions.Add(2, null, Presenter.Create(3)); var session3 = sessions.Add(3, null, Presenter.Create(1)); var session4 = sessions.Add(4, null, Presenter.Create(2)); var session5 = sessions.Add(5, null, Presenter.Create(2)); var session6 = sessions.Add(6, null, Presenter.Create(2)); session5.AddDependency(session6); session4.AddDependency(session5); var rooms = new List<Room>(); rooms.Add(Room.Create(1)); rooms.Add(Room.Create(2)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1, 8.5)); timeslots.Add(Timeslot.Create(2, 9.75)); timeslots.Add(Timeslot.Create(3, 11.0)); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); var testAssignment = assignments.Single(a => a.SessionId == 4); Assert.That(testAssignment.TimeslotId, Is.EqualTo(3), "Session 4 must be in the 3rd timeslot"); }
public void ThrowingNoFeasibleSolutionIfSpeakerWouldHaveToBeInTwoPlacesAtOnceDueTo2Sessions1Speaker1Timeslot() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(1)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(new Timeslot() { Id = 1 }); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); }
public void ReturningTheCorrectAssignmentIfTwoSpeakersAreAvailableForTwoOfTheThreeSlots() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1, new int[] { 2 })); // Not available for slot 2 sessions.Add(2, null, Presenter.Create(2, new int[] { 2 })); // Not available for slot 2 sessions.Add(3, null, Presenter.Create(3)); // Available for all but must be assigned to slot 2 var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); timeslots.Add(Timeslot.Create(3)); var assignments = engine.Process(sessions, rooms, timeslots); var checkAssignment = assignments.Where(a => a.SessionId == 3).Single(); assignments.WriteSchedule(); // Session 3 should have been assigned to slot 2 Assert.Equal(2, checkAssignment.TimeslotId); }
public void ThrowingArgumentExceptionIfDuplicatePresenterIdsWithDifferentAvailabilityCountsExist() { var presenter1 = Presenter.Create(1, new int[] { 2 }); var presenter2 = Presenter.Create(2, new int[] { 2 }); var presenter3 = Presenter.Create(1); var sessions = new SessionsCollection(); var session1 = sessions.Add(1, 1, presenter1); var session2 = sessions.Add(2, 1, presenter2); var session3 = sessions.Add(3, 1, presenter3); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var engine = (null as IConferenceOptimizer).Create(); Assert.Throws <ArgumentException>(() => engine.Process(sessions, rooms, timeslots)); }
public void ThrowingDependencyExceptionIfCircularDependenciesExist() { var presenter1 = Presenter.Create(1, new int[] { 2 }); var sessions = new SessionsCollection(); var session1 = sessions.Add(1, 1, Presenter.Create(1)); var session2 = sessions.Add(2, 1, Presenter.Create(2)); var session3 = sessions.Add(3, 1, Presenter.Create(3)); session1.AddDependency(session2); session2.AddDependency(session3); session3.AddDependency(session1); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var engine = (null as IConferenceOptimizer).Create(); Assert.Throws <Exceptions.DependencyException>(() => engine.Process(sessions, rooms, timeslots)); Assert.Throws <Exceptions.DependencyException>(() => engine.Process(sessions, rooms, timeslots)); }
public void ResultInTheSameNumberOfAssignments() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, 1, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(3)); sessions.Add(4, 1, Presenter.Create(4)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); var solution = new Solution(sessions, rooms, timeslots); while (solution.AssignmentsCompleted < sessions.Count()) { solution.AssignSessionsWithOnlyOneOption(); solution.AssignMostConstrainedSession(); } var s2 = solution.SwapAssignments(); Assert.AreEqual(solution.Assignments.Count(), s2.Assignments.Count()); }
public void PuttingSessionsInTheSameTrackIntoTheSameRoom_4Sessions1Track() { var sessions = new SessionsCollection(); sessions.Add(1, 1, Presenter.Create(1)); sessions.Add(2, 2, Presenter.Create(2)); sessions.Add(3, 1, Presenter.Create(3)); sessions.Add(4, 3, Presenter.Create(4)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); var s1RoomId = assignments.Where(a => a.SessionId == 1).Single().RoomId; var s3RoomId = assignments.Where(a => a.SessionId == 3).Single().RoomId; // Sessions with the same TopicId should be in the same room whenever possible Assert.Equal(s1RoomId, s3RoomId); }
private void Load(SessionsCollection sessions, IEnumerable <Room> rooms, IEnumerable <Timeslot> timeslots) { _sessions = sessions; _rooms = rooms; _timeslots = timeslots; _presenters = sessions.GetPresenters(); // Create the session availability matrix _sessionMatrix = new SessionAvailabilityCollection(sessions, rooms, timeslots); if (!_sessionMatrix.IsFeasible) { throw new Exceptions.NoFeasibleSolutionsException(); } // Setup the empty assignment matrix foreach (var room in rooms) { foreach (var timeslot in timeslots) { if (room.AvailableInTimeslot(timeslot.Id)) { this.Assignments.Add(new Assignment(room.Id, timeslot.Id)); } } } // Make sure there are enough slots/rooms for all of the sessions if (sessions.Count() > this.Assignments.Count()) { throw new Exceptions.NoFeasibleSolutionsException("There are not enough rooms and timeslots to accommodate all of the sessions."); } }
public void ThrowingNoFeasibleSolutionIfSpeakerWouldHaveToBeInTwoPlacesAtOnce3SessionsFor1SpeakerWith2Timeslots() { var speaker1 = Presenter.Create(1); var speaker2 = Presenter.Create(2); var sessions = new SessionsCollection(); sessions.Add(1, null, speaker1); sessions.Add(2, null, speaker1); sessions.Add(3, null, speaker2); sessions.Add(4, null, speaker1); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var engine = (null as IConferenceOptimizer).Create(); Assert.Throws <Exceptions.NoFeasibleSolutionsException>(() => engine.Process(sessions, rooms, timeslots)); }
public void AssigningAllSessions() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(2)); sessions.Add(4, null, Presenter.Create(3)); sessions.Add(5, null, Presenter.Create(3)); sessions.Add(6, null, Presenter.Create(3)); sessions.Add(7, null, Presenter.Create(3)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); rooms.Add(Room.Create(3, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); timeslots.Add(Timeslot.Create(3)); timeslots.Add(Timeslot.Create(4)); timeslots.Add(Timeslot.Create(5)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); var assignmentsWithSessions = assignments.Where(a => a.SessionId.HasValue); assignments.WriteSchedule(); Assert.That(assignmentsWithSessions.Count(), Is.EqualTo(sessions.Count()), "The wrong number of assignments were returned."); }
public void ReturningTheCorrectAssignmentIfOneSpeakerIsAvailableForOnlyOneSlot() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2, new int[] { 2, 3 })); // Only available for slot 1 sessions.Add(3, null, Presenter.Create(3)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); timeslots.Add(Timeslot.Create(3)); var assignments = engine.Process(sessions, rooms, timeslots); var checkAssignment = assignments.Where(a => a.SessionId == 2).Single(); assignments.WriteSchedule(); // Session 2 should have been assigned to slot 1 Assert.Equal(1, checkAssignment.TimeslotId); }
public void SeparatingSessionsInTheSameTrackIntoDifferentTimslots_4Sessions3Tracks() { var sessions = new SessionsCollection(); sessions.Add(1, 1, Presenter.Create(1)); sessions.Add(2, 2, Presenter.Create(2)); sessions.Add(3, 1, Presenter.Create(3)); sessions.Add(4, 3, Presenter.Create(4)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); var s1TimeslotId = assignments.Where(a => a.SessionId == 1).Single().TimeslotId; var s3TimeslotId = assignments.Where(a => a.SessionId == 3).Single().TimeslotId; Assert.That(s1TimeslotId, Is.Not.EqualTo(s3TimeslotId), "Sessions with the same TopicId should not be in the same timeslot."); }
public void NotFailIfTwoUnnamedSessionsHaveTheSameTimeslotUnavailability() { // This test exposes a bug that existed in a version // of the tool in early Oct 2018 where failing to add // a name caused a collision in naming constraints // if the same Timeslot is unavailable for multiple sessions var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1, new int[] { 2 })); sessions.Add(2, null, Presenter.Create(2, new int[] { 2 })); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); timeslots.Add(Timeslot.Create(3)); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); }
public void KeepTheOriginalAssignmentsUnchanged() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, 1, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(3)); sessions.Add(4, 1, Presenter.Create(4)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); var solution = new Solution(sessions, rooms, timeslots); while (solution.AssignmentsCompleted < sessions.Count()) { solution.AssignSessionsWithOnlyOneOption(); solution.AssignMostConstrainedSession(); } var originalSolution = solution.Assignments.Serialize(); solution.Assignments.WriteSchedule(); var s2 = solution.SwapAssignments(); var postSwapSolution = solution.Assignments.Serialize(); solution.Assignments.WriteSchedule(); Assert.AreEqual(originalSolution, postSwapSolution); }
public void AssigningAllSessions() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(2)); sessions.Add(4, null, Presenter.Create(3)); sessions.Add(5, null, Presenter.Create(3)); sessions.Add(6, null, Presenter.Create(3)); sessions.Add(7, null, Presenter.Create(3)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); rooms.Add(Room.Create(3, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); timeslots.Add(Timeslot.Create(3)); timeslots.Add(Timeslot.Create(4)); timeslots.Add(Timeslot.Create(5)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); var assignmentsWithSessions = assignments.Where(a => a.SessionId.HasValue); assignments.WriteSchedule(); Assert.That(assignmentsWithSessions.Count(), Is.EqualTo(sessions.Count()), "The wrong number of assignments were returned."); }
public void ResultInTheSameNumberOfAssignments() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, 1, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(3)); sessions.Add(4, 1, Presenter.Create(4)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); var solution = new Solution(sessions, rooms, timeslots); while (solution.AssignmentsCompleted < sessions.Count()) { solution.AssignSessionsWithOnlyOneOption(); solution.AssignMostConstrainedSession(); } var s2 = solution.SwapAssignments(); Assert.AreEqual(solution.Assignments.Count(), s2.Assignments.Count()); }
public void SeparatingSessionsInTheSameTrackIntoDifferentTimslots_4Sessions1Track() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, 1, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(3)); sessions.Add(4, 1, Presenter.Create(4)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); var s2TimeslotId = assignments.Where(a => a.SessionId == 2).Single().TimeslotId; var s4TimeslotId = assignments.Where(a => a.SessionId == 4).Single().TimeslotId; Assert.That(s2TimeslotId, Is.Not.EqualTo(s4TimeslotId), "Sessions with the same TopicId should not be in the same timeslot."); }
public void ResultInTwoDifferencesInAssignments() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, 1, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(3)); sessions.Add(4, 1, Presenter.Create(4)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); var solution = new Solution(sessions, rooms, timeslots); while (solution.AssignmentsCompleted < sessions.Count()) { solution.AssignSessionsWithOnlyOneOption(); solution.AssignMostConstrainedSession(); } var s2 = solution.SwapAssignments(); int differenceCount = 0; foreach (var a1 in solution.Assignments) { var a2 = s2.Assignments.Where(a => a.RoomId == a1.RoomId && a.TimeslotId == a1.TimeslotId).Single(); if (a1.SessionId != a2.SessionId) differenceCount++; } Assert.AreEqual(2, differenceCount); }
public void ReturningTheOnlyPossibleAssignmentIfTheSecondSessionIsDependentOnTheFirst() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); var session1 = sessions.Add(1, null, Presenter.Create(1)); var session2 = sessions.Add(2, null, Presenter.Create(1)); session2.AddDependency(session1); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1, 10)); timeslots.Add(Timeslot.Create(2, 11)); var assignments = engine.Process(sessions, rooms, timeslots); var session2Assignment = assignments.Where(a => a.SessionId.Value == 2).Single(); assignments.WriteSchedule(); Assert.That(session2Assignment.TimeslotId, Is.EqualTo(2), "Session 2 must be assigned to timeslot 2 to satisfy the dependencies."); }
public void NotAssigningASessionToARoomWhenItIsNotAvailableInTimesdlot2() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(3)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10, 2)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var assignments = engine.Process(sessions, rooms, timeslots); var checkAssignment = assignments.Where(a => a.RoomId == 2 && a.TimeslotId == 2).SingleOrDefault(); assignments.WriteSchedule(); if (checkAssignment == null) { Assert.Null(checkAssignment); } else { // No session should have been assigned to room 2 during timeslot 2 Assert.Null(checkAssignment.SessionId); } }
public void ReturnThreeIfThereAreTwoConflictsInTheTimeslot() { // 3 Rooms, 2 timeslots, 6 Sessions var sessions = new SessionsCollection(); sessions.Add(1, 1, Presenter.Create(1)); sessions.Add(2, 1, Presenter.Create(2)); sessions.Add(3, 1, Presenter.Create(2)); sessions.Add(4, 2, Presenter.Create(3)); sessions.Add(5, 3, Presenter.Create(3)); sessions.Add(6, 4, Presenter.Create(3)); var assignments = new List <Assignment>(); assignments.Add(new Assignment(1, 1, 1)); assignments.Add(new Assignment(1, 1, 2)); assignments.Add(new Assignment(2, 1, 3)); assignments.Add(new Assignment(2, 2, 4)); assignments.Add(new Assignment(3, 2, 5)); assignments.Add(new Assignment(3, 2, 6)); var target = new Timeslot() { Id = 1, DayIndex = 0, StartHour = 11.0F }; var result = target.GetTopicScore(assignments, sessions); Assert.AreEqual(3, result); }
public void SeparatingSessionsInTheSameTrackIntoDifferentTimslots_4Sessions1Track() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, 1, Presenter.Create(2)); sessions.Add(3, null, Presenter.Create(3)); sessions.Add(4, 1, Presenter.Create(4)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); var s2TimeslotId = assignments.Where(a => a.SessionId == 2).Single().TimeslotId; var s4TimeslotId = assignments.Where(a => a.SessionId == 4).Single().TimeslotId; // Sessions with the same TopicId should not be in the same timeslot Assert.NotEqual(s2TimeslotId, s4TimeslotId); }
public void ThrowingArgumentExceptionIfNoTimeslotsSupplied() { var sessions = new SessionsCollection(); sessions.Add(1, 1); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List<Timeslot>(); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ThrowingArgumentNullExceptionIfRoomsIsNull() { var sessions = new SessionsCollection(); sessions.Add(1, 1); IEnumerable<Room> rooms = null; var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ThrowingNoFeasibleSolutionIfSpeakerIsUnavailableForAllTimeslots() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1, 1)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(new Timeslot() { Id = 1 }); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ThrowingArgumentExceptionIfNoRoomsSupplied() { var sessions = new SessionsCollection(); sessions.Add(1, 1); var rooms = new List <Room>(); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ThrowingNoFeasibleSolutionsExceptionIfNoSessionsSupplied() { var sessions = new SessionsCollection(); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ThrowingArgumentNullExceptionIfRoomsIsNull() { var sessions = new SessionsCollection(); sessions.Add(1, 1, Presenter.Create(1)); IEnumerable <Room> rooms = null; var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); var engine = (null as IConferenceOptimizer).Create(); Assert.Throws <ArgumentNullException>(() => engine.Process(sessions, rooms, timeslots)); }
public void ThrowingArgumentNullExceptionIfTimeslotsIsNull() { var sessions = new SessionsCollection(); sessions.Add(1, 1); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); IEnumerable <Timeslot> timeslots = null; var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ThrowingArgumentExceptionIfNoTimeslotsSupplied() { var sessions = new SessionsCollection(); sessions.Add(1, 1); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); var engine = (null as IConferenceOptimizer).Create(); Assert.Throws <ArgumentException>(() => engine.Process(sessions, rooms, timeslots)); }
public void ThrowingArgumentExceptionIfThereIsntAtLeastOnePresenterForEachSession() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, 1); sessions.Add(new Session() { Id = 2 }); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ReturningTheOnlyPossibleAssignmentIfOneSessionRoomAndSlotAreSupplied() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); Assert.That(assignments.Count(), Is.EqualTo(1), "The wrong number of assignments were returned."); }
private static void Validate(IEnumerable <Session> sessions, IEnumerable <Room> rooms, IEnumerable <Timeslot> timeslots) { if (sessions == null) { throw new ArgumentNullException(nameof(sessions)); } if (rooms == null) { throw new ArgumentNullException(nameof(rooms)); } if (timeslots == null) { throw new ArgumentNullException(nameof(timeslots)); } if (sessions.Count() == 0) { throw new ArgumentException("You must have at least one session"); } if (timeslots.Count() == 0) { throw new ArgumentException("You must have at least one timeslot"); } if (rooms.Count() == 0) { throw new ArgumentException("You must have at least one room"); } if (sessions.Count(s => s.Presenters == null || s.Presenters.Count() < 1) > 0) { throw new ArgumentException("Every session must have at least one presenter."); } var presentations = new SessionsCollection(sessions); if (presentations.HaveCircularDependencies()) { throw new DependencyException("Sessions may not have circular dependencies."); } }
public void DistributingSessionsReasonablyAcrossTimeslotsWithNoDependencies() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); const int sessionCount = 12; for (int i = 0; i < sessionCount; i++) { sessions.Add(i, i, Presenter.Create(i)); } var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); rooms.Add(Room.Create(3, 10)); rooms.Add(Room.Create(4, 10)); rooms.Add(Room.Create(5, 10)); rooms.Add(Room.Create(6, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); timeslots.Add(Timeslot.Create(3, 11.5)); timeslots.Add(Timeslot.Create(4, 13.5)); timeslots.Add(Timeslot.Create(5, 14.75)); timeslots.Add(Timeslot.Create(6, 16.00)); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); bool hasSurplus = false; for (int t = 0; t < timeslots.Count; t++) { hasSurplus = (hasSurplus || (assignments.Count(a => a.TimeslotId == t) > 2)); } Assert.False(hasSurplus, "Sessions should be spread-out across timeslots"); }
public void SchedulingThePresenterInAPreferredTimeslotIfPossible_3Presenter3Slots3Presentation_2SpeakersPreferTheSameSlot() { int expectedTimeslot1 = 2; var preferredTimeslotIds1 = new int[] { expectedTimeslot1 }; var presenter1 = Presenter.Create(1, "Test Presenter 1", new int[] { }, preferredTimeslotIds1); int expectedTimeslot2 = 1; var preferredTimeslotIds2 = new int[] { expectedTimeslot2 }; var presenter2 = Presenter.Create(2, "Test Presenter 2", new int[] { }, preferredTimeslotIds2); int expectedTimeslot3 = 2; var preferredTimeslotIds3 = new int[] { expectedTimeslot3 }; var presenter3 = Presenter.Create(3, "Test Presenter 3", new int[] { }, preferredTimeslotIds3); var sessions = new SessionsCollection(); sessions.Add(1, null, presenter1); sessions.Add(2, null, presenter2); sessions.Add(3, null, presenter3); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(new Timeslot() { Id = 1 }); timeslots.Add(new Timeslot() { Id = 2 }); timeslots.Add(new Timeslot() { Id = 3 }); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); Assert.Equal(expectedTimeslot2, assignments.Single(a => a.SessionId == 2).TimeslotId); }
public void ThrowingArgumentExceptionIfThereAreMoreSessionsThanSlotsAndRooms() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); Assert.Throws <ArgumentException>(() => engine.Process(sessions, rooms, timeslots)); }
public void ThrowingNoFeasibleSolutionIfThereAreMoreSessionsThanSlotsAndRooms() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2)); var rooms = new List <Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List <Timeslot>(); timeslots.Add(Timeslot.Create(1)); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ReturningTheCorrectAssignmentIfOneSpeakerIsAvailableForOnlyOneSlot() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2, 2)); // Only available for slot 1 var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var assignments = engine.Process(sessions, rooms, timeslots); var checkAssignment = assignments.Where(a => a.SessionId == 2).Single(); assignments.WriteSchedule(); Assert.That(checkAssignment.TimeslotId, Is.EqualTo(1), "Session 2 should have been assigned to slot 1."); }
public void ReturningTheCorrectAssignmentIfTwoSpeakersAreAvailableForTwoOfTheThreeSlots() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1, 2)); // Not available for slot 2 sessions.Add(2, null, Presenter.Create(2, 2)); // Not available for slot 2 sessions.Add(3, null, Presenter.Create(3)); // Available for all but must be assigned to slot 2 var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); timeslots.Add(Timeslot.Create(3)); var assignments = engine.Process(sessions, rooms, timeslots); var checkAssignment = assignments.Where(a => a.SessionId == 3).Single(); assignments.WriteSchedule(); Assert.That(checkAssignment.TimeslotId, Is.EqualTo(2), "Session 3 should have been assigned to slot 2."); }
public void ReturnThreeIfThereAreTwoConflictsInTheTimeslot() { // 3 Rooms, 2 timeslots, 6 Sessions var sessions = new SessionsCollection(); sessions.Add(1, 1, Presenter.Create(1)); sessions.Add(2, 1, Presenter.Create(2)); sessions.Add(3, 1, Presenter.Create(2)); sessions.Add(4, 2, Presenter.Create(3)); sessions.Add(5, 3, Presenter.Create(3)); sessions.Add(6, 4, Presenter.Create(3)); var assignments = new List<Assignment>(); assignments.Add(new Assignment(1, 1, 1)); assignments.Add(new Assignment(1, 1, 2)); assignments.Add(new Assignment(2, 1, 3)); assignments.Add(new Assignment(2, 2, 4)); assignments.Add(new Assignment(3, 2, 5)); assignments.Add(new Assignment(3, 2, 6)); var target = new Timeslot() { Id = 1, DayIndex = 0, StartHour = 11.0F }; var result = target.GetTopicScore(assignments, sessions); Assert.AreEqual(3, result); }
public void AssigningAllDependenciesOfASessionPriorToThatSession() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); var session1 = sessions.Add(1, null, Presenter.Create(1)); var session2 = sessions.Add(2, null, Presenter.Create(3)); var session3 = sessions.Add(3, null, Presenter.Create(1)); var session4 = sessions.Add(4, null, Presenter.Create(2)); var session5 = sessions.Add(5, null, Presenter.Create(2)); var session6 = sessions.Add(6, null, Presenter.Create(2)); session4.AddDependency(session6); session4.AddDependency(session5); session4.AddDependency(session1); session4.AddDependency(session2); var rooms = new List<Room>(); rooms.Add(Room.Create(1)); rooms.Add(Room.Create(2)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1, 8.5)); timeslots.Add(Timeslot.Create(2, 9.75)); timeslots.Add(Timeslot.Create(3, 11.0)); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); var targetTimeslotId = assignments.Single(a => a.SessionId == 4).TimeslotId; var dependentSessionIds = new List<int>() { 1, 2, 5, 6 }; var maxTimeslotId = assignments.Where(a => dependentSessionIds.Contains(a.SessionId.Value)).Max(a => a.TimeslotId); Assert.That(maxTimeslotId, Is.LessThan(targetTimeslotId), "All dependent sessions must assigned earlier than the dependency session."); }
private static void Validate(IEnumerable<Session> sessions, IEnumerable<Room> rooms, IEnumerable<Timeslot> timeslots) { if (sessions == null) throw new ArgumentNullException(nameof(sessions)); if (rooms == null) throw new ArgumentNullException(nameof(rooms)); if (timeslots == null) throw new ArgumentNullException(nameof(timeslots)); if (timeslots.Count() == 0) throw new ArgumentException("You must have at least one timeslot"); if (sessions.Count() == 0) throw new ArgumentException("You must have at least one session"); if (rooms.Count() == 0) throw new ArgumentException("You must have at least one room"); if (sessions.Count(s => s.Presenters == null || s.Presenters.Count() < 1) > 0) throw new ArgumentException("Every session must have at least one presenter."); var presentations = new SessionsCollection(sessions); if (presentations.HaveCircularDependencies()) throw new Exceptions.DependencyException("Sessions may not have circular dependencies."); }
private void Load(SessionsCollection sessions, IEnumerable<Room> rooms, IEnumerable<Timeslot> timeslots) { _sessions = sessions; _rooms = rooms; _timeslots = timeslots; _presenters = sessions.GetPresenters(); // Create the session availability matrix _sessionMatrix = new SessionAvailabilityCollection(sessions, rooms, timeslots); if (!_sessionMatrix.IsFeasible) throw new Exceptions.NoFeasibleSolutionsException(); // Setup the empty assignment matrix foreach (var room in rooms) foreach (var timeslot in timeslots) if (room.AvailableInTimeslot(timeslot.Id)) this.Assignments.Add(new Assignment(room.Id, timeslot.Id)); // Make sure there are enough slots/rooms for all of the sessions if (sessions.Count() > this.Assignments.Count()) throw new Exceptions.NoFeasibleSolutionsException("There are not enough rooms and timeslots to accommodate all of the sessions."); }
public void SeparatingSessionsInTheSameTrackIntoDifferentTimslots_6Sessions3Tracks() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, 1, Presenter.Create(1)); sessions.Add(2, 2, Presenter.Create(2)); sessions.Add(3, 1, Presenter.Create(3)); sessions.Add(4, 1, Presenter.Create(4)); sessions.Add(5, null, Presenter.Create(5)); sessions.Add(6, 3, Presenter.Create(6)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1, 9.0)); timeslots.Add(Timeslot.Create(2, 10.25)); timeslots.Add(Timeslot.Create(3, 11.5)); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); var s1TimeslotId = assignments.Where(a => a.SessionId == 1).Single().TimeslotId; var s3TimeslotId = assignments.Where(a => a.SessionId == 3).Single().TimeslotId; var s4TimeslotId = assignments.Where(a => a.SessionId == 4).Single().TimeslotId; var slotsAreDifferent = ((s1TimeslotId != s3TimeslotId) && (s1TimeslotId != s4TimeslotId) && (s3TimeslotId != s4TimeslotId)); Assert.True(slotsAreDifferent, "Sessions with the same TopicId should not be in the same timeslot."); }
public void ReturningTheOnlyPossibleAssignmentIfTheSecondSessionIsDependentOnTheFirst() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); var session1 = sessions.Add(1, null, Presenter.Create(1)); var session2 = sessions.Add(2, null, Presenter.Create(1)); session2.AddDependency(session1); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1, 10)); timeslots.Add(Timeslot.Create(2, 11)); var assignments = engine.Process(sessions, rooms, timeslots); var session2Assignment = assignments.Where(a => a.SessionId.Value == 2).Single(); assignments.WriteSchedule(); Assert.That(session2Assignment.TimeslotId, Is.EqualTo(2), "Session 2 must be assigned to timeslot 2 to satisfy the dependencies."); }
public void ThrowingDependencyExceptionIfCircularDependenciesExist() { var presenter1 = Presenter.Create(1, 2); var sessions = new SessionsCollection(); var session1 = sessions.Add(1, 1, Presenter.Create(1)); var session2 = sessions.Add(2, 1, Presenter.Create(2)); var session3 = sessions.Add(3, 1, Presenter.Create(3)); session1.AddDependency(session2); session2.AddDependency(session3); session3.AddDependency(session1); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ThrowingNoFeasibleSolutionIfSpeakerWouldHaveToBeInTwoPlacesAtOnce3SessionsFor1SpeakerWith2Timeslots() { var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(1)); sessions.Add(3, null, Presenter.Create(2)); sessions.Add(4, null, Presenter.Create(1)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); rooms.Add(Room.Create(2, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(new Timeslot() { Id = 1 }); timeslots.Add(new Timeslot() { Id = 2 }); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); assignments.WriteSchedule(); }
public void ThrowingNoFeasibleSolutionIfAvailableTimeslotsForAMultiPresenterSessionDontIntersect() { // 2 presenters for one session where neither // is available to present when the other is available var presenter1 = Presenter.Create(1, 2); var presenter2 = Presenter.Create(2, 1); var sessions = new SessionsCollection(); sessions.Add(1, null, presenter1, presenter2); var rooms = new List<Room>() { Room.Create(1, 10) }; var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); timeslots.Add(Timeslot.Create(2)); var engine = (null as IConferenceOptimizer).Create(); var assignments = engine.Process(sessions, rooms, timeslots); }
public void ThrowingNoFeasibleSolutionIfThereAreMoreSessionsThanSlotsAndRooms() { var engine = (null as IConferenceOptimizer).Create(); var sessions = new SessionsCollection(); sessions.Add(1, null, Presenter.Create(1)); sessions.Add(2, null, Presenter.Create(2)); var rooms = new List<Room>(); rooms.Add(Room.Create(1, 10)); var timeslots = new List<Timeslot>(); timeslots.Add(Timeslot.Create(1)); var assignments = engine.Process(sessions, rooms, timeslots); }