c++ - 有限空间内的图可达性

标签 c++ algorithm graph

我有一个有向图 G,有 N 个顶点,其中 k 个标记为“终端”。我想用从 v 可达的一组终端顶点标记每个顶点 v。我可以在空间 (R+r)N 中这样做吗,其中 R 是从 G 的节点可达的终端顶点的平均数量,r是一个小常数吗?

为了使这个更具体,数据结构大致如下所示:

struct Node{
  bool isTerminal(); // True if this is a terminal node
  vector<Node*> successors() ; //return the successors of this node
  set<Node*> reachable_terminals; //the value to compute
  bool done; //initially false
}

我们想要一个函数

void set_reachables(vector<Node> &); // the "&" means "pass by reference" in C++

它采用表示 G 中顶点的 Node vector ,并将 G 中每个节点的“reachable_terminals”成员设置为从该节点可达的终端。

具体来说,N 约为 100,000,00,k 约为 150。平均分支因子约为 3,从任何特定顶点最多只能到达约 1000 个顶点。 (通常最多可以从任何 v 到达十个终端顶点)。

现在,如果 G 是非循环的,则可以使用简单的深度优先搜索。这是导致问题的周期。此外,如果空间不是问题,我可以计算并存储每个节点的前任节点,然后从终端节点向后工作,但这会占用太多空间(请注意,节点 v 的后继节点不与 v 一起存储,而是计算出来的必要时在运行中),并且我希望不必为每个节点多次计算 successors()

我正在使用 C++,但任何算法描述都可以。

编辑:请注意,非循环情况下的 DFS 使用如下算法工作:

void set_reachables(vector<Node>&v){
   for(auto & node:v) node.visit();
}

set<Node*> Node::visit(){
  if (node.isTerminal()) reachableTerminals.insert(this);
  if (done) return reachableTerminals;
  for(auto&node:successors())
    reachableTerminals=set_union(reachableTerminals,node.visit());
  done=true;
  return reachableTerminals;
}

显然,如果图是循环的,该算法将失败。

最佳答案

由于平均分支因子是常数,E = O(V),其中E是边数,V是顶点的数量。反转图中的所有边。现在,从每个终端顶点开始执行 DFS,并相应地标记从终端顶点可达的所有顶点。这将在 O(kE) 时间内解决您的问题。虽然这不会达到您要求的复杂性,但考虑到您的图表上还有其他严格的稀疏性条件,这可能就足够了。 (当然,不是一般情况下,但我猜你的情况下你可能有更多的结构给其他人。)

关于c++ - 有限空间内的图可达性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24967434/

相关文章:

用于动态可视化的 Java 图形库

python - 如何沿曲线注释文本

c++ - std::ifstream,删除函数的使用

c++ - 负数的 lexical_cast 在不同的机器上表现不同

c++ - 自由函数的模板参数

c++ - 在计算列表中获取前 n 项的最快方法是什么?

python - 家谱图数据库

c++ - 两种语法 new( int[ size ] ) 和 new int[ size ] 之间的区别

algorithm - 如何在 python 中使用 triangle 库中的 triangulate

algorithm - 如何将 1 亿个字符串映射到 10 万个 int?