Procházet zdrojové kódy

robust error handling to avoid later crashes

Sven Czarnian před 3 roky
rodič
revize
fc84aab0f2
3 změnil soubory, kde provedl 23 přidání a 5 odebrání
  1. 7 0
      aman/sys/aco/Ant.py
  2. 14 5
      aman/sys/aco/Colony.py
  3. 2 0
      aman/sys/aco/RunwayManager.py

+ 7 - 0
aman/sys/aco/Ant.py

@@ -27,6 +27,9 @@ class Ant:
     # Implements function (5)
     def heuristicInformation(self, current : int):
         _, eta, _ = self.RunwayManager.selectArrivalRunway(self.Nodes[current], self.Configuration.EarliestArrivalTime)
+        if None == eta:
+            return -1.0
+
         inboundDelay = eta - self.Nodes[current].Inbound.InitialArrivalTime
 
         # 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]:
                     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)
         cumdist = list(itertools.accumulate(weights)) + [total]
         candidateIndex = bisect.bisect(cumdist, random.random() * total)

+ 14 - 5
aman/sys/aco/Colony.py

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

+ 2 - 0
aman/sys/aco/RunwayManager.py

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