本文整理汇总了C++中LinkGraphJob类的典型用法代码示例。如果您正苦于以下问题:C++ LinkGraphJob类的具体用法?C++ LinkGraphJob怎么用?C++ LinkGraphJob使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了LinkGraphJob类的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: FOR_ALL_LINK_GRAPHS
/**
* Shift all dates (join dates and edge annotations) of link graphs and link
* graph jobs by the number of days given.
* @param interval Number of days to be added or subtracted.
*/
void LinkGraphSchedule::ShiftDates(int interval)
{
LinkGraph *lg;
FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(interval);
LinkGraphJob *lgj;
FOR_ALL_LINK_GRAPH_JOBS(lgj) lgj->ShiftJoinDate(interval);
}
示例2: TileXY
/**
* Create the DemandCalculator and immediately do the calculation.
* @param job Job to calculate the demands for.
*/
DemandCalculator::DemandCalculator(LinkGraphJob &job) :
max_distance(DistanceMaxPlusManhattan(TileXY(0,0), TileXY(MapMaxX(), MapMaxY())))
{
const LinkGraphSettings &settings = job.Settings();
CargoID cargo = job.Cargo();
this->accuracy = settings.accuracy;
this->mod_dist = settings.demand_distance;
if (this->mod_dist > 100) {
/* Increase effect of mod_dist > 100 */
int over100 = this->mod_dist - 100;
this->mod_dist = 100 + over100 * over100;
}
switch (settings.GetDistributionType(cargo)) {
case DT_SYMMETRIC:
this->CalcDemand<SymmetricScaler>(job, SymmetricScaler(settings.demand_size));
break;
case DT_ASYMMETRIC:
this->CalcDemand<AsymmetricScaler>(job, AsymmetricScaler());
break;
default:
/* Nothing to do. */
break;
}
}
示例3: JoinNext
/**
* Join the next finished job, if available.
*/
void LinkGraphSchedule::JoinNext()
{
if (this->running.empty()) return;
LinkGraphJob *next = this->running.front();
if (!next->IsFinished()) return;
this->running.pop_front();
LinkGraphID id = next->LinkGraphIndex();
delete next; // implicitly joins the thread
if (LinkGraph::IsValidID(id)) {
LinkGraph *lg = LinkGraph::Get(id);
this->Unqueue(lg); // Unqueue to avoid double-queueing recycled IDs.
this->Queue(lg);
}
}
示例4: Load_LGRJ
/**
* Load all link graph jobs.
*/
static void Load_LGRJ()
{
int index;
while ((index = SlIterateArray()) != -1) {
if (!LinkGraphJob::CanAllocateItem()) {
/* Impossible as they have been present in previous game. */
NOT_REACHED();
}
LinkGraphJob *lgj = new (index) LinkGraphJob();
SlObject(lgj, GetLinkGraphJobDesc());
LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph());
SlObject(&lg, GetLinkGraphDesc());
lg.Init(_num_nodes);
SaveLoad_LinkGraph(lg);
}
}
示例5: Run
/**
* Map the paths generated by the MCF solver into flows associated with nodes.
* @param component the link graph component to be used.
*/
void FlowMapper::Run(LinkGraphJob &job) const
{
for (NodeID node_id = 0; node_id < job.Size(); ++node_id) {
Node prev_node = job[node_id];
StationID prev = prev_node.Station();
PathList &paths = prev_node.Paths();
for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) {
Path *path = *i;
uint flow = path->GetFlow();
if (flow == 0) break;
Node node = job[path->GetNode()];
StationID via = node.Station();
StationID origin = job[path->GetOrigin()].Station();
assert(prev != via && via != origin);
/* Mark all of the flow for local consumption at "first". */
node.Flows().AddFlow(origin, via, flow);
if (prev != origin) {
/* Pass some of the flow marked for local consumption at "prev" on
* to this node. */
prev_node.Flows().PassOnFlow(origin, via, flow);
} else {
/* Prev node is origin. Simply add flow. */
prev_node.Flows().AddFlow(origin, via, flow);
}
}
}
for (NodeID node_id = 0; node_id < job.Size(); ++node_id) {
/* Remove local consumption shares marked as invalid. */
Node node = job[node_id];
FlowStatMap &flows = node.Flows();
flows.FinalizeLocalConsumption(node.Station());
if (this->scale) {
/* Scale by time the graph has been running without being compressed. */
uint runtime = job.JoinDate() - job.Settings().recalc_time - job.LastCompression();
for (FlowStatMap::iterator i = flows.begin(); i != flows.end(); ++i) {
i->second.ScaleToMonthly(runtime);
}
}
/* Clear paths. */
PathList &paths = node.Paths();
for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) {
delete *i;
}
paths.clear();
}
}
示例6: AfterLoadLinkGraphs
/**
* Spawn the threads for running link graph calculations.
* Has to be done after loading as the cargo classes might have changed.
*/
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);
}
}
}
示例7: FlowEdgeIterator
/**
* Constructor.
* @param job Link graph job to work with.
*/
FlowEdgeIterator(LinkGraphJob &job) : job(job)
{
for (NodeID i = 0; i < job.Size(); ++i) {
StationID st = job[i].Station();
if (st >= this->station_to_node.size()) {
this->station_to_node.resize(st + 1);
}
this->station_to_node[st] = i;
}
}
示例8: while
/**
* Start the next job in the schedule.
*/
void LinkGraphSchedule::SpawnNext()
{
if (this->schedule.empty()) return;
LinkGraph *next = this->schedule.front();
LinkGraph *first = next;
while (next->Size() < 2) {
this->schedule.splice(this->schedule.end(), this->schedule, this->schedule.begin());
next = this->schedule.front();
if (next == first) return;
}
assert(next == LinkGraph::Get(next->index));
this->schedule.pop_front();
if (LinkGraphJob::CanAllocateItem()) {
LinkGraphJob *job = new LinkGraphJob(*next);
job->SpawnThread();
this->running.push_back(job);
} else {
NOT_REACHED();
}
}
示例9: MultiCommodityFlow
/**
* Run the second pass of the MCF calculation which assigns all remaining
* demands to existing paths.
* @param job Link graph job to calculate.
*/
MCF2ndPass::MCF2ndPass(LinkGraphJob &job) : MultiCommodityFlow(job)
{
this->max_saturation = UINT_MAX; // disable artificial cap on saturation
PathVector paths;
uint size = job.Size();
uint accuracy = job.Settings().accuracy;
bool demand_left = true;
while (demand_left) {
demand_left = false;
for (NodeID source = 0; source < size; ++source) {
this->Dijkstra<CapacityAnnotation, FlowEdgeIterator>(source, paths);
for (NodeID dest = 0; dest < size; ++dest) {
Edge edge = this->job[source][dest];
Path *path = paths[dest];
if (edge.UnsatisfiedDemand() > 0 && path->GetFreeCapacity() > INT_MIN) {
this->PushFlow(edge, path, accuracy, UINT_MAX);
if (edge.UnsatisfiedDemand() > 0) demand_left = true;
}
}
this->CleanupPaths(source, paths);
}
}
}
示例10: FlowEdgeIterator
/**
* Constructor.
* @param job Link graph job to work with.
*/
FlowEdgeIterator(LinkGraphJob &job) : job(job)
{
for (NodeID i = 0; i < job.Size(); ++i) {
this->station_to_node[job[i].Station()] = i;
}
}
示例11: CalcDemand
void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler)
{
NodeList supplies;
NodeList demands;
uint num_supplies = 0;
uint num_demands = 0;
for (NodeID node = 0; node < job.Size(); node++) {
scaler.AddNode(job[node]);
if (job[node].Supply() > 0) {
supplies.push_back(node);
num_supplies++;
}
if (job[node].Demand() > 0) {
demands.push_back(node);
num_demands++;
}
}
if (num_supplies == 0 || num_demands == 0) return;
/* Mean acceptance attributed to each node. If the distribution is
* symmetric this is relative to remote supply, otherwise it is
* relative to remote demand. */
scaler.SetDemandPerNode(num_demands);
uint chance = 0;
while (!supplies.empty() && !demands.empty()) {
NodeID from_id = supplies.front();
supplies.pop_front();
for (uint i = 0; i < num_demands; ++i) {
assert(!demands.empty());
NodeID to_id = demands.front();
demands.pop_front();
if (from_id == to_id) {
/* Only one node with supply and demand left */
if (demands.empty() && supplies.empty()) return;
demands.push_back(to_id);
continue;
}
int32 supply = scaler.EffectiveSupply(job[from_id], job[to_id]);
assert(supply > 0);
/* Scale the distance by mod_dist around max_distance */
int32 distance = this->max_distance - (this->max_distance -
(int32)job[from_id][to_id].Distance()) * this->mod_dist / 100;
/* Scale the accuracy by distance around accuracy / 2 */
int32 divisor = this->accuracy * (this->mod_dist - 50) / 100 +
this->accuracy * distance / this->max_distance + 1;
assert(divisor > 0);
uint demand_forw = 0;
if (divisor <= supply) {
/* At first only distribute demand if
* effective supply / accuracy divisor >= 1
* Others are too small or too far away to be considered. */
demand_forw = supply / divisor;
} else if (++chance > this->accuracy * num_demands * num_supplies) {
/* After some trying, if there is still supply left, distribute
* demand also to other nodes. */
demand_forw = 1;
}
demand_forw = min(demand_forw, job[from_id].UndeliveredSupply());
scaler.SetDemands(job, from_id, to_id, demand_forw);
if (scaler.HasDemandLeft(job[to_id])) {
demands.push_back(to_id);
} else {
num_demands--;
}
if (job[from_id].UndeliveredSupply() == 0) break;
}
if (job[from_id].UndeliveredSupply() != 0) {
supplies.push_back(from_id);
} else {
num_supplies--;
}
}
}