bool partition_gas_tubes(Digraph& dg, ArcFilter& arc_filter, NodeArray& pumps, GasTubeTypeMap& gtt) { //标记所有分支为负压管 for( Digraph::ArcIt e( dg ); e != INVALID; ++e ) { gtt[e] = GTT_NEGATIVE; } //用FilterArc适配器过滤一部分分支 typedef FilterArcs<Digraph, ArcFilter> Adaptor; Adaptor adaptor(dg, arc_filter); PositiveTubeVisitorFunctor func(gtt); typedef PositiveTubeVisitor<Adaptor, PositiveTubeVisitorFunctor> VisitoAdaptor; typedef DfsVisit<Adaptor, VisitoAdaptor> DfsVisitAdaptor; bool ret = true; //从所有的泵分支的末点开始,做一次dfs //遍历到的所有分支均视作正压管 for( int i = 0; i < pumps.size(); i++ ) { //初始化假设没有出现泵串联的情况 func.inSeriable = false; //定义dfs visitor,用于在dfs遍历的过程中对分支进行标记 VisitoAdaptor visitor( func ); DfsVisitAdaptor dv( adaptor, visitor ); //从泵分支的末节点开始dfs Digraph::Node u = pumps[i]; dv.run(u); //如果串联,则标记结果为false if(func.inSeriable) { ret = false; } } return ret; }
static void CriticalActivity(DGR& dg, Weight& w, EdgeArray& criticalEdges) { //过滤后的图 typedef typename DGR::template NodeMap<double> EventTimeMap; typedef typename DGR::template ArcMap<double> ActivityTimeMap; //正向拓扑排序,计算ve //事件最早发生时间vt EventTimeMap ve(dg,0); NodeArray nodes; GraphUtils::TopologySort(dg, nodes); // nodes[0] == sn for(size_t i=0;i<nodes.size();i++) { Digraph::Node uu = nodes[i]; double maxTime = DBL_MIN; int count = 0; for(typename DGR::InArcIt e(dg,uu);e!=INVALID;++e) { count++; double t = ve[dg.source(e)] + w[e]; if(t > maxTime) { maxTime = t; } } if(count > 0) { ve[uu]=maxTime; } } //逆向拓扑排序,计算vt //vt默认初始话为ve拓扑序列的最后一个节点值 //事件最晚发生时间vt EventTimeMap vt(dg,ve[nodes.back()]); //拓扑序列反向 GraphUtils::ReverseArray(nodes); for(size_t i=0;i<nodes.size();i++) { Digraph::Node uu = nodes[i]; double minTime = DBL_MAX; int count = 0; for(typename DGR::OutArcIt e(dg,uu);e!=INVALID;++e) { double t = ve[dg.target(e)] - w[e]; if(t < minTime) { minTime = t; } count++; } if(count > 0) { vt[uu] = minTime; } } //活动最早开始和最晚开始时间 ActivityTimeMap et(dg), lt(dg); for(typename DGR::ArcIt e(dg);e!=INVALID;++e) { Digraph::Node u = dg.source(e); Digraph::Node v = dg.target(e); et[e] = ve[dg.source(e)]; lt[e] = vt[dg.target(e)] - w[e]; //如果et[e] == lt[e],则该分支为关键活动分支 if(abs(et[e] - lt[e]) < 0.001) { criticalEdges.push_back(e); } } }