From 312f8ce5d8e858ed7a5c443d7774023d93b4ea07 Mon Sep 17 00:00:00 2001 From: "niehues.mark@gmail.com" <niehues.mark@gmail.com> Date: Mon, 16 Mar 2020 16:50:29 +0100 Subject: [PATCH] wip --- evrouting/charge/T.py | 20 ++++++++++++------- evrouting/charge/__init__.py | 2 +- evrouting/charge/routing.py | 38 ++++++++++++++++++++++-------------- evrouting/graph_tools.py | 16 ++++++++++----- 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/evrouting/charge/T.py b/evrouting/charge/T.py index d65d7bc..4d8c308 100644 --- a/evrouting/charge/T.py +++ b/evrouting/charge/T.py @@ -1,3 +1,4 @@ +from typing import Tuple from copy import copy from collections import namedtuple from math import inf @@ -7,7 +8,12 @@ import networkx as nx from evrouting.T import SoC, Wh, ChargingCoefficient, Time, Node from evrouting.graph_tools import charging_cofficient, consumption -Label = namedtuple('Label', ['t_trip', 'beta_u', 'u', 'SoCProfile_u_v']) + +class Label(namedtuple): + t_trip: Time + beta_u: SoC + u: Node + SoCProfile: SoCProfile class ChargingFunction: @@ -19,8 +25,7 @@ class ChargingFunction: def __call__(self, t: Time, beta: SoC = 0) -> SoC: beta += self.c * t - if beta > self.U: - return self.U + return beta if beta < self.U else self.U class SoCFunction: @@ -29,10 +34,10 @@ class SoCFunction: self.t_trip: Time = l.t_trip self.beta_u: SoC = l.beta_u self.u: Node = l.u - self.b_u_v: SoCProfile = l.SoCProfile_u_v + self.b_u_v: SoCProfile = l.SoCProfile self.cf: ChargingFunction = ChargingFunction(G, l.u, U) - def __call__(self, t) -> SoC: + def __call__(self, t: Time) -> SoC: if t < self.t_trip: return -inf @@ -41,7 +46,8 @@ class SoCFunction: def get_minimum(self) -> Time: """TODO: Explain.""" cost_p = self.b_u_v.cost - return max(self.t_trip, (cost_p - self.beta_u) / self.cf.c + self.t_trip) + return max(self.t_trip, (cost_p - self.beta_u) / + self.cf.c + self.t_trip) class SoCProfile: @@ -59,7 +65,7 @@ class SoCProfile: self.cost: Wh = consumption(G, u, v) self.out: Wh = U - self.cost - def __call__(self, beta) -> SoC: + def __call__(self, beta: SoC) -> SoC: if beta < self.cost: return -inf return beta - self.cost diff --git a/evrouting/charge/__init__.py b/evrouting/charge/__init__.py index 0e1bcfd..3133abe 100644 --- a/evrouting/charge/__init__.py +++ b/evrouting/charge/__init__.py @@ -1 +1 @@ -from .routing import shortest_path \ No newline at end of file +from .routing import shortest_path diff --git a/evrouting/charge/routing.py b/evrouting/charge/routing.py index 2dd2beb..2d3778c 100644 --- a/evrouting/charge/routing.py +++ b/evrouting/charge/routing.py @@ -1,14 +1,16 @@ -from typing import List +from typing import Dict from math import inf import networkx as nx -from evrouting.T import Node, SoC, Time, ChargingCoefficient +from evrouting.T import Node, SoC, Time from evrouting.utils import PriorityQueue -from .T import SoCProfile, SoCFunction, Label +from .T import SoCProfile, SoCFunction, Label, ChargingFunction +from ..graph_tools import distance -def shortest_path(G: nx.Graph, S: set, s: Node, t: Node, beta_s: SoC, beta_t: SoC, U: SoC): +def shortest_path(G: nx.Graph, S: set, s: Node, t: Node, + beta_s: SoC, beta_t: SoC, U: SoC): """ Calculates shortest path using the CHarge algorithm. @@ -21,13 +23,12 @@ def shortest_path(G: nx.Graph, S: set, s: Node, t: Node, beta_s: SoC, beta_t: So :return: """ q = PriorityQueue() - l_set = {v: set() for v in G} - l_uns = {v: PriorityQueue() for v in G} + l_set: Dict[int, set] = {v: set() for v in G} + l_uns: Dict[int, PriorityQueue] = {v: PriorityQueue() for v in G} # Dummy vertex without incident edges that is (temporarily) added to G v_0: Node = len(G.nodes) G.add_node(v_0) - S.add(v_0) cf_v_0 = [(0, beta_s)] @@ -55,9 +56,19 @@ def shortest_path(G: nx.Graph, S: set, s: Node, t: Node, beta_s: SoC, beta_t: So # handle charging stations t_trip, beta_u, u, b_u_v = l if v in S and not v == u: - # TODO !!! - for t_charge in t_breaks(l): - l_uns[v].insert(new_label(l), priority=) # prio?? + cf_u = ChargingFunction(G, u, U) # Last charging station + cf_v = ChargingFunction(G, v, U) # Current charging station + + if cf_v.c > cf_u.c: + f_l = SoCFunction(G, l, U) + t_charge = f_l.get_minimum() + l_new = Label( + t_trip=t_trip + t_charge, + beta_u=beta_u, + u=v, + SoCProfile=SoCProfile(G, U, v) + ) + l_uns[v].insert(l_new, priority=key(l_new)) # update priority queue if l_uns[v]: @@ -69,8 +80,8 @@ def shortest_path(G: nx.Graph, S: set, s: Node, t: Node, beta_s: SoC, beta_t: So # scan outgoing arcs for x, y in G[v]: b_x_y = b_u_v + SoCProfile(G, U, x, y) - if not b_x_y(beta_max_u) == -inf: - l_new = (t_trip + G.edges[x, y]['weight'], beta_u, u, b_x_y) + if not b_x_y(U) == -inf: + l_new = Label(t_trip + distance(G, x, y), beta_u, u, b_x_y) l_uns[y].insert(l_new) if l_new == l_uns[y].peak_min(): q.insert(y, key(l_new)) @@ -79,6 +90,3 @@ def shortest_path(G: nx.Graph, S: set, s: Node, t: Node, beta_s: SoC, beta_t: So def key(l: Label) -> Time: return l.t_trip - -def t_breaks(c_old: ChargingCoefficient, c_new: ChargingCoefficient) -> List[Time]: - pass diff --git a/evrouting/graph_tools.py b/evrouting/graph_tools.py index 2d92456..e08c119 100644 --- a/evrouting/graph_tools.py +++ b/evrouting/graph_tools.py @@ -1,14 +1,16 @@ -from typing import Dict, Tuple +from typing import Dict, Tuple, Any from collections import namedtuple import networkx as nx -from evrouting.T import Wh, ChargingCoefficient +from evrouting.T import Wh, ChargingCoefficient, Time TemplateEdge = namedtuple('Edge', ['u', 'v', 'distance', 'consumption']) -TemplateNode = namedtuple('Node', ['label', 'charging_coeff'], defaults=(None, None)) +TemplateNode = namedtuple( + 'Node', ['label', 'charging_coeff'], defaults=(None, None) +) -NodeData = Dict -EdgeData = Dict +NodeData = Dict[str, Any] +EdgeData = Dict[str, Any] Node = int Edge = Tuple[int, int] @@ -26,5 +28,9 @@ def consumption(G: nx.Graph, u: Node, v: Node) -> Wh: return G.edges[u, v]['c'] +def distance(G: nx.Graph, u: Node, v: Node) -> Time: + return G.edges[u, v]['weight'] + + def charging_cofficient(G: nx.Graph, n: Node) -> ChargingCoefficient: return G.nodes[n]['c'] -- GitLab