Overlap Operations in a Customization

How to use a customization point to overlap operations based on custom rules

This guide will step through the process of coding a Schedulability customization. If you are just getting started, please first see getting started with customizations and the schedulability customization point basics

Overlapping Operations

This example will overlap operations into predecessor's setup span  based on a UDF on the operation with a Boolean value for whether to overlap an operation or not.

private readonly Dictionary<BaseId, bool> m_opsMappingDictionary = new Dictionary<BaseId, bool>();

protected override void SimulationInitialization(ScenarioDetail a_sd, SchedulabilitySimulationInitializationHelper a_schedulabilityHelper, ScenarioDetail.SimulationType a_simulationType, ScenarioBaseT a_transmission)
{
//Clear before each initialization
m_opsMappingDictionary.Clear();

foreach (Job job in a_sd.JobManager)
{
//We are not interested in template jobs
if (job.Template)
{
continue;
}

foreach (BaseOperation op in job.GetOperations())
{
if(op.Successors.Count == 0)
{
//this is not a predecessor operation and won't need to overlap
continue;
}

UserField userField = op.UserFields?.Find("Overlap");
if (userField != null && userField.DataValue is bool overlap)
{
m_opsMappingDictionary.Add(op.Id, overlap);
}
}
}
}

protected override bool IsSchedulable(ScenarioDetail a_sd, ScenarioDetail.SimulationType a_simType, long a_clock, long a_simulationClock, BaseResource a_res, BaseActivity a_activity, SchedulableInfo a_schedulableInfo, out long o_postEventTime)
{
o_postEventTime = -1;

//Cast to InternalActivity to be able to access the operation
InternalActivity ia = (InternalActivity)a_activity;
InternalOperation io = ia.Operation;

//If no predecessor return true
if (io.Predecessors.Count == 0)
{
return true;
}

BaseOperation ioPred = io.Predecessors[0].Predecessor.Operation;

if (m_opsMappingDictionary.TryGetValue(ioPred.Id, out bool overlap))
{
if (overlap)
{
DateTime ioPredScheduledEndDate = ioPred.ScheduledEndDate;
DateTime succOpEndSetUp = new DateTime(a_schedulableInfo.m_setupFinishDate);

//If predecessor scheduled end date is less than or equal to the successor operation's set up end time, return true
if (ioPredScheduledEndDate <= succOpEndSetUp)
{
return true;
}

//Tell scheduler to attempt again at the point in time of the predecessor operation
//end date minus the the setup span of the successor operation
TimeSpan setUpDuration = TimeSpan.FromTicks(a_schedulableInfo.m_requiredSetupSpan.TimeSpanTicks);
o_postEventTime = ioPredScheduledEndDate.Subtract(setUpDuration).Ticks;

return false;
}
}

return true;
}

Next Steps

To expand your customization, meet other types of scheduling requirements or to learn how to better navigate the PlanetTogether data objects explore the following articles:

Advanced topics

Coming Soon...