将拓扑排序列表与原始列表进行比较

发布于 2024-11-19 16:24:45 字数 2596 浏览 2 评论 0原文

我有一个来自 mygraph 的顶点向量,并且我对顶点进行拓扑排序。

typedef typename boost::adjacency_list<boost::listS, boost::vecS, 
       boost::directedS,Vertex_t*> Graph_t;

typedef typename boost::graph_traits<Graph_t>::vertex_descriptor Vd_t;
Graph_t mygraph;
std::vector<Vd_t> v1; 
//initialize the vertices and get a copy of vertices in vector v1
//...
//and then i use

std::vector<Vd_t> v2;
boost::topological_sort(mygraph,std::back_inserter(v2));

“按顺序”对顶点进行拓扑排序。 那么比较 v1 和 v2 来测试我的原始顶点向量(v1)是否“按顺序”或“无序”的最佳方法是什么。

编辑: 例如: 如果向量 v1 有顶点 {A, B, C} 并且我们有边 (甲、乙) (C,A)

所以在拓扑排序之后,我将在 v2

{C, A, B}

中得到。在某些情况下,我可能无法获得唯一的拓扑顺序,例如,如果我有 (A,C) 作为唯一的边,那么 v2 可能会得到 {A , B , C} 或 {B , A , C}

现在我需要查看 v1 和 v2 以查明 v1 和 v2 是否表示相同的顺序。

第二次编辑: 我尝试了一种方法,目前有效,请告诉我这是否是一个好方法。

template <typename Vertex_t>
void DepAnalyzer<Vertex_t>::CheckTotalOrder()
{
  //Vd_t is the vertex descriptor type
  typename std::vector<Vd_t> topo_order;
  typename std::vector<Vd_t>::iterator ordered_vertices_iter;

  //puts the topologically sorted vertices into topo_order
  DoTopologicalSort(topo_order);

  //will point to the vertices in the order they were inserted
  typename boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end;
  std::unordered_map<Vertex_t*,int,std::hash<Vertex_t*>,
                      VertexEqual> orig_order_map, topo_order_map;  

  int i = 0;
  for(std::tie(vi, vi_end) = boost::vertices(depGraph); vi != vi_end; ++vi) {
    orig_order_map[depGraph[*vi]] = ++i;
    //std::cout<<depGraph[*vi]->get_identifier_str()<<"\n";
  }
  i = 0;
  //will point to the vertices in the topological order
  ordered_vertices_iter = topo_order.begin();
  for(;ordered_vertices_iter != topo_order.end(); ordered_vertices_iter++) {
    topo_order_map[depGraph[*ordered_vertices_iter]] = ++i;
    //std::cout<<depGraph[*ordered_vertices_iter]->get_identifier_str()<<"\n";
  }
  //checking the order now
  ordered_vertices_iter = topo_order.begin();
  for(;ordered_vertices_iter != topo_order.end(); ordered_vertices_iter++) {
    //if the vertex in topologically sorted list occurs before(w.r.t. position)
    //the macro in the original list of vertices, then it's okay
    if(orig_order_map[depGraph[*ordered_vertices_iter]] >
      topo_order_map[depGraph[*ordered_vertices_iter]]) {
      std::cerr << depGraph[*ordered_vertices_iter]->get_identifier_str() 
                << ": out of order\n";
    }
  }
}

i have a vector of vertices from mygraph, and i topologically sort the vertices.

typedef typename boost::adjacency_list<boost::listS, boost::vecS, 
       boost::directedS,Vertex_t*> Graph_t;

typedef typename boost::graph_traits<Graph_t>::vertex_descriptor Vd_t;
Graph_t mygraph;
std::vector<Vd_t> v1; 
//initialize the vertices and get a copy of vertices in vector v1
//...
//and then i use

std::vector<Vd_t> v2;
boost::topological_sort(mygraph,std::back_inserter(v2));

to topologically sort the vertices 'in order'.
So what is the best way to compare v1 and v2 to test if my original vector of vertices(v1) was 'in order' or 'out of order'.

EDIT:
For example:
if vector v1 has vertices {A, B, C} and we have edges
(A,B)
(C,A)

so after topological sort I'll have in v2

{C, A, B}

There will be cases where i may not get a unique topological order, for example if i have
(A,C) as the only edge, then v2 might end up with
{A , B , C} or {B , A , C}

Now i need to look into v1 and v2 to find out if both v1 and v2 represent the same order or not.

SECOND EDIT:
I tried an approach and it works for now, please tell me if this is a good approach or not.

