use the shortcut-path as the ITA for the optimization, but use the full path as the ITA itself

This commit is contained in:
Sven Czarnian
2021-12-16 10:22:43 +01:00
parent 6fd4f4da1b
commit cd5c21d099
5 changed files with 67 additions and 136 deletions

View File

@@ -17,8 +17,8 @@ from aman.types.Inbound import Inbound
# This class implements the ant colony of the following paper:
# https://sci-hub.mksa.top/10.1109/cec.2019.8790135
class Colony:
def associateInbound(rwyManager : RunwayManager, node : Node, earliestArrivalTime : datetime, useITA : bool):
rwy, eta, _ = rwyManager.selectArrivalRunway(node, useITA, earliestArrivalTime)
def associateInbound(rwyManager : RunwayManager, node : Node, earliestArrivalTime : datetime):
rwy, eta, _ = rwyManager.selectArrivalRunway(node, earliestArrivalTime)
eta = max(earliestArrivalTime, eta)
node.Inbound.PlannedRunway = rwy
@@ -34,7 +34,7 @@ class Colony:
# assume that the nodes are sorted in FCFS order
for node in nodes:
Colony.associateInbound(rwyManager, node, earliestArrivalTime, False)
Colony.associateInbound(rwyManager, node, earliestArrivalTime)
overallDelay += node.Inbound.PlannedArrivalTime - node.Inbound.InitialArrivalTime
return overallDelay
@@ -62,6 +62,17 @@ class Colony:
self.Configuration.ThetaZero = 1.0 / (len(self.Nodes) * (delay.total_seconds() / 60.0))
self.PheromoneMatrix = np.ones(( len(self.Nodes), len(self.Nodes) ), dtype=float) * self.Configuration.ThetaZero
def sequenceAndPredictInbound(self, rwyManager : RunwayManager, node : Node):
self.Result.append(node)
Colony.associateInbound(rwyManager, node, self.Configuration.EarliestArrivalTime)
reqTimeDelta = self.Result[-1].Inbound.InitialArrivalTime - self.Result[-1].Inbound.PlannedArrivalTime
self.Result[-1].Inbound.PlannedArrivalRoute[0].PTA = self.Result[-1].Inbound.PlannedArrivalRoute[0].ETA - reqTimeDelta
for i in range(1, len(self.Result[-1].Inbound.PlannedArrivalRoute)):
prev = self.Result[-1].Inbound.PlannedArrivalRoute[i - 1]
current = self.Result[-1].Inbound.PlannedArrivalRoute[i]
current.PTA = prev.PTA + (current.ETA - prev.ETA)
def optimize(self):
# FCFS is the best solution
if None != self.Result:
@@ -82,23 +93,21 @@ class Colony:
ant.findSolution(index)
# fallback to check if findSolution was successful
if None == ant.SequenceDelay or None == ant.Sequence or None == ant.SequenceScore:
if None == ant.SequenceDelay or None == ant.Sequence:
sys.stderr.write('Invalid ANT run detected!')
sys.exit(-1)
candidates.append(
[
ant.SequenceDelay,
ant.Sequence,
ant.SequenceScore,
ant.SequenceDelay.total_seconds() / ant.SequenceScore
ant.Sequence
]
)
# find the best solution in all candidates of this generation
bestCandidate = None
for candidate in candidates:
if None == bestCandidate or candidate[3] < bestCandidate[3]:
if None == bestCandidate or candidate[0] < bestCandidate[0]:
bestCandidate = candidate
dTheta = 1.0 / ((candidate[0].total_seconds() / 60.0) or 1.0)
@@ -112,20 +121,19 @@ class Colony:
bestSequence = bestCandidate
# create the final sequence
if None != bestSequence:
self.Result = []
rwyManager = RunwayManager(self.Configuration)
# use the optimized sequence
if None != bestSequence and self.FcfsDelay >= bestSequence[0]:
# create the resulting sequence
self.ResultDelay = bestSequence[0]
self.Result = []
# finalize the sequence
rwyManager = RunwayManager(self.Configuration)
for i in range(0, len(bestSequence[1])):
self.Result.append(self.Nodes[bestSequence[1][i]])
Colony.associateInbound(rwyManager, self.Nodes[bestSequence[1][i]], self.Configuration.EarliestArrivalTime, True)
reqTimeDelta = self.Result[-1].Inbound.InitialArrivalTime - self.Result[-1].Inbound.PlannedArrivalTime
self.Result[-1].Inbound.PlannedArrivalRoute[0].PTA = self.Result[-1].Inbound.PlannedArrivalRoute[0].ETA - reqTimeDelta
for i in range(1, len(self.Result[-1].Inbound.PlannedArrivalRoute)):
prev = self.Result[-1].Inbound.PlannedArrivalRoute[i - 1]
current = self.Result[-1].Inbound.PlannedArrivalRoute[i]
current.PTA = prev.PTA + (current.ETA - prev.ETA)
for idx in bestSequence[1]:
self.sequenceAndPredictInbound(rwyManager, self.Nodes[idx])
# use the FCFS sequence
else:
self.ResultDelay = self.FcfsDelay
for node in self.Nodes:
self.sequenceAndPredictInbound(node)