Add setting to increase cost/distance of aircraft linkgraph links
This commit is contained in:
@@ -41,6 +41,7 @@ inline void LinkGraph::BaseEdge::Init()
|
||||
this->usage = 0;
|
||||
this->last_unrestricted_update = INVALID_DATE;
|
||||
this->last_restricted_update = INVALID_DATE;
|
||||
this->last_aircraft_update = INVALID_DATE;
|
||||
this->next_edge = INVALID_NODE;
|
||||
}
|
||||
|
||||
@@ -59,6 +60,7 @@ void LinkGraph::ShiftDates(int interval)
|
||||
BaseEdge &edge = this->edges[node1][node2];
|
||||
if (edge.last_unrestricted_update != INVALID_DATE) edge.last_unrestricted_update += interval;
|
||||
if (edge.last_restricted_update != INVALID_DATE) edge.last_restricted_update += interval;
|
||||
if (edge.last_aircraft_update != INVALID_DATE) edge.last_aircraft_update += interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,6 +201,7 @@ void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMo
|
||||
first.next_edge = to;
|
||||
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = _date;
|
||||
if (mode & EUM_RESTRICTED) edge.last_restricted_update = _date;
|
||||
if (mode & EUM_AIRCRAFT) edge.last_aircraft_update = _date;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,6 +233,7 @@ void LinkGraph::Node::RemoveEdge(NodeID to)
|
||||
edge.capacity = 0;
|
||||
edge.last_unrestricted_update = INVALID_DATE;
|
||||
edge.last_restricted_update = INVALID_DATE;
|
||||
edge.last_aircraft_update = INVALID_DATE;
|
||||
edge.usage = 0;
|
||||
|
||||
NodeID prev = this->index;
|
||||
@@ -270,6 +274,7 @@ void LinkGraph::Edge::Update(uint capacity, uint usage, EdgeUpdateMode mode)
|
||||
}
|
||||
if (mode & EUM_UNRESTRICTED) this->edge.last_unrestricted_update = _date;
|
||||
if (mode & EUM_RESTRICTED) this->edge.last_restricted_update = _date;
|
||||
if (mode & EUM_AIRCRAFT) this->edge.last_aircraft_update = _date;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -72,6 +72,7 @@ public:
|
||||
uint usage; ///< Usage of the link.
|
||||
Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
|
||||
Date last_restricted_update; ///< When the restricted part of the link was last updated.
|
||||
Date last_aircraft_update; ///< When aircraft capacity of the link was last updated.
|
||||
NodeID next_edge; ///< Destination of next valid edge starting at the same source node.
|
||||
void Init();
|
||||
};
|
||||
@@ -117,6 +118,12 @@ public:
|
||||
*/
|
||||
Date LastRestrictedUpdate() const { return this->edge.last_restricted_update; }
|
||||
|
||||
/**
|
||||
* Get the date of the last update to the edge's aircraft capacity.
|
||||
* @return Last update.
|
||||
*/
|
||||
Date LastAircraftUpdate() const { return this->edge.last_aircraft_update; }
|
||||
|
||||
/**
|
||||
* Get the date of the last update to any part of the edge's capacity.
|
||||
* @return Last update.
|
||||
@@ -307,6 +314,7 @@ public:
|
||||
void Update(uint capacity, uint usage, EdgeUpdateMode mode);
|
||||
void Restrict() { this->edge.last_unrestricted_update = INVALID_DATE; }
|
||||
void Release() { this->edge.last_restricted_update = INVALID_DATE; }
|
||||
void ClearAircraft() { this->edge.last_aircraft_update = INVALID_DATE; }
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -48,6 +48,7 @@ enum EdgeUpdateMode {
|
||||
EUM_REFRESH = 1 << 1, ///< Refresh capacity.
|
||||
EUM_RESTRICTED = 1 << 2, ///< Use restricted link.
|
||||
EUM_UNRESTRICTED = 1 << 3, ///< Use unrestricted link.
|
||||
EUM_AIRCRAFT = 1 << 4, ///< Capacity is an aircraft link.
|
||||
};
|
||||
|
||||
DECLARE_ENUM_AS_BIT_SET(EdgeUpdateMode)
|
||||
|
@@ -284,6 +284,8 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths)
|
||||
|
||||
this->job.path_allocator.SetParameters(sizeof(Tannotation), (8192 - 32) / sizeof(Tannotation));
|
||||
|
||||
const uint16 aircraft_link_scale = this->job.Settings().aircraft_link_scale;
|
||||
|
||||
for (NodeID node = 0; node < size; ++node) {
|
||||
Tannotation *anno = new (this->job.path_allocator.Allocate()) Tannotation(node, node == source_node);
|
||||
anno->UpdateAnnotation();
|
||||
@@ -310,6 +312,10 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths)
|
||||
}
|
||||
/* punish in-between stops a little */
|
||||
uint distance = DistanceMaxPlusManhattan(this->job[from].XY(), this->job[to].XY()) + 1;
|
||||
if (edge.LastAircraftUpdate() != INVALID_DATE && aircraft_link_scale != 100) {
|
||||
distance *= aircraft_link_scale;
|
||||
distance /= 100;
|
||||
}
|
||||
Tannotation *dest = static_cast<Tannotation *>(paths[to]);
|
||||
if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance)) {
|
||||
if (dest->GetAnnosSetFlag()) annos.erase(AnnoSetItem<Tannotation>(dest));
|
||||
|
@@ -55,7 +55,10 @@
|
||||
HopSet seen_hops;
|
||||
LinkRefresher refresher(v, &seen_hops, allow_merge, is_full_loading, iter_cargo_mask);
|
||||
|
||||
refresher.RefreshLinks(first, first, (iter_cargo_mask & have_cargo_mask) ? 1 << HAS_CARGO : 0);
|
||||
uint8 flags = 0;
|
||||
if (iter_cargo_mask & have_cargo_mask) flags |= 1 << HAS_CARGO;
|
||||
if (v->type == VEH_AIRCRAFT) flags |= 1 << AIRCRAFT;
|
||||
refresher.RefreshLinks(first, first, flags);
|
||||
}
|
||||
|
||||
cargo_mask &= ~iter_cargo_mask;
|
||||
@@ -234,7 +237,7 @@ const Order *LinkRefresher::PredictNextOrder(const Order *cur, const Order *next
|
||||
* @param cur Last stop where the consist could interact with cargo.
|
||||
* @param next Next order to be processed.
|
||||
*/
|
||||
void LinkRefresher::RefreshStats(const Order *cur, const Order *next)
|
||||
void LinkRefresher::RefreshStats(const Order *cur, const Order *next, uint8 flags)
|
||||
{
|
||||
StationID next_station = next->GetDestination();
|
||||
Station *st = Station::GetIfValid(cur->GetDestination());
|
||||
@@ -257,6 +260,8 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next)
|
||||
EdgeUpdateMode restricted_mode = (cur->GetCargoLoadType(c) & OLFB_NO_LOAD) == 0 ?
|
||||
EUM_UNRESTRICTED : EUM_RESTRICTED;
|
||||
|
||||
if (HasBit(flags, AIRCRAFT)) restricted_mode |= EUM_AIRCRAFT;
|
||||
|
||||
/* If the vehicle is currently full loading, increase the capacities at the station
|
||||
* where it is loading by an estimate of what it would have transported if it wasn't
|
||||
* loading. Don't do that if the vehicle has been waiting for longer than the entire
|
||||
@@ -347,7 +352,7 @@ void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, uint8 flag
|
||||
if (cur->IsType(OT_GOTO_STATION) || cur->IsType(OT_IMPLICIT)) {
|
||||
if (cur->CanLeaveWithCargo(HasBit(flags, HAS_CARGO), FindFirstBit(this->cargo_mask))) {
|
||||
SetBit(flags, HAS_CARGO);
|
||||
this->RefreshStats(cur, next);
|
||||
this->RefreshStats(cur, next, flags);
|
||||
} else {
|
||||
ClrBit(flags, HAS_CARGO);
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@ protected:
|
||||
WAS_REFIT, ///< Consist was refit since the last stop where it could interact with cargo.
|
||||
RESET_REFIT, ///< Consist had a chance to load since the last refit and the refit capacities can be reset.
|
||||
IN_AUTOREFIT, ///< Currently doing an autorefit loop. Ignore the first autorefit order.
|
||||
AIRCRAFT, ///< Vehicle is an aircraft.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -93,7 +94,7 @@ protected:
|
||||
|
||||
bool HandleRefit(CargoID refit_cargo);
|
||||
void ResetRefit();
|
||||
void RefreshStats(const Order *cur, const Order *next);
|
||||
void RefreshStats(const Order *cur, const Order *next, uint8 flags);
|
||||
const Order *PredictNextOrder(const Order *cur, const Order *next, uint8 flags, uint num_hops = 0);
|
||||
|
||||
void RefreshLinks(const Order *cur, const Order *next, uint8 flags, uint num_hops = 0);
|
||||
|
Reference in New Issue
Block a user