Пример #1
0
 /// <summary>
 /// To call before starting a new occurence of the same simulation.
 /// </summary>
 public virtual void PrepareForNextOccurrence()
 {
     this.remainingDuration = this.Duration.XValue;
     this.lastProcessTime   = this.simulationTimeArrives;
     //if (this.simulationCrewMembersAssigned == null) this.simulationCrewMembersAssigned = new List<CrewMember>();
     //else this.crewMembersAssigned.Clear();	//TODO: Find out if we want to clear the list at this point
 }
Пример #2
0
        /// <summary>
        /// Generates the concrete value based on its statistical distribution and a random number,
        /// and assign it to <see cref="XValue"/>.
        /// </summary>
        /// <param name="rand">A random number generator.</param>
        /// <returns>The concrete value generated, ≥ 0</returns>
        public SimulationTime NextValue(Random rand)
        {
            switch (this.probabilityDistribution)
            {
            case ProbabilityDistribution.Exponential:
                this.xValue = -Math.Log(1.0 - rand.NextDouble()) * mode;                                //mode == mean == 1/lambda (where lamda is the rate parameter)
                return(this.xValue);

            case ProbabilityDistribution.Triangular:
                //TODO:Optimise (e.g. helper variables)	//Try to implement with integers?
                var u     = rand.NextDouble();
                var minS  = this.min.TotalSeconds;
                var modeS = this.mode.TotalSeconds;
                var maxS  = this.max.TotalSeconds;
                if (u <= ((modeS - minS) / (maxS - minS)))
                {
                    this.xValue = new SimulationTime(TimeUnit.Seconds, minS + Math.Sqrt((u * (maxS - minS) * (modeS - minS))));
                }
                else
                {
                    this.xValue = new SimulationTime(TimeUnit.Seconds, maxS - Math.Sqrt(((1.0 - u) * (maxS - minS) * (maxS - modeS))));
                }
                this.xValue.Unit = this.Unit;
                return(this.xValue);

            case ProbabilityDistribution.Constant:                      //Nothing to do
            default:
                return(this.xValue);
            }
        }
Пример #3
0
 /// <summary>
 /// Reset to the default parameters of the parent Task, except for readonly attributes (e.g. this.id) and lists.
 /// </summary>
 public void Reset()
 {
     if (this.refTask == null)
     {
         this.name     = "!Invalid";
         this.TaskType = (int)default(StandardTaskType);
         this.taskInterruptionPolicy     = TaskInterruptionPolicies.Undefined;
         this.phaseInterruptionPolicy    = PhaseInterruptionPolicies.Undefined;
         this.scenarioInterruptionPolicy = ScenarioInterruptionPolicies.Undefined;
         return;
     }
     this.InternalId = refTask.InternalId;
     this.name       = this.refTask.name;
     this.TaskType   = this.refTask.taskType;
     //this.systemTask = this.refTask.systemTask;
     this.autoExpandToAllCrewmen = this.refTask.autoExpandToAllCrewmen;
     this.RelativeDate           = this.refTask.relativeDate;
     this.DateOffset             = this.refTask.DateOffset;
     this.StartDate                  = this.refTask.StartDate;
     this.relativeTime               = this.refTask.relativeTime;
     this.DailyHourStart             = this.refTask.DailyHourStart;
     this.DailyHourEnd               = this.refTask.DailyHourEnd;
     this.onHolidays                 = this.refTask.onHolidays;
     this.Duration                   = this.refTask.Duration;
     this.taskInterruptionPolicy     = this.refTask.taskInterruptionPolicy;
     this.phaseInterruptionPolicy    = this.refTask.phaseInterruptionPolicy;
     this.scenarioInterruptionPolicy = this.refTask.scenarioInterruptionPolicy;
     this.interruptionErrorPolicy    = this.refTask.interruptionErrorPolicy;
     this.priority                   = this.refTask.priority;
     this.numberOfCrewmenNeeded      = this.refTask.numberOfCrewmenNeeded;
     this.Rotation                   = this.refTask.Rotation;
     this.description                = this.refTask.description;
     this.duplicatesPolicy           = this.refTask.duplicatesPolicy;
 }
Пример #4
0
        /// <summary>
        /// Check the different time constraints to tell when the task will next be allowed to be resumed.
        /// </summary>
        /// <param name="eventTime">A simulation time</param>
        /// <param name="allowCurrentTime">Gives the possibility to use the given simulation time</param>
        /// <returns>A simulation time in the relative future when the task is allowed to run</returns>
        public SimulationTime NextPossibleResume(SimulationTime eventTime, bool allowCurrentTime = true)
        {
            var workStart = eventTime.NextDayTime(this.DailyHourStart, allowCurrentTime);
            var workEnd   = eventTime.NextDayTime(this.DailyHourEnd, allowCurrentTime);

            if ((workStart < workEnd) || (eventTime >= workEnd))
            {
                eventTime = workStart;                  //TimeWindow, next day
            }
            else if (!allowCurrentTime)
            {
                eventTime = eventTime.NextUp();
            }
            if ((!this.onHolidays) && eventTime.IsSunday)
            {
                eventTime = eventTime.NextWeekTime(SimulationTime.OneDay, allowCurrentTime: false);                     //Next monday
                workStart = eventTime.NextDayTime(this.DailyHourStart);
                workEnd   = eventTime.NextDayTime(this.DailyHourEnd);
                if ((workStart < workEnd) || (eventTime >= workEnd))
                {
                    eventTime = workStart;                      //TimeWindow, next day
                }
            }
            return(eventTime);
        }
Пример #5
0
 /// <summary>
 /// Call <see cref="DismissTask"/> for all tasks currently assigned to the crewman.
 /// </summary>
 /// <param name="time">Current simulation time</param>
 /// <param name="phase">Current phase</param>
 public void DismissAllTasks(SimulationTime time, Phase phase)
 {
     while (this.tasksAssigned.Count > 0)
     {
         DismissTask(time, phase, this.tasksAssigned[0]);
     }
 }
Пример #6
0
 /// <summary>
 /// Assign the crewman to a running task.
 /// This starts by calling <see cref="RefreshStatus"/>, and increase <see cref="CurrentLoad"/>.
 /// </summary>
 /// <param name="time">Current simulation time</param>
 /// <param name="phase">Current phase</param>
 /// <param name="task">New task</param>
 public virtual void AssignTask(SimulationTime time, Phase phase, SimulationTask task)
 {
     RefreshStatus(time);
     this.tasksAssigned.Add(task);
     if (task.IsWork)
     {
         currentLoad++;
     }
 }
Пример #7
0
        /// <summary>
        /// To call when the time since last update needs to be discarded.
        /// Used for instance when a task has to start a bit before than current time and be shortened accordingly.
        /// </summary>
        /// <param name="currentTime">Current simulation time.</param>
        public virtual void DiscardUntilNow(SimulationTime currentTime)
        {
            var duration = currentTime - this.lastProcessTime;

            if (duration.Positive)
            {
                this.remainingDuration -= duration;
            }
            this.lastProcessTime = currentTime;
        }
Пример #8
0
 /// <summary>
 /// Remove a running or completed task from the crewman.
 /// This starts by calling <see cref="RefreshStatus"/>, and decrease <see cref="CurrentLoad"/>.
 /// </summary>
 /// <param name="time">Current simulation time</param>
 /// <param name="phase">Current phase</param>
 /// <param name="task">Task dismissed</param>
 public virtual void DismissTask(SimulationTime time, Phase phase, SimulationTask task)
 {
     RefreshStatus(time);
     this.tasksAssigned.Remove(task);
     if (task.IsWork)
     {
         this.currentLoad--;
         Debug.Assert(currentLoad >= 0, "Current load must be positive!");
         if (this.currentLoad < 0)
         {
             this.currentLoad = 0;
         }
     }
 }
Пример #9
0
        /// <summary>
        /// To call when the task has been active until now, in order to update the statistics of the task (e.g. remaining duration).
        /// Does not call <see cref="Crewman.RefreshStatus"/> by default.
        /// </summary>
        /// <param name="currentTime">Current simulation time.</param>
        /// <param name="phase">Phase during which the process occurs.</param>
        /// <returns>A positive duration if the task was processed, <see cref="SimulationTime.Zero"/> otherwise.</returns>
        public virtual SimulationTime ProcessUntilNow(SimulationTime currentTime, Phase phase)
        {
            var previousProcessTime = this.lastProcessTime;

            this.lastProcessTime = currentTime;
            if (this.simulationCrewmenAssigned.Count >= this.numberOfCrewmenNeeded)
            {
                var duration = currentTime - previousProcessTime;
                if (duration.Positive)
                {
                    this.remainingDuration -= duration;
                    Debug.Assert((this.taskType == (int)StandardTaskType.InternalWait) || Allowed(phase), "A task must not run in phases where it is not allowed!");
                    Debug.Assert(duration <= currentTime - phase.simulationTimeBegin, "A task cannot last longer than its phase!");
                    return(duration);
                }
            }
            return(SimulationTime.Zero);
        }
Пример #10
0
 /// <summary>
 /// Refresh all status parameters of the crewman such as cumulated work time.
 /// This is called automatically by <see cref="AssignTask"/>, <see cref="DismissTask"/>,
 /// at at the end of each phase transition by <see cref="Simulator"/>.
 /// Furthermore, this should be called by implementations of <see cref="SimManning.Domain.DomainDispatcher"/>
 /// before deciding which crewmen should take a job.
 /// </summary>
 /// <remarks>Implementations of domains should override this function to include their domain-specific parameters</remarks>
 /// <param name="time">Current simulation time</param>
 /// <returns>true if a refresh was needed, false otherwise</returns>
 public virtual bool RefreshStatus(SimulationTime time)
 {        //In the base class, we only have cumulatedWorkTime
     Debug.Assert(this.lastRefreshTime <= time, "Simulation cannot go back in time!");
     if (time == this.lastRefreshTime)
     {
         return(false);
     }
     //Debug.WriteLine("?\t{0}\tRefreshStatus\t{1}", time, this);
     if (this.currentLoad > 0)
     {            //The crewman is currently working
         var offset = time - this.lastRefreshTime;
         if (offset.Positive)
         {
             this.cumulatedWorkTime += offset;
         }
     }
     this.lastRefreshTime = time;
     return(true);
 }
Пример #11
0
 public void Validate()
 {
     if ((this.Unit == TimeUnit.Undefined) || (this.mode < SimulationTime.Zero))
     {
         this.mode = SimulationTime.Zero;
     }
     if (this.min > this.mode)
     {
         this.min = this.mode;
     }
     else if (this.min < SimulationTime.Zero)
     {
         this.min = SimulationTime.Zero;
     }
     if ((this.max != SimulationTime.Zero) && (this.max < this.mode))
     {
         this.max = this.mode;
     }
 }
Пример #12
0
 public TimeDistribution(TimeUnit timeUnit, SimulationTime min, SimulationTime mode, SimulationTime max)
 {
     this.min  = min;
     this.mode = mode;
     this.max  = max;
     if (this.mode <= SimulationTime.Zero)
     {
         this.probabilityDistribution = ProbabilityDistribution.Constant;
         this.min = this.max = this.mode = SimulationTime.Zero;
     }
     else if (this.max <= SimulationTime.Zero)
     {
         this.probabilityDistribution = ProbabilityDistribution.Exponential;
         this.min = this.max = SimulationTime.Zero;
     }
     else
     {
         if (this.min > this.mode)
         {
             this.min = this.mode;
         }
         else if (this.min < SimulationTime.Zero)
         {
             this.min = SimulationTime.Zero;
         }
         if (this.max < this.mode)
         {
             this.max = this.mode;
         }
         if ((this.min < this.mode) || (this.mode < this.max))
         {
             this.probabilityDistribution = ProbabilityDistribution.Triangular;
         }
         else
         {
             this.probabilityDistribution = ProbabilityDistribution.Constant;
         }
     }
     this.xValue = this.mode;
     this.Unit   = timeUnit;
 }
Пример #13
0
 public TimeDistribution(TimeUnit timeUnit, SimulationTime constantValue) :
     this(timeUnit, constantValue, constantValue, constantValue)
 {
 }
Пример #14
0
 public TimeDistribution(SimulationTime min, SimulationTime mode, SimulationTime max) :
     this(mode.Unit, min, mode, max)
 {
 }
Пример #15
0
 /// <summary>
 /// Tells if the task is allowed to run at this time of the day.
 /// </summary>
 /// <param name="eventTime">A date/time; only the time of the day will be used.</param>
 /// <returns>true if the task is allowed to run at this time of the day, false otherwise.</returns>
 public bool IsAllowedTime(SimulationTime eventTime)
 {
     return(eventTime.InDayTimeInterval(this.DailyHourStart, this.DailyHourEnd) &&
            (this.onHolidays || (!eventTime.IsSunday) ||
             (!eventTime.NextDown().IsSunday)));                         //Case of Sunday at 00:00
 }
Пример #16
0
 /// <summary>
 /// To be called before each replication to reset some parameters.
 /// Automatically called by <see cref="SimulationDataSet.PrepareForNextReplication"/>
 /// </summary>
 protected internal virtual void PrepareForNextReplication()
 {
     this.lastRefreshTime   = SimulationTime.MinValue;
     this.cumulatedWorkTime = SimulationTime.Zero;
     this.tasksAssigned.Clear();
 }
Пример #17
0
 public TimeDistribution(SimulationTime constantValue) :
     this(constantValue.Unit, constantValue, constantValue, constantValue)
 {
 }
Пример #18
0
 public void Validate()
 {
                 #pragma warning disable 618     //Disable warning for obsolete "DoNotInterrupt"
     if (this.phaseInterruptionPolicy == PhaseInterruptionPolicies.DoNotInterrupt)
                 #pragma warning restore 618
     {            //Back compatibility
         this.taskInterruptionPolicy  = TaskInterruptionPolicies.ContinueOrResumeWithError;
         this.phaseInterruptionPolicy = PhaseInterruptionPolicies.ContinueOrDropWithError;
     }
     if (this.taskType.IsSubCodeOf(StandardTaskType.ExternalCondition) ||
         this.taskType.IsSubCodeOf(StandardTaskType.CriticalEvents))
     {
         this.taskInterruptionPolicy     = TaskInterruptionPolicies.DropWithError;
         this.phaseInterruptionPolicy    = PhaseInterruptionPolicies.ResumeOrDropWithError;
         this.scenarioInterruptionPolicy = ScenarioInterruptionPolicies.DropWithoutError;
         //this.relativeTime = Task.RelativeTimeType.TimeWindow;
         //this.dailyHourStart = TimeSpan.Zero;
         //this.dailyHourEnd = TimeSpan.Zero;
         //this.onHolidays = true;
         this.autoExpandToAllCrewmen = false;
         this.numberOfCrewmenNeeded  = 0;
         this.Rotation         = SimulationTime.Zero;
         this.duplicatesPolicy = TaskDuplicatesPolicy.MergeDuplicates;
         this.masterTasks.Clear();
         this.parallelTasks.Clear();
         this.priority = 700;
     }
     else
     {
         this.slaveTasks.Clear();                        //Only external conditions can have slaves
         if (this.relativeDate == RelativeDateType.TriggeredByAnEvent)
         {
             this.StartDate        = TimeDistribution.Zero;
             this.Duration         = new TimeDistribution(SimulationTime.ArbitraryLargeDuration);
             this.duplicatesPolicy = TaskDuplicatesPolicy.MergeDuplicates;
             this.parallelTasks.Clear();
             this.phaseTypes.Clear();
         }
         else
         {
             this.masterTasks.Clear();
         }
         if (this.phaseInterruptionPolicy == PhaseInterruptionPolicies.WholePhase)
         {
             this.DailyHourStart = SimulationTime.Zero;
             this.DailyHourEnd   = SimulationTime.Zero;
             this.RelativeDate   = RelativeDateType.RelativeStartFromStartOfPhase;
             this.StartDate      = TimeDistribution.Zero;
             this.Duration       = new TimeDistribution(SimulationTime.ArbitraryLargeDuration);
             this.parallelTasks.Clear();
         }
         else if ((this.phaseInterruptionPolicy == PhaseInterruptionPolicies.Obligatory) &&
                  (this.relativeDate != RelativeDateType.RelativeStartFromStartOfPhase) &&
                  (this.relativeDate != RelativeDateType.RelativeStartFromEndOfPhase) &&
                  (this.relativeDate != RelativeDateType.RelativeStopFromEndOfPhase))
         {
             this.phaseInterruptionPolicy = PhaseInterruptionPolicies.DropWithError;
         }
         switch (this.relativeDate)
         {
         case RelativeDateType.RelativeStopFromEndOfPhase:
         case RelativeDateType.RelativeStartFromStartOfPhase:
         case RelativeDateType.RelativeStartFromEndOfPhase:
         case RelativeDateType.RelativeStartFromPreviousStart:
             this.DateOffset = default(TimeDistribution);
             break;
         }
         if (((this.relativeDate == RelativeDateType.AbsoluteStartMonthDay) ||
              (this.relativeDate == RelativeDateType.AbsoluteStartWeekDay)))
         {
             this.StartDate.Unit = TimeUnit.Days;
         }
         if (this.autoExpandToAllCrewmen)
         {
             this.numberOfCrewmenNeeded = 1;
             this.Rotation = SimulationTime.Zero;
         }
     }
     this.Duration.Validate();
     this.StartDate.Validate();
 }
Пример #19
0
 /// <summary>
 /// To call when the task has been waiting until now, in order to update the statistics of the task.
 /// </summary>
 /// <param name="currentTime">Current simulation time.</param>
 public virtual void SleepUntilNow(SimulationTime currentTime)
 {
     this.lastProcessTime = currentTime;
 }