linkgraph.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "../stdafx.h"
00013 #include "../map_func.h"
00014 #include "../core/bitmath_func.hpp"
00015 #include "../debug.h"
00016 #include "../window_func.h"
00017 #include "../window_gui.h"
00018 #include "linkgraph.h"
00019 #include "demands.h"
00020 #include "mcf.h"
00021 #include "flowmapper.h"
00022 #include <queue>
00023 
00027 LinkGraph _link_graphs[NUM_CARGO];
00028 
00032 LinkGraphJob::HandlerList LinkGraphJob::_handlers;
00033 
00040 inline void Node::Init(StationID st, uint sup, uint dem)
00041 {
00042   this->supply = sup;
00043   this->undelivered_supply = sup;
00044   this->demand = dem;
00045   this->station = st;
00046 
00047   for (PathSet::iterator i = this->paths.begin(); i != this->paths.end(); ++i) {
00048     delete *i;
00049   }
00050   this->paths.clear();
00051   this->flows.clear();
00052 }
00053 
00059 inline void Edge::Init(uint distance, uint capacity)
00060 {
00061   this->distance = distance;
00062   this->capacity = capacity;
00063   this->demand = 0;
00064   this->unsatisfied_demand = 0;
00065   this->flow = 0;
00066   this->next_edge = INVALID_NODE;
00067 }
00068 
00069 
00077 void LinkGraph::CreateComponent(Station *first)
00078 {
00079   std::map<Station *, NodeID> index;
00080   index[first] = this->AddNode(first);
00081 
00082   std::queue<Station *> search_queue;
00083   search_queue.push(first);
00084 
00085   /* Find all stations belonging to the current component. */
00086   while (!search_queue.empty()) {
00087     Station *source = search_queue.front();
00088     search_queue.pop();
00089 
00090     const LinkStatMap &links = source->goods[this->cargo].link_stats;
00091     for (LinkStatMap::const_iterator i = links.begin(); i != links.end(); ++i) {
00092       Station *target = Station::GetIfValid(i->first);
00093       if (target == NULL) continue;
00094 
00095       std::map<Station *, NodeID>::iterator index_it = index.find(target);
00096       if (index_it == index.end()) {
00097         search_queue.push(target);
00098         NodeID node = this->AddNode(target);
00099         index[target] = node;
00100 
00101         this->AddEdge(index[source], node, i->second.Capacity());
00102       } else {
00103         this->AddEdge(index[source], index_it->second, i->second.Capacity());
00104       }
00105     }
00106   }
00107 
00108   /* Here the list of nodes and edges for this component is complete. */
00109   this->SpawnThread();
00110 }
00111 
00125 void LinkGraph::NextComponent()
00126 {
00127   /* Check for no stations to avoid problems with Station::GetPoolSize()
00128    * being 0 later and to avoid searching an empty pool.
00129    */
00130   if (Station::GetNumItems() == 0) return;
00131 
00132   /* Don't mess with running jobs (might happen when changing interval).*/
00133   if (this->GetSize() > 0) return;
00134 
00135   /* The station pool may shrink when saving and subsequently loading a game as
00136    * NULL entries at the end are cut off then. If the current station id points
00137    * to one of those NULL entries we have to clamp it here to avoid an infinite
00138    * loop later.
00139    */
00140   StationID last_station_id = min(this->current_station_id, Station::GetPoolSize() - 1);
00141 
00142   /* In each run over the link graph at most half of the available component
00143    * IDs can be assigned. That's 32768. There is one special
00144    * INVALID_COMPONENT_ID which should not be used, so let's say 32767. A new
00145    * component ID is only issued if a station with a link for the respective
00146    * cargo is found. That means there have to be at least two stations in
00147    * that component. Each station can only be in one component at a time.
00148    * There can be up to 65534 stations in the game:
00149    * 2 ^ 16 available IDs - 2 special ones; INVALID_STATION and NEW_STATION.
00150    * So we need at most 65534 / 2 == 32767 component IDs in each run. Thus,
00151    * the component IDs will not overflow. There's an assert for that in
00152    * LinkGraphComponent::Init(). */
00153   LinkGraphComponentID current_component_id = this->LinkGraphComponent::index + 2;
00154 
00155   do {
00156     if (++this->current_station_id >= Station::GetPoolSize()) {
00157       /* Wrap around and recycle the component IDs. Use different
00158        * divisibility by 2 than in the last run so that we can find out
00159        * which stations haven't been seen in this run.
00160        */
00161       this->current_station_id = 0;
00162       current_component_id = (current_component_id + 1) % 2;
00163     }
00164 
00165     /* Find first station of next component */
00166     Station *station = Station::GetIfValid(this->current_station_id);
00167     if (station == NULL) continue;
00168     const GoodsEntry &ge = station->goods[this->cargo];
00169 
00170     /* Same divisibility by 2: We've seen that station before. */
00171     if (ge.last_component != INVALID_LINKGRAPH_COMPONENT &&
00172         (ge.last_component + current_component_id) % 2 == 0) {
00173       continue;
00174     }
00175 
00176     /* Different divisibility by 2: This station has not been seen
00177      * in the current run over the link graph. */
00178     if (!ge.link_stats.empty()) {
00179       this->LinkGraphComponent::Init(current_component_id);
00180       this->CreateComponent(station);
00181       return;
00182     }
00183 
00184   } while (this->current_station_id != last_station_id);
00185 }
00186 
00192 void OnTick_LinkGraph()
00193 {
00194   if (_date_fract != LinkGraph::COMPONENTS_SPAWN_TICK &&
00195       _date_fract != LinkGraph::COMPONENTS_JOIN_TICK) {
00196     return;
00197   }
00198 
00199   /* This creates a round robin distribution of all link graphs' turns over the
00200    * available dates. */
00201   for (uint cargo = _date % _settings_game.linkgraph.recalc_interval; cargo < NUM_CARGO;
00202       cargo += _settings_game.linkgraph.recalc_interval) {
00203 
00204     /* Don't calculate a link graph if the distribution is manual */
00205     if (_settings_game.linkgraph.GetDistributionType(cargo) == DT_MANUAL) continue;
00206 
00207     if (_date_fract == LinkGraph::COMPONENTS_SPAWN_TICK) {
00208       _link_graphs[cargo].NextComponent();
00209     } else /* LinkGraph::COMPONENTS_JOIN_TICK */ {
00210       _link_graphs[cargo].Join();
00211     }
00212   }
00213 }
00214 
00223 NodeID LinkGraphComponent::AddNode(Station *st)
00224 {
00225   GoodsEntry &good = st->goods[this->cargo];
00226   good.last_component = this->index;
00227 
00228   bool do_resize = (this->nodes.size() == this->num_nodes);
00229 
00230   if (do_resize) {
00231     this->nodes.push_back(Node());
00232     this->edges.push_back(std::vector<Edge>(this->num_nodes + 1));
00233   }
00234 
00235   this->nodes[this->num_nodes].Init(st->index, good.supply,
00236       HasBit(good.acceptance_pickup, GoodsEntry::GES_ACCEPTANCE));
00237 
00238   std::vector<Edge> &new_edges = this->edges[this->num_nodes];
00239 
00240   /* Reset the first edge starting at the new node */
00241   new_edges[this->num_nodes].next_edge = INVALID_NODE;
00242 
00243   for (NodeID i = 0; i < this->num_nodes; ++i) {
00244     uint distance = DistanceManhattan(st->xy, Station::Get(this->nodes[i].station)->xy);
00245     if (do_resize) this->edges[i].push_back(Edge());
00246     new_edges[i].Init(distance);
00247     this->edges[i][this->num_nodes].Init(distance);
00248   }
00249   return this->num_nodes++;
00250 }
00251 
00258 inline void LinkGraphComponent::AddEdge(NodeID from, NodeID to, uint capacity)
00259 {
00260   assert(from != to);
00261   Edge &edge = this->edges[from][to];
00262   Edge &first = this->edges[from][from];
00263   edge.capacity = capacity;
00264   edge.next_edge = first.next_edge;
00265   first.next_edge = to;
00266 }
00267 
00277 void LinkGraphComponent::SetSize()
00278 {
00279   if (this->nodes.size() < this->num_nodes) {
00280     for (EdgeMatrix::iterator i = this->edges.begin(); i != this->edges.end(); ++i) {
00281       i->resize(this->num_nodes);
00282     }
00283     this->nodes.resize(this->num_nodes);
00284     this->edges.resize(this->num_nodes, std::vector<Edge>(this->num_nodes));
00285   }
00286 
00287   for (uint i = 0; i < this->num_nodes; ++i) {
00288     this->nodes[i].Init();
00289     for (uint j = 0; j < this->num_nodes; ++j) {
00290       this->edges[i][j].Init();
00291     }
00292   }
00293 }
00294 
00298 LinkGraphComponent::LinkGraphComponent() :
00299     settings(_settings_game.linkgraph),
00300     cargo(INVALID_CARGO),
00301     num_nodes(0),
00302     index(INVALID_LINKGRAPH_COMPONENT)
00303 {}
00304 
00308 void LinkGraphComponent::Init(LinkGraphComponentID id)
00309 {
00310   assert(this->num_nodes == 0);
00311 
00312   /* -1 as we won't need the last even numbered ID anyway and IDs are
00313    * incremented by 2 with alternating divisibility by 2. Thus, if we just
00314    * asserted on INVALID_LINKGRAPH_COMPONENT we might not catch an overflow
00315    * in the even numbered case. */
00316   assert(id < INVALID_LINKGRAPH_COMPONENT - 1);
00317   this->index = id;
00318   this->settings = _settings_game.linkgraph;
00319 }
00320 
00321 
00330 void Node::ExportFlows(FlowMap::iterator &it, FlowStatMap &station_flows, CargoID cargo)
00331 {
00332   FlowStat *dest = NULL;
00333   StationID source = it->first;
00334   FlowViaMap &source_flows = it->second;
00335   if (!Station::IsValidID(source)) {
00336     source_flows.clear();
00337   } else {
00338     Station *curr_station = Station::Get(this->station);
00339     for (FlowViaMap::iterator update = source_flows.begin(); update != source_flows.end();) {
00340       StationID next = update->first;
00341       int planned = update->second;
00342       assert(planned >= 0);
00343 
00344       Station *via = Station::GetIfValid(next);
00345       if (planned > 0 && via != NULL) {
00346         if (next == this->station ||
00347             curr_station->goods[cargo].link_stats.find(next) !=
00348             curr_station->goods[cargo].link_stats.end()) {
00349           if (dest == NULL) {
00350             dest = &(station_flows.insert(std::make_pair(it->first, FlowStat(next, planned))).first->second);
00351           } else {
00352             dest->AddShare(next, planned);
00353           }
00354         }
00355       }
00356       source_flows.erase(update++);
00357     }
00358   }
00359 
00360   assert(source_flows.empty());
00361 
00362   this->flows.erase(it++);
00363 }
00364 
00369 void Node::ExportFlows(CargoID cargo)
00370 {
00371   FlowStatMap &station_flows = Station::Get(this->station)->goods[cargo].flows;
00372   station_flows.clear();
00373 
00374   /* Loop over flows in the node's map and insert them into the station. */
00375   for (FlowMap::iterator it(this->flows.begin()); it != this->flows.end();) {
00376     this->ExportFlows(it, station_flows, cargo);
00377   }
00378   assert(this->flows.empty());
00379 }
00380 
00384 void LinkGraph::Join()
00385 {
00386   this->LinkGraphJob::Join();
00387 
00388   for (NodeID node_id = 0; node_id < this->GetSize(); ++node_id) {
00389     Node &node = this->GetNode(node_id);
00390     if (Station::IsValidID(node.station)) {
00391       node.ExportFlows(this->cargo);
00392       InvalidateWindowData(WC_STATION_VIEW, node.station, this->GetCargo());
00393     }
00394   }
00395 
00396   this->LinkGraphComponent::Clear();
00397 }
00398 
00403 /* static */ void LinkGraphJob::RunLinkGraphJob(void *j)
00404 {
00405   LinkGraphJob *job = (LinkGraphJob *)j;
00406   for (HandlerList::iterator i = LinkGraphJob::_handlers.begin(); i != LinkGraphJob::_handlers.end(); ++i) {
00407     (*i)->Run(job);
00408   }
00409 }
00410 
00414 /* static */ void LinkGraphJob::ClearHandlers()
00415 {
00416   for (HandlerList::iterator i = LinkGraphJob::_handlers.begin(); i != LinkGraphJob::_handlers.end(); ++i) {
00417     delete *i;
00418   }
00419   LinkGraphJob::_handlers.clear();
00420 }
00421 
00430 void Path::Fork(Path *base, uint cap, int free_cap, uint dist)
00431 {
00432   this->capacity = min(base->capacity, cap);
00433   this->free_capacity = min(base->free_capacity, free_cap);
00434   this->distance = base->distance + dist;
00435   assert(this->distance > 0);
00436   if (this->parent != base) {
00437     this->Detach();
00438     this->parent = base;
00439     this->parent->num_children++;
00440   }
00441   this->origin = base->origin;
00442 }
00443 
00452 uint Path::AddFlow(uint new_flow, LinkGraphComponent *graph, bool only_positive)
00453 {
00454   if (this->parent != NULL) {
00455     Edge &edge = graph->GetEdge(this->parent->node, this->node);
00456     if (only_positive) {
00457       uint usable_cap = edge.capacity * graph->GetSettings().short_path_saturation / 100;
00458       if (usable_cap > edge.flow) {
00459         new_flow = min(new_flow, usable_cap - edge.flow);
00460       } else {
00461         return 0;
00462       }
00463     }
00464     new_flow = this->parent->AddFlow(new_flow, graph, only_positive);
00465     if (new_flow > 0) {
00466       graph->GetNode(this->parent->node).paths.insert(this);
00467     }
00468     edge.flow += new_flow;
00469   }
00470   this->flow += new_flow;
00471   return new_flow;
00472 }
00473 
00479 Path::Path(NodeID n, bool source) :
00480   distance(source ? 0 : UINT_MAX),
00481   capacity(0),
00482   free_capacity(source ? INT_MAX : INT_MIN),
00483   flow(0), node(n), origin(source ? n : INVALID_NODE),
00484   num_children(0), parent(NULL)
00485 {}
00486 
00490 inline void LinkGraphJob::Join()
00491 {
00492   if (this->thread == NULL) return;
00493   this->thread->Join();
00494   delete this->thread;
00495   this->thread = NULL;
00496 }
00497 
00502 void LinkGraphJob::SpawnThread()
00503 {
00504   assert(this->thread == NULL);
00505   if (!ThreadObject::New(&(LinkGraphJob::RunLinkGraphJob), this, &(this->thread))) {
00506     this->thread = NULL;
00507     /* Of course this will hang a bit.
00508      * On the other hand, if you want to play games which make this hang noticably
00509      * on a platform without threads then you'll probably get other problems first.
00510      * OK:
00511      * If someone comes and tells me that this hangs for him/her, I'll implement a
00512      * smaller grained "Step" method for all handlers and add some more ticks where
00513      * "Step" is called. No problem in principle.
00514      */
00515     LinkGraphJob::RunLinkGraphJob(this);
00516   }
00517 }
00518 
00524 void LinkGraph::Init(CargoID cargo)
00525 {
00526   this->LinkGraphJob::Join();
00527   this->LinkGraphComponent::Clear();
00528 
00529   this->current_station_id = 0;
00530   this->LinkGraphComponent::cargo = cargo;
00531 }
00532 
00536 void InitializeLinkGraphs()
00537 {
00538   for (CargoID c = 0; c < NUM_CARGO; ++c) _link_graphs[c].Init(c);
00539 
00540   LinkGraphJob::ClearHandlers();
00541   LinkGraphJob::AddHandler(new DemandHandler);
00542   LinkGraphJob::AddHandler(new MCFHandler<MCF1stPass>);
00543 
00544   /* It's easier to determine "has already a path" from the flows than from
00545    * the paths. In MCF2ndPass we only add new paths to edges which already
00546    * have a path. As there is no additional cost in clearing away the paths
00547    * from MCF1stPass early we just do that here to get the flows. */
00548   LinkGraphJob::AddHandler(new FlowMapper);
00549 
00550   LinkGraphJob::AddHandler(new MCFHandler<MCF2ndPass>);
00551   LinkGraphJob::AddHandler(new FlowMapper);
00552 }