adapt the code to split up predictions form the inbounds
This commit is contained in:
@@ -1,48 +1,57 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from datetime import datetime as dt
|
||||
from datetime import datetime, timedelta
|
||||
import numpy as np
|
||||
import pytz
|
||||
import random
|
||||
import sys
|
||||
import pytz
|
||||
import time
|
||||
|
||||
from aman.sys.aco.Ant import Ant
|
||||
from aman.sys.aco.Configuration import Configuration
|
||||
from aman.sys.aco.Node import Node
|
||||
from aman.sys.aco.RunwayManager import RunwayManager
|
||||
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, inbound : Inbound, earliestArrivalTime : datetime, useITA : bool):
|
||||
rwy, eta, _ = rwyManager.selectArrivalRunway(inbound, useITA, earliestArrivalTime)
|
||||
def associateInbound(rwyManager : RunwayManager, node : Node, earliestArrivalTime : datetime, useITA : bool):
|
||||
rwy, eta, _ = rwyManager.selectArrivalRunway(node, useITA, earliestArrivalTime)
|
||||
eta = max(earliestArrivalTime, eta)
|
||||
|
||||
inbound.PlannedRunway = rwy
|
||||
inbound.PlannedStar = inbound.ArrivalCandidates[rwy.Name].Star
|
||||
inbound.PlannedArrivalRoute = inbound.ArrivalCandidates[rwy.Name].ArrivalRoute
|
||||
inbound.PlannedArrivalTime = eta
|
||||
inbound.InitialArrivalTime = inbound.ArrivalCandidates[rwy.Name].InitialArrivalTime
|
||||
inbound.PlannedTrackmiles = inbound.ArrivalCandidates[rwy.Name].Trackmiles
|
||||
rwyManager.RunwayInbounds[rwy.Name] = inbound
|
||||
node.Inbound.PlannedRunway = rwy
|
||||
node.Inbound.PlannedStar = node.ArrivalCandidates[rwy.Name].Star
|
||||
node.Inbound.PlannedArrivalRoute = node.ArrivalCandidates[rwy.Name].ArrivalRoute
|
||||
node.Inbound.PlannedArrivalTime = eta
|
||||
node.Inbound.InitialArrivalTime = node.ArrivalCandidates[rwy.Name].InitialArrivalTime
|
||||
node.Inbound.PlannedTrackmiles = node.ArrivalCandidates[rwy.Name].Trackmiles
|
||||
rwyManager.RunwayInbounds[rwy.Name] = node
|
||||
|
||||
def calculateInitialCosts(rwyManager : RunwayManager, inbounds, earliestArrivalTime : datetime):
|
||||
def calculateInitialCosts(rwyManager : RunwayManager, nodes, earliestArrivalTime : datetime):
|
||||
overallDelay = timedelta(seconds = 0)
|
||||
|
||||
# assume that the inbounds are sorted in FCFS order
|
||||
for inbound in inbounds:
|
||||
Colony.associateInbound(rwyManager, inbound, earliestArrivalTime, False)
|
||||
overallDelay += inbound.PlannedArrivalTime - inbound.InitialArrivalTime
|
||||
# assume that the nodes are sorted in FCFS order
|
||||
for node in nodes:
|
||||
Colony.associateInbound(rwyManager, node, earliestArrivalTime, False)
|
||||
overallDelay += node.Inbound.PlannedArrivalTime - node.Inbound.InitialArrivalTime
|
||||
|
||||
return overallDelay
|
||||
|
||||
def __init__(self, configuration : Configuration):
|
||||
def __init__(self, inbounds, configuration : Configuration):
|
||||
self.Configuration = configuration
|
||||
self.ResultDelay = None
|
||||
self.Result = None
|
||||
self.Nodes = []
|
||||
|
||||
# create the new planning instances
|
||||
currentTime = dt.utcfromtimestamp(int(time.time())).replace(tzinfo = pytz.UTC)
|
||||
for inbound in inbounds:
|
||||
self.Nodes.append(Node(inbound, currentTime, self.Configuration.WeatherModel, self.Configuration.NavData, self.Configuration.RunwayConstraints))
|
||||
|
||||
rwyManager = RunwayManager(self.Configuration)
|
||||
delay = Colony.calculateInitialCosts(rwyManager, self.Configuration.Inbounds, self.Configuration.EarliestArrivalTime)
|
||||
delay = Colony.calculateInitialCosts(rwyManager, self.Nodes, self.Configuration.EarliestArrivalTime)
|
||||
self.FcfsDelay = delay
|
||||
|
||||
# run the optimization in every cycle to ensure optimal spacings based on TTG
|
||||
@@ -50,8 +59,8 @@ class Colony:
|
||||
delay = timedelta(seconds = 1.0)
|
||||
|
||||
# initial value for the optimization
|
||||
self.Configuration.ThetaZero = 1.0 / (len(self.Configuration.Inbounds) * (delay.total_seconds() / 60.0))
|
||||
self.PheromoneMatrix = np.ones(( len(self.Configuration.Inbounds), len(self.Configuration.Inbounds) ), dtype=float) * self.Configuration.ThetaZero
|
||||
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 optimize(self):
|
||||
# FCFS is the best solution
|
||||
@@ -64,12 +73,12 @@ class Colony:
|
||||
# run the optimization loops
|
||||
for _ in range(0, self.Configuration.ExplorationRuns):
|
||||
# select the first inbound
|
||||
index = random.randint(1, len(self.Configuration.Inbounds)) - 1
|
||||
index = random.randint(1, len(self.Nodes)) - 1
|
||||
candidates = []
|
||||
|
||||
for _ in range(0, self.Configuration.AntCount):
|
||||
# let the ant find a solution
|
||||
ant = Ant(self.PheromoneMatrix, self.Configuration)
|
||||
ant = Ant(self.PheromoneMatrix, self.Configuration, self.Nodes)
|
||||
ant.findSolution(index)
|
||||
|
||||
# fallback to check if findSolution was successful
|
||||
@@ -111,8 +120,8 @@ class Colony:
|
||||
# finalize the sequence
|
||||
rwyManager = RunwayManager(self.Configuration)
|
||||
for i in range(0, len(bestSequence[1])):
|
||||
self.Result.append(self.Configuration.Inbounds[bestSequence[1][i]])
|
||||
Colony.associateInbound(rwyManager, self.Result[-1], self.Configuration.EarliestArrivalTime, True)
|
||||
self.Result.append(self.Nodes[bestSequence[1][i]].Inbound)
|
||||
Colony.associateInbound(rwyManager, self.Nodes[bestSequence[1][i]], self.Configuration.EarliestArrivalTime, True)
|
||||
|
||||
# the idea behind the TTL/TTG per waypoint is that the TTL and TTG needs to be achieved in the
|
||||
# first 2/3 of the estimated trackmiles and assign it with a linear function to the waypoints
|
||||
|
||||
Reference in New Issue
Block a user