Example #1
0
        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();
        }
Example #2
0
        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);
        }