async Task ExecuteGetSchedule() { Status = Constants.GetFinalSchedule; ScheduledConference result = null; await Task.Run(() => { result = _conferenceEngine.Run(_talks); }); if (result == null) { Status = Constants.InternalFailure; return; } if (result.Type == ResultType.Success) { ScheduledTalks = new ObservableCollection <Talk>(result.OrderedTalks); IsResultAvailable = true; OnPropertyRaised("ScheduledTalks"); } else { } Status = result.Type.ToString(); }
public ScheduledConference Run(IEnumerable <Talk> talks) { /* Notes: * Algorithm checks for all the followingn edge cases * - Empty list of talks passed to the engine * - Total talk time is either greater than or less than the configured time * - Talks are overlapping (See IsTalksOverlappingSessions for more explaination) * Here, the configured time is divided into different "Sessions" and algorithm fills each session one by one * Each Session knows its capacity. So, using the logic to find the sub array that matches the given SUM * Sessions are sorted to start with the smallest one */ var result = new ScheduledConference(); CleanupFromPreviousSchedule(); try { if (talks == null || !talks.Any()) { result.Type = ResultType.InvalidInput; return(result); } var totalTalkTime = talks.Sum(c => c.Duration); if (totalTalkTime > _config.TalkTime) { result.Type = ResultType.MoreTalksComparedToAvailableTime; return(result); } else if (totalTalkTime < _config.TalkTime) { result.Type = ResultType.NotEnoughTalksForTheConference; return(result); } else if (talks.Count() < _sessions.Count()) { result.Type = ResultType.OverlappingTalks; return(result); } else { // Check whether any talk overlaps the session if (IsTalksOverlappingSessions(talks)) { result.Type = ResultType.OverlappingTalks; return(result); } result.Type = ResultType.Success; } for (int i = 0; i < _sessions.Count(); i++) { // Clear previously scheduled talks if any if (_sessions[i].Talks.Any()) { _sessions[i].Talks.Clear(); } var duration = _sessions[i].Duration; var backTrackTalkId = -1; var retryCount = 0; while (!AddTalksToSession(talks, _sessions[i], backTrackTalkId)) { // set the backTrackIndex, starting from first available talk // Note: Retry using backtracking methodology retryCount++; backTrackTalkId = talks.Where(c => c.SessionId != 0).ElementAt(retryCount).Id; } // Assign sessionIds after successfully finding the Talks for the session foreach (var talk in _sessions[i].Talks) { talk.SessionId = _sessions[i].Id; } } } catch (System.Exception ex) { // Note: Should log the exception result.Type = ResultType.Exception; } _sessions = _sessions.OrderBy(c => c.Id).ToList(); var prevTalk = default(Talk); foreach (var session in _sessions) { foreach (var currentTalk in session.Talks) { if (!result.OrderedTalks.Any()) { currentTalk.StartTime = _config.GetStartTime(); } else { currentTalk.StartTime = LocalTime.Add(prevTalk.StartTime, Period.FromMinutes(prevTalk.Duration)); } result.OrderedTalks.Add(currentTalk); prevTalk = currentTalk; } } return(result); }