template <typename Vertex_t>
void DepAnalyzer<Vertex_t>::CheckTotalOrder()
{
  //Vd_t is the vertex descriptor type
  typename std::vector<Vd_t> topo_order;
  typename std::vector<Vd_t>::iterator ordered_vertices_iter;

  //puts the topologically sorted vertices into topo_order
  DoTopologicalSort(topo_order);

  //will point to the vertices in the order they were inserted
  typename boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end;
  std::unordered_map<Vertex_t*,int,std::hash<Vertex_t*>,
                      VertexEqual> orig_order_map, topo_order_map;  

  int i = 0;
  for(std::tie(vi, vi_end) = boost::vertices(depGraph); vi != vi_end; ++vi) {
    orig_order_map[depGraph[*vi]] = ++i;
    //std::cout<<depGraph[*vi]->get_identifier_str()<<"\n";
  }
  i = 0;
  //will point to the vertices in the topological order
  ordered_vertices_iter = topo_order.begin();
  for(;ordered_vertices_iter != topo_order.end(); ordered_vertices_iter++) {
    topo_order_map[depGraph[*ordered_vertices_iter]] = ++i;
    //std::cout<<depGraph[*ordered_vertices_iter]->get_identifier_str()<<"\n";
  }
  //checking the order now
  ordered_vertices_iter = topo_order.begin();
  for(;ordered_vertices_iter != topo_order.end(); ordered_vertices_iter++) {
    //if the vertex in topologically sorted list occurs before(w.r.t. position)
    //the macro in the original list of vertices, then it's okay
    if(orig_order_map[depGraph[*ordered_vertices_iter]] >
      topo_order_map[depGraph[*ordered_vertices_iter]]) {
      std::cerr << depGraph[*ordered_vertices_iter]->get_identifier_str() 
                << ": out of order\n";
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

非要怀念 2024-11-26 16:24:45

那么比较 v1 和 v2 来测试我的原始顶点向量 (v1) 是“按顺序”还是“无顺序”的最佳方法是什么。

不比较向量。该测试存在缺陷,如果成功(两个向量相同),您将知道它是按顺序排列的,但如果失败(向量不同),您将不知道它是否乱序或是否处于不同的顺序。命令。

考虑该图(想象边缘向下):

  A
 / \
B   C
 \ /
  D

列表 { A, B, C, D }{ A, C, B, D } 均按拓扑顺序排列,因为 BC 之间没有排序约束。如果您有其中一个选项,并且 boost::topological_sort 产生了另一种变体,您将不知道您是否有一个错误的顺序,或者更确切地说是一个不同的正确顺序。

最好编写一个简单的算法来检查顺序的正确性并在需要时重新排序。

So what is the best way to compare v1 and v2 to test if my original vector of vertices(v1) was 'in order' or 'out of order'.

Not comparing the vectors. The test is flawed in that if it succeeds (both vectors are the same) you will know that it was in order, but if it fails (vectors differ) you will not know whether it was out of order or if it was in a different order.

Consider the graph (imagine edges going down):

  A
 / \
B   C
 \ /
  D

The lists { A, B, C, D } and { A, C, B, D } are both in topological order, because there is no ordering constraint between B and C. If you had one of the options and the boost::topological_sort yielded the other variant you will not know whether you had an incorrect order or rather a different correct one.

It is probably better to write a simple algorithm that will check the order for correctness and reorder if needed.

童话 2024-11-26 16:24:45

我是否正确理解你的问题,你想测试顶点列表是否已经按拓扑顺序排列?

如果是这样,您可以执行以下操作:

  • 令顶点列表为 v。现在构造一个列表r,其中r[i]给出顶点iv中的索引,即v[r[i]] = i
  • 然后循环遍历所有有向边(i,j)并检查r[i] <= r[j]
  • 如果是这样,则列表 v 已经按拓扑顺序排列。

然而,这与对 v 进行完整的拓扑排序一样慢(两者在边数和顶点数上都是线性的)。因此,如果您的目标只是让 v 按拓扑顺序排列,只需进行排序即可。如果可能的话,如果您需要将 v 保持在当前顺序,这将很有用。

Do I understand your question correctly that you want to test if a list of vertices is already in topological order?

If so, you might do the following:

  • Let the list of vertices be v. Now construct a list r where r[i] gives the index of vertex i in v, i.e. v[r[i]] = i.
  • Then loop over all directed edges (i,j) and check that r[i] <= r[j].
  • If so, the list v is already in topological order.

However, this will be just as slow as doing a full topological sort of v (both are linear in the number of edges plus number of vertices). So if your aim is just to have v in topological order, just do the sorting. If you need to keep v in the current order if possible, this will be useful.

满栀 2024-11-26 16:24:45

std::vectoroperator== 所以你可以简单地 if(v1==v2)

编辑:这是一个充分但不是必要的条件。

std::vector has operator== so you can simply if(v1==v2)

Edit: this is a sufficient but not neccesary condition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文