Feature: [Linkgraph] Prioritize faster routes for passengers, mail and express cargo
Passengers usually prefer fast paths to short paths.
Average travel times of links are updated in real-time for use in Dijkstra's algorithm,
and newer travel times weigh more, just like capacities.
(cherry picked from commit 977604ef08
)
This commit is contained in:

committed by
Jonathan G Rennison

parent
1518c2fa1e
commit
a43a1902bb
@@ -39,6 +39,7 @@ inline void LinkGraph::BaseEdge::Init()
|
||||
{
|
||||
this->capacity = 0;
|
||||
this->usage = 0;
|
||||
this->travel_time_sum = 0;
|
||||
this->last_unrestricted_update = INVALID_DATE;
|
||||
this->last_restricted_update = INVALID_DATE;
|
||||
this->last_aircraft_update = INVALID_DATE;
|
||||
@@ -75,6 +76,7 @@ void LinkGraph::Compress()
|
||||
if (edge.capacity > 0) {
|
||||
edge.capacity = std::max(1U, edge.capacity / 2);
|
||||
edge.usage /= 2;
|
||||
edge.travel_time_sum = std::max(1ULL, edge.travel_time_sum / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,9 +104,11 @@ void LinkGraph::Merge(LinkGraph *other)
|
||||
backward = other->edges[node2][node1];
|
||||
forward.capacity = LinkGraph::Scale(forward.capacity, age, other_age);
|
||||
forward.usage = LinkGraph::Scale(forward.usage, age, other_age);
|
||||
forward.travel_time_sum = LinkGraph::Scale(forward.travel_time_sum, age, other_age);
|
||||
if (forward.next_edge != INVALID_NODE) forward.next_edge += first;
|
||||
backward.capacity = LinkGraph::Scale(backward.capacity, age, other_age);
|
||||
backward.usage = LinkGraph::Scale(backward.usage, age, other_age);
|
||||
backward.travel_time_sum = LinkGraph::Scale(backward.travel_time_sum, age, other_age);
|
||||
if (backward.next_edge != INVALID_NODE) backward.next_edge += first;
|
||||
}
|
||||
BaseEdge &new_start = this->edges[new_node][new_node];
|
||||
@@ -190,13 +194,14 @@ NodeID LinkGraph::AddNode(const Station *st)
|
||||
* @param usage Usage to be added.
|
||||
* @param mode Update mode to be used.
|
||||
*/
|
||||
void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode)
|
||||
void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode)
|
||||
{
|
||||
assert(this->index != to);
|
||||
BaseEdge &edge = this->edges[to];
|
||||
BaseEdge &first = this->edges[this->index];
|
||||
edge.capacity = capacity;
|
||||
edge.usage = usage;
|
||||
edge.travel_time_sum = travel_time * capacity;
|
||||
edge.next_edge = first.next_edge;
|
||||
first.next_edge = to;
|
||||
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = _date;
|
||||
@@ -211,14 +216,14 @@ void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMo
|
||||
* @param usage Usage to be added.
|
||||
* @param mode Update mode to be used.
|
||||
*/
|
||||
void LinkGraph::Node::UpdateEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode)
|
||||
void LinkGraph::Node::UpdateEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode)
|
||||
{
|
||||
assert(capacity > 0);
|
||||
assert(usage <= capacity);
|
||||
if (this->edges[to].capacity == 0) {
|
||||
this->AddEdge(to, capacity, usage, mode);
|
||||
this->AddEdge(to, capacity, usage, travel_time, mode);
|
||||
} else {
|
||||
(*this)[to].Update(capacity, usage, mode);
|
||||
(*this)[to].Update(capacity, usage, travel_time, mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,6 +240,7 @@ void LinkGraph::Node::RemoveEdge(NodeID to)
|
||||
edge.last_restricted_update = INVALID_DATE;
|
||||
edge.last_aircraft_update = INVALID_DATE;
|
||||
edge.usage = 0;
|
||||
edge.travel_time_sum = 0;
|
||||
|
||||
NodeID prev = this->index;
|
||||
NodeID next = this->edges[this->index].next_edge;
|
||||
@@ -253,23 +259,39 @@ void LinkGraph::Node::RemoveEdge(NodeID to)
|
||||
|
||||
/**
|
||||
* Update an edge. If mode contains UM_REFRESH refresh the edge to have at
|
||||
* least the given capacity and usage, otherwise add the capacity and usage.
|
||||
* least the given capacity and usage, otherwise add the capacity, usage and travel time.
|
||||
* In any case set the respective update timestamp(s), according to the given
|
||||
* mode.
|
||||
* @param capacity Capacity to be added/updated.
|
||||
* @param usage Usage to be added.
|
||||
* @param travel_time Travel time to be added, in ticks.
|
||||
* @param mode Update mode to be applied.
|
||||
*/
|
||||
void LinkGraph::Edge::Update(uint capacity, uint usage, EdgeUpdateMode mode)
|
||||
void LinkGraph::Edge::Update(uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode)
|
||||
{
|
||||
assert(this->edge.capacity > 0);
|
||||
assert(capacity >= usage);
|
||||
|
||||
if (mode & EUM_INCREASE) {
|
||||
if (this->edge.travel_time_sum == 0) {
|
||||
this->edge.travel_time_sum = (this->edge.capacity + capacity) * travel_time;
|
||||
} else if (travel_time == 0) {
|
||||
this->edge.travel_time_sum += this->edge.travel_time_sum / this->edge.capacity * capacity;
|
||||
} else {
|
||||
this->edge.travel_time_sum += travel_time * capacity;
|
||||
}
|
||||
this->edge.capacity += capacity;
|
||||
this->edge.usage += usage;
|
||||
} else if (mode & EUM_REFRESH) {
|
||||
this->edge.capacity = std::max(this->edge.capacity, capacity);
|
||||
/* If travel time is not provided, we scale the stored time based on
|
||||
* the capacity increase. */
|
||||
if (capacity > this->edge.capacity && travel_time == 0) {
|
||||
this->edge.travel_time_sum = this->edge.travel_time_sum / this->edge.capacity * capacity;
|
||||
this->edge.capacity = capacity;
|
||||
} else {
|
||||
this->edge.capacity = std::max(this->edge.capacity, capacity);
|
||||
this->edge.travel_time_sum = std::max<uint64>(this->edge.travel_time_sum, travel_time * capacity);
|
||||
}
|
||||
this->edge.usage = std::max(this->edge.usage, usage);
|
||||
}
|
||||
if (mode & EUM_UNRESTRICTED) this->edge.last_unrestricted_update = _date;
|
||||
|
Reference in New Issue
Block a user