robust error handling to avoid later crashes

This commit is contained in:
Sven Czarnian
2021-12-19 13:06:03 +01:00
parent 91683ec899
commit fc84aab0f2
3 changed files with 23 additions and 5 deletions

View File

@@ -27,6 +27,9 @@ class Ant:
# Implements function (5) # Implements function (5)
def heuristicInformation(self, current : int): def heuristicInformation(self, current : int):
_, eta, _ = self.RunwayManager.selectArrivalRunway(self.Nodes[current], self.Configuration.EarliestArrivalTime) _, eta, _ = self.RunwayManager.selectArrivalRunway(self.Nodes[current], self.Configuration.EarliestArrivalTime)
if None == eta:
return -1.0
inboundDelay = eta - self.Nodes[current].Inbound.InitialArrivalTime inboundDelay = eta - self.Nodes[current].Inbound.InitialArrivalTime
# calculate the fraction with a mix of the unused runway time and the delay of single aircrafts # calculate the fraction with a mix of the unused runway time and the delay of single aircrafts
@@ -54,6 +57,10 @@ class Ant:
if False == self.InboundSelected[i]: if False == self.InboundSelected[i]:
weights.append(self.heuristicInformation(i) / (pheromoneScale or 1)) weights.append(self.heuristicInformation(i) / (pheromoneScale or 1))
# something was wrong in the runway selection
if -1.0 in weights:
return None
total = sum(weights) total = sum(weights)
cumdist = list(itertools.accumulate(weights)) + [total] cumdist = list(itertools.accumulate(weights)) + [total]
candidateIndex = bisect.bisect(cumdist, random.random() * total) candidateIndex = bisect.bisect(cumdist, random.random() * total)

View File

@@ -19,6 +19,8 @@ from aman.types.Inbound import Inbound
class Colony: class Colony:
def associateInbound(rwyManager : RunwayManager, node : Node, earliestArrivalTime : datetime): def associateInbound(rwyManager : RunwayManager, node : Node, earliestArrivalTime : datetime):
rwy, eta, _ = rwyManager.selectArrivalRunway(node, earliestArrivalTime) rwy, eta, _ = rwyManager.selectArrivalRunway(node, earliestArrivalTime)
if None == eta:
return False
eta = max(earliestArrivalTime, eta) eta = max(earliestArrivalTime, eta)
node.Inbound.PlannedRunway = rwy node.Inbound.PlannedRunway = rwy
@@ -29,12 +31,15 @@ class Colony:
node.Inbound.PlannedTrackmiles = node.ArrivalCandidates[rwy.Name].Trackmiles node.Inbound.PlannedTrackmiles = node.ArrivalCandidates[rwy.Name].Trackmiles
rwyManager.RunwayInbounds[rwy.Name] = node rwyManager.RunwayInbounds[rwy.Name] = node
return True
def calculateInitialCosts(rwyManager : RunwayManager, nodes, earliestArrivalTime : datetime): def calculateInitialCosts(rwyManager : RunwayManager, nodes, earliestArrivalTime : datetime):
overallDelay = timedelta(seconds = 0) overallDelay = timedelta(seconds = 0)
# assume that the nodes are sorted in FCFS order # assume that the nodes are sorted in FCFS order
for node in nodes: for node in nodes:
Colony.associateInbound(rwyManager, node, earliestArrivalTime) if False == Colony.associateInbound(rwyManager, node, earliestArrivalTime):
return None
overallDelay += node.Inbound.PlannedArrivalTime - node.Inbound.InitialArrivalTime overallDelay += node.Inbound.PlannedArrivalTime - node.Inbound.InitialArrivalTime
return overallDelay return overallDelay
@@ -42,6 +47,7 @@ class Colony:
def __init__(self, inbounds, configuration : Configuration): def __init__(self, inbounds, configuration : Configuration):
self.Configuration = configuration self.Configuration = configuration
self.ResultDelay = None self.ResultDelay = None
self.FcfsDelay = None
self.Result = None self.Result = None
self.Nodes = [] self.Nodes = []
@@ -52,6 +58,8 @@ class Colony:
rwyManager = RunwayManager(self.Configuration) rwyManager = RunwayManager(self.Configuration)
delay = Colony.calculateInitialCosts(rwyManager, self.Nodes, self.Configuration.EarliestArrivalTime) delay = Colony.calculateInitialCosts(rwyManager, self.Nodes, self.Configuration.EarliestArrivalTime)
if None == delay:
return
self.FcfsDelay = delay self.FcfsDelay = delay
# run the optimization in every cycle to ensure optimal spacings based on TTG # run the optimization in every cycle to ensure optimal spacings based on TTG
@@ -74,9 +82,8 @@ class Colony:
current.PTA = prev.PTA + (current.ETA - prev.ETA) current.PTA = prev.PTA + (current.ETA - prev.ETA)
def optimize(self): def optimize(self):
# FCFS is the best solution if None == self.FcfsDelay:
if None != self.Result: return False
return
# define the tracking variables # define the tracking variables
bestSequence = None bestSequence = None
@@ -95,7 +102,7 @@ class Colony:
# fallback to check if findSolution was successful # fallback to check if findSolution was successful
if None == ant.SequenceDelay or None == ant.Sequence: if None == ant.SequenceDelay or None == ant.Sequence:
sys.stderr.write('Invalid ANT run detected!') sys.stderr.write('Invalid ANT run detected!')
sys.exit(-1) break
candidates.append( candidates.append(
[ [
@@ -142,3 +149,5 @@ class Colony:
self.ResultDelay = self.FcfsDelay self.ResultDelay = self.FcfsDelay
for node in self.Nodes: for node in self.Nodes:
self.sequenceAndPredictInbound(rwyManager, node) self.sequenceAndPredictInbound(rwyManager, node)
return True

View File

@@ -117,6 +117,8 @@ class RunwayManager:
def selectArrivalRunway(self, node : Node, earliestArrivalTime : datetime): def selectArrivalRunway(self, node : Node, earliestArrivalTime : datetime):
availableRunways = self.Configuration.RunwayConstraints.ActiveArrivalRunways availableRunways = self.Configuration.RunwayConstraints.ActiveArrivalRunways
if 0 == len(availableRunways):
return None, None, None
if True == self.Configuration.RunwayConstraints.UseShallShouldMay and None == node.Inbound.RequestedRunway: if True == self.Configuration.RunwayConstraints.UseShallShouldMay and None == node.Inbound.RequestedRunway:
availableRunways = self.executeShallShouldMayAssignment(node, earliestArrivalTime) availableRunways = self.executeShallShouldMayAssignment(node, earliestArrivalTime)