mirror of https://github.com/OpenTTD/OpenTTD
(svn r26646) -Fix [FS#6041]: Save locations instead of distances in link graphs to reduce size.
parent
e8e5cdde03
commit
957f5ca117
|
@ -210,7 +210,8 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler)
|
||||||
|
|
||||||
/* Scale the distance by mod_dist around max_distance */
|
/* Scale the distance by mod_dist around max_distance */
|
||||||
int32 distance = this->max_distance - (this->max_distance -
|
int32 distance = this->max_distance - (this->max_distance -
|
||||||
(int32)job[from_id][to_id].Distance()) * this->mod_dist / 100;
|
(int32)DistanceMaxPlusManhattan(job[from_id].XY(), job[to_id].XY())) *
|
||||||
|
this->mod_dist / 100;
|
||||||
|
|
||||||
/* Scale the accuracy by distance around accuracy / 2 */
|
/* Scale the accuracy by distance around accuracy / 2 */
|
||||||
int32 divisor = this->accuracy * (this->mod_dist - 50) / 100 +
|
int32 divisor = this->accuracy * (this->mod_dist - 50) / 100 +
|
||||||
|
|
|
@ -21,11 +21,13 @@ INSTANTIATE_POOL_METHODS(LinkGraph)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a node or clear it.
|
* Create a node or clear it.
|
||||||
|
* @param xy Location of the associated station.
|
||||||
* @param st ID of the associated station.
|
* @param st ID of the associated station.
|
||||||
* @param demand Demand for cargo at the station.
|
* @param demand Demand for cargo at the station.
|
||||||
*/
|
*/
|
||||||
inline void LinkGraph::BaseNode::Init(StationID st, uint demand)
|
inline void LinkGraph::BaseNode::Init(TileIndex xy, StationID st, uint demand)
|
||||||
{
|
{
|
||||||
|
this->xy = xy;
|
||||||
this->supply = 0;
|
this->supply = 0;
|
||||||
this->demand = demand;
|
this->demand = demand;
|
||||||
this->station = st;
|
this->station = st;
|
||||||
|
@ -34,11 +36,9 @@ inline void LinkGraph::BaseNode::Init(StationID st, uint demand)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an edge.
|
* Create an edge.
|
||||||
* @param distance Length of the link as manhattan distance.
|
|
||||||
*/
|
*/
|
||||||
inline void LinkGraph::BaseEdge::Init(uint distance)
|
inline void LinkGraph::BaseEdge::Init()
|
||||||
{
|
{
|
||||||
this->distance = distance;
|
|
||||||
this->capacity = 0;
|
this->capacity = 0;
|
||||||
this->usage = 0;
|
this->usage = 0;
|
||||||
this->last_unrestricted_update = INVALID_DATE;
|
this->last_unrestricted_update = INVALID_DATE;
|
||||||
|
@ -146,21 +146,6 @@ void LinkGraph::RemoveNode(NodeID id)
|
||||||
* been copied around in the loop above. */
|
* been copied around in the loop above. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update distances between the given node and all others.
|
|
||||||
* @param id Node that changed position.
|
|
||||||
* @param xy New position of the node.
|
|
||||||
*/
|
|
||||||
void LinkGraph::UpdateDistances(NodeID id, TileIndex xy)
|
|
||||||
{
|
|
||||||
assert(id < this->Size());
|
|
||||||
for (NodeID other = 0; other < this->Size(); ++other) {
|
|
||||||
if (other == id) continue;
|
|
||||||
this->edges[id][other].distance = this->edges[other][id].distance =
|
|
||||||
DistanceMaxPlusManhattan(xy, Station::Get(this->nodes[other].station)->xy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a node to the component and create empty edges associated with it. Set
|
* Add a node to the component and create empty edges associated with it. Set
|
||||||
* the station's last_component to this component. Calculate the distances to all
|
* the station's last_component to this component. Calculate the distances to all
|
||||||
|
@ -180,7 +165,7 @@ NodeID LinkGraph::AddNode(const Station *st)
|
||||||
this->edges.Resize(new_node + 1U,
|
this->edges.Resize(new_node + 1U,
|
||||||
max(new_node + 1U, this->edges.Height()));
|
max(new_node + 1U, this->edges.Height()));
|
||||||
|
|
||||||
this->nodes[new_node].Init(st->index,
|
this->nodes[new_node].Init(st->xy, st->index,
|
||||||
HasBit(good.status, GoodsEntry::GES_ACCEPTANCE));
|
HasBit(good.status, GoodsEntry::GES_ACCEPTANCE));
|
||||||
|
|
||||||
BaseEdge *new_edges = this->edges[new_node];
|
BaseEdge *new_edges = this->edges[new_node];
|
||||||
|
@ -189,9 +174,8 @@ NodeID LinkGraph::AddNode(const Station *st)
|
||||||
new_edges[new_node].next_edge = INVALID_NODE;
|
new_edges[new_node].next_edge = INVALID_NODE;
|
||||||
|
|
||||||
for (NodeID i = 0; i <= new_node; ++i) {
|
for (NodeID i = 0; i <= new_node; ++i) {
|
||||||
uint distance = DistanceMaxPlusManhattan(st->xy, Station::Get(this->nodes[i].station)->xy);
|
new_edges[i].Init();
|
||||||
new_edges[i].Init(distance);
|
this->edges[i][new_node].Init();
|
||||||
this->edges[i][new_node].Init(distance);
|
|
||||||
}
|
}
|
||||||
return new_node;
|
return new_node;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,9 @@ public:
|
||||||
uint supply; ///< Supply at the station.
|
uint supply; ///< Supply at the station.
|
||||||
uint demand; ///< Acceptance at the station.
|
uint demand; ///< Acceptance at the station.
|
||||||
StationID station; ///< Station ID.
|
StationID station; ///< Station ID.
|
||||||
|
TileIndex xy; ///< Location of the station referred to by the node.
|
||||||
Date last_update; ///< When the supply was last updated.
|
Date last_update; ///< When the supply was last updated.
|
||||||
void Init(StationID st = INVALID_STATION, uint demand = 0);
|
void Init(TileIndex xy = INVALID_TILE, StationID st = INVALID_STATION, uint demand = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,13 +61,12 @@ public:
|
||||||
* the column as next_edge.
|
* the column as next_edge.
|
||||||
*/
|
*/
|
||||||
struct BaseEdge {
|
struct BaseEdge {
|
||||||
uint distance; ///< Length of the link.
|
|
||||||
uint capacity; ///< Capacity of the link.
|
uint capacity; ///< Capacity of the link.
|
||||||
uint usage; ///< Usage of the link.
|
uint usage; ///< Usage of the link.
|
||||||
Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
|
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_restricted_update; ///< When the restricted part of the link was last updated.
|
||||||
NodeID next_edge; ///< Destination of next valid edge starting at the same source node.
|
NodeID next_edge; ///< Destination of next valid edge starting at the same source node.
|
||||||
void Init(uint distance = 0);
|
void Init();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,12 +98,6 @@ public:
|
||||||
*/
|
*/
|
||||||
uint Usage() const { return this->edge.usage; }
|
uint Usage() const { return this->edge.usage; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Get edge's distance.
|
|
||||||
* @return Distance.
|
|
||||||
*/
|
|
||||||
uint Distance() const { return this->edge.distance; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the date of the last update to the edge's unrestricted capacity.
|
* Get the date of the last update to the edge's unrestricted capacity.
|
||||||
* @return Last update.
|
* @return Last update.
|
||||||
|
@ -169,6 +163,12 @@ public:
|
||||||
* @return Last update.
|
* @return Last update.
|
||||||
*/
|
*/
|
||||||
Date LastUpdate() const { return this->node.last_update; }
|
Date LastUpdate() const { return this->node.last_update; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the location of the station associated with the node.
|
||||||
|
* @return Location of the station.
|
||||||
|
*/
|
||||||
|
TileIndex XY() const { return this->node.xy; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -412,6 +412,15 @@ public:
|
||||||
this->node.last_update = _date;
|
this->node.last_update = _date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the node's location on the map.
|
||||||
|
* @param xy New location.
|
||||||
|
*/
|
||||||
|
void UpdateLocation(TileIndex xy)
|
||||||
|
{
|
||||||
|
this->node.xy = xy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the node's demand.
|
* Set the node's demand.
|
||||||
* @param demand New demand for the node.
|
* @param demand New demand for the node.
|
||||||
|
@ -513,7 +522,6 @@ public:
|
||||||
|
|
||||||
NodeID AddNode(const Station *st);
|
NodeID AddNode(const Station *st);
|
||||||
void RemoveNode(NodeID id);
|
void RemoveNode(NodeID id);
|
||||||
void UpdateDistances(NodeID id, TileIndex xy);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class LinkGraph::ConstNode;
|
friend class LinkGraph::ConstNode;
|
||||||
|
|
|
@ -259,7 +259,6 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths)
|
||||||
for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) {
|
for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) {
|
||||||
if (to == from) continue; // Not a real edge but a consumption sign.
|
if (to == from) continue; // Not a real edge but a consumption sign.
|
||||||
Edge edge = this->job[from][to];
|
Edge edge = this->job[from][to];
|
||||||
assert(edge.Distance() < UINT_MAX);
|
|
||||||
uint capacity = edge.Capacity();
|
uint capacity = edge.Capacity();
|
||||||
if (this->max_saturation != UINT_MAX) {
|
if (this->max_saturation != UINT_MAX) {
|
||||||
capacity *= this->max_saturation;
|
capacity *= this->max_saturation;
|
||||||
|
@ -267,7 +266,7 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths)
|
||||||
if (capacity == 0) capacity = 1;
|
if (capacity == 0) capacity = 1;
|
||||||
}
|
}
|
||||||
/* punish in-between stops a little */
|
/* punish in-between stops a little */
|
||||||
uint distance = edge.Distance() + 1;
|
uint distance = DistanceMaxPlusManhattan(this->job[from].XY(), this->job[to].XY()) + 1;
|
||||||
Tannotation *dest = static_cast<Tannotation *>(paths[to]);
|
Tannotation *dest = static_cast<Tannotation *>(paths[to]);
|
||||||
if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance)) {
|
if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance)) {
|
||||||
annos.erase(dest);
|
annos.erase(dest);
|
||||||
|
|
|
@ -109,24 +109,25 @@ const SaveLoad *GetLinkGraphScheduleDesc()
|
||||||
* SaveLoad desc for a link graph node.
|
* SaveLoad desc for a link graph node.
|
||||||
*/
|
*/
|
||||||
static const SaveLoad _node_desc[] = {
|
static const SaveLoad _node_desc[] = {
|
||||||
SLE_VAR(Node, supply, SLE_UINT32),
|
SLE_CONDVAR(Node, xy, SLE_UINT32, 191, SL_MAX_VERSION),
|
||||||
SLE_VAR(Node, demand, SLE_UINT32),
|
SLE_VAR(Node, supply, SLE_UINT32),
|
||||||
SLE_VAR(Node, station, SLE_UINT16),
|
SLE_VAR(Node, demand, SLE_UINT32),
|
||||||
SLE_VAR(Node, last_update, SLE_INT32),
|
SLE_VAR(Node, station, SLE_UINT16),
|
||||||
SLE_END()
|
SLE_VAR(Node, last_update, SLE_INT32),
|
||||||
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SaveLoad desc for a link graph edge.
|
* SaveLoad desc for a link graph edge.
|
||||||
*/
|
*/
|
||||||
static const SaveLoad _edge_desc[] = {
|
static const SaveLoad _edge_desc[] = {
|
||||||
SLE_VAR(Edge, distance, SLE_UINT32),
|
SLE_CONDNULL(4, 0, 190), // distance
|
||||||
SLE_VAR(Edge, capacity, SLE_UINT32),
|
SLE_VAR(Edge, capacity, SLE_UINT32),
|
||||||
SLE_VAR(Edge, usage, SLE_UINT32),
|
SLE_VAR(Edge, usage, SLE_UINT32),
|
||||||
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
|
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
|
||||||
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, 187, SL_MAX_VERSION),
|
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, 187, SL_MAX_VERSION),
|
||||||
SLE_VAR(Edge, next_edge, SLE_UINT16),
|
SLE_VAR(Edge, next_edge, SLE_UINT16),
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,8 +140,16 @@ void SaveLoad_LinkGraph(LinkGraph &lg)
|
||||||
for (NodeID from = 0; from < size; ++from) {
|
for (NodeID from = 0; from < size; ++from) {
|
||||||
Node *node = &lg.nodes[from];
|
Node *node = &lg.nodes[from];
|
||||||
SlObject(node, _node_desc);
|
SlObject(node, _node_desc);
|
||||||
for (NodeID to = 0; to < size; ++to) {
|
if (IsSavegameVersionBefore(191)) {
|
||||||
SlObject(&lg.edges[from][to], _edge_desc);
|
/* We used to save the full matrix ... */
|
||||||
|
for (NodeID to = 0; to < size; ++to) {
|
||||||
|
SlObject(&lg.edges[from][to], _edge_desc);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* ... but as that wasted a lot of space we save a sparse matrix now. */
|
||||||
|
for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) {
|
||||||
|
SlObject(&lg.edges[from][to], _edge_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,6 +229,23 @@ static void Load_LGRS()
|
||||||
*/
|
*/
|
||||||
void AfterLoadLinkGraphs()
|
void AfterLoadLinkGraphs()
|
||||||
{
|
{
|
||||||
|
if (IsSavegameVersionBefore(191)) {
|
||||||
|
LinkGraph *lg;
|
||||||
|
FOR_ALL_LINK_GRAPHS(lg) {
|
||||||
|
for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
|
||||||
|
(*lg)[node_id].UpdateLocation(Station::Get((*lg)[node_id].Station())->xy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkGraphJob *lgj;
|
||||||
|
FOR_ALL_LINK_GRAPH_JOBS(lgj) {
|
||||||
|
lg = &(const_cast<LinkGraph &>(lgj->Graph()));
|
||||||
|
for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
|
||||||
|
(*lg)[node_id].UpdateLocation(Station::Get((*lg)[node_id].Station())->xy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LinkGraphSchedule::Instance()->SpawnAll();
|
LinkGraphSchedule::Instance()->SpawnAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,8 +258,9 @@
|
||||||
* 188 26169 1.4.x
|
* 188 26169 1.4.x
|
||||||
* 189 26450
|
* 189 26450
|
||||||
* 190 26547
|
* 190 26547
|
||||||
|
* 191 26646
|
||||||
*/
|
*/
|
||||||
extern const uint16 SAVEGAME_VERSION = 190; ///< Current savegame version of OpenTTD.
|
extern const uint16 SAVEGAME_VERSION = 191; ///< Current savegame version of OpenTTD.
|
||||||
|
|
||||||
SavegameType _savegame_type; ///< type of savegame we are loading
|
SavegameType _savegame_type; ///< type of savegame we are loading
|
||||||
|
|
||||||
|
|
|
@ -649,7 +649,7 @@ static void UpdateStationSignCoord(BaseStation *st)
|
||||||
for (CargoID c = 0; c < NUM_CARGO; ++c) {
|
for (CargoID c = 0; c < NUM_CARGO; ++c) {
|
||||||
LinkGraphID lg = full_station->goods[c].link_graph;
|
LinkGraphID lg = full_station->goods[c].link_graph;
|
||||||
if (!LinkGraph::IsValidID(lg)) continue;
|
if (!LinkGraph::IsValidID(lg)) continue;
|
||||||
LinkGraph::Get(lg)->UpdateDistances(full_station->goods[c].node, st->xy);
|
(*LinkGraph::Get(lg))[full_station->goods[c].node].UpdateLocation(st->xy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue