예제 #1
0
        public override bool Insert(Episode ep, Random random)
        {
            /* This is where episodes are first put near their other common types
             * RULES:
             * 1) Unless it is a Work Business episode, we are not allowed to have a "split" conflict type
             * 2) We are not allowed to squish things past the threshold allowed (50% by default)
             */
            // Learn what type of case we are going to be in
            ConflictReport conflict = InsertCase(null, ep, false);

            switch (conflict.Type)
            {
            case ScheduleConflictType.NoConflict:
            {
                InsertAt(ep, conflict.Position);
                return(true);
            }

            case ScheduleConflictType.Split:
            {
                if ((ep.ActivityType != Activity.WorkBasedBusiness) & (ep.ActivityType != Activity.ReturnFromWork))
                {
                    return(false);
                }
                if (Episodes[conflict.Position].ActivityType != Activity.PrimaryWork)
                {
                    return(false);
                }
                // Since it is a primary work episode we need to split it
                var postEp = new ActivityEpisode(new TimeWindow(ep.EndTime, Episodes[conflict.Position].EndTime), Activity.PrimaryWork,
                                                 Episodes[conflict.Position].Owner)
                {
                    Zone = Episodes[conflict.Position].Zone
                };
                ((Episode)Episodes[conflict.Position]).EndTime = ep.StartTime;
                InsertAt(ep, conflict.Position + 1);
                InsertAt(postEp, conflict.Position + 2);
                return(true);
            }

            case ScheduleConflictType.Posterior:
            {
                // the given position is the element we need to go after
                Time    earlyTimeBound = Time.StartOfDay;
                Time    lateTimeBound  = Time.EndOfDay;
                Episode prior          = (Episode)Episodes[conflict.Position];
                Episode middle         = ep;
                Episode post           = (Episode)((conflict.Position < EpisodeCount - 1)
                            ? Episodes[conflict.Position + 1] : null);
                if (conflict.Position >= 1)
                {
                    earlyTimeBound = Episodes[conflict.Position - 1].EndTime;
                }
                if (EpisodeCount - conflict.Position > 2)
                {
                    lateTimeBound = Episodes[conflict.Position + 2].StartTime;
                }
                if (Insert(earlyTimeBound, prior, middle, post, lateTimeBound))
                {
                    InsertAt(ep, conflict.Position + 1);
                    return(true);
                }
                return(false);
            }

            case ScheduleConflictType.Prior:
            {
                // The given position is the element we need to go before
                Time    earlyTimeBound = Time.StartOfDay;
                Time    lateTimeBound  = Time.EndOfDay;
                Episode prior          = (Episode)(conflict.Position > 0 ? Episodes[conflict.Position - 1] : null);
                Episode middle         = ep;
                Episode post           = (Episode)Episodes[conflict.Position];
                if (conflict.Position >= 2)
                {
                    earlyTimeBound = Episodes[conflict.Position - 2].EndTime;
                }
                if (EpisodeCount - conflict.Position > 1)
                {
                    lateTimeBound = Episodes[conflict.Position + 1].StartTime;
                }
                if (Insert(earlyTimeBound, prior, middle, post, lateTimeBound))
                {
                    InsertAt(ep, conflict.Position);
                    return(true);
                }
                return(false);
            }

            case ScheduleConflictType.CompleteOverlap:
            {
                // There are no cases where a complete overlap is allowed
                return(false);
            }

            default:
            {
                // We came across a type of conflict that we do not know how to handle!
                throw new NotImplementedException(String.Format("This conflict type \"{0}\" has not been coded for yet!",
                                                                Enum.GetName(typeof(ScheduleConflictType), conflict.Type)));
            }
            }
        }
예제 #2
0
        public bool Insert(Episode ep, IZone location)
        {
            // you must be going somewhere
            if (location == null)
            {
                return(false);
            }
            ep.Zone = location;

            /*
             * This is going to be very similar to the ProjectSchedule version
             * The only difference is that we are going to take into account travel times
             */
            ConflictReport conflict = InsertCase(Owner, ep, true);

            switch (conflict.Type)
            {
            case ScheduleConflictType.NoConflict:
            {
                InsertAt(ep, conflict.Position);
                return(true);
            }

            case ScheduleConflictType.CompleteOverlap:
            case ScheduleConflictType.Split:
            {
                // At this point work-business episodes have already been dealt with in the project schedule
                // Thus everything that splits an episode is in fact not allowed!
                return(false);
            }

            case ScheduleConflictType.Posterior:
            {
                // the given position is the element we need to go after
                Time    earlyTimeBound = Time.StartOfDay + FirstTripTime;
                Time    lateTimeBound  = Time.EndOfDay;
                Episode prior          = (Episode)Episodes[conflict.Position];
                Episode middle         = ep;
                Episode post           = (Episode)((conflict.Position < EpisodeCount - 1)
                            ? Episodes[conflict.Position + 1] : null);
                // Make sure to bound the times with the padding of the travel times required
                if (conflict.Position >= 1)
                {
                    earlyTimeBound = Episodes[conflict.Position - 1].EndTime + Scheduler.TravelTime(Owner, Episodes[conflict.Position - 1].Zone,
                                                                                                    prior.Zone, prior.StartTime);
                }
                if (EpisodeCount - conflict.Position > 2)
                {
                    lateTimeBound = Episodes[conflict.Position + 2].StartTime - Scheduler.TravelTime(Owner, post.Zone, Episodes[conflict.Position + 2].Zone, post.EndTime);
                }
                if (Insert(earlyTimeBound, prior, middle, post, lateTimeBound))
                {
                    InsertAt(ep, conflict.Position + 1);
                    return(true);
                }
                return(false);
            }

            case ScheduleConflictType.Prior:
            {
                // The given position is the element we need to go before
                Time    earlyTimeBound = Time.StartOfDay + FirstTripTime;
                Time    lateTimeBound  = Time.EndOfDay;
                Episode prior          = (Episode)(conflict.Position > 0 ? Episodes[conflict.Position - 1] : null);
                Episode middle         = ep;
                Episode post           = (Episode)Episodes[conflict.Position];

                // Make sure to bound the times with the padding of the travel times required
                if (conflict.Position >= 2)
                {
                    earlyTimeBound = Episodes[conflict.Position - 2].EndTime + Scheduler.TravelTime(Owner, Episodes[conflict.Position - 2].Zone,
                                                                                                    prior.Zone, prior.StartTime);
                }
                if (EpisodeCount - conflict.Position > 1)
                {
                    lateTimeBound = Episodes[conflict.Position + 1].StartTime - Scheduler.TravelTime(Owner, post.Zone,
                                                                                                     Episodes[conflict.Position + 1].Zone, post.EndTime);
                }

                if (Insert(earlyTimeBound, prior, middle, post, lateTimeBound))
                {
                    InsertAt(ep, conflict.Position);
                    return(true);
                }
                return(false);
            }

            default:
                throw new NotImplementedException("Unknown insert conflict type!");
            }
        }