在无向图上设置值

时间:2014-05-29 19:16:05

标签: c++ graph graph-algorithm

我有一个在节点上有值的图表

  

value = A / B / C

     

values = {A,B,C}

目标:连接后的节点在建立后必须具有相同的值:

示例:

  

预先安排:

     

node1 = {A,B}

     

node2 = {A,B,C}

     

node3 = {D}

     

解决后:

     

node1 = {A,B,C,D}

     

node2 = {A,B,C,D}

     

node3 = {A,B,C,D}

结算算法:

建立节点对(node1,node2),(node2,node3)等

didSomething = false
doWhile ( didSomething ) 
  for ( iterate all pairs ) 
   didSomething |= settle ( a-pair )
如果(node1.values!= node2.values)

didSomething为真

问题:有些图表设置需要很长时间才能确定。

最好不要使用连接组件的概念,某些节点获得与其他节点不同的价值

> **gprof**
>
>   SkipAcrossBlocks::PortSpreader::settle() [12] [13]    56.1    0.09  
> 48.77 7367012         SkipAcrossBlocks::EdgePair::settle() [13]
>                 0.03   45.78 7367012/7367012     bool std::operator=  
> <SkipAcrossBlocks::OneJumpRecord,
> std::less<SkipAcrossBlocks::OneJumpRecord>,
> std::allocator<SkipAcrossBlocks::OneJumpRecord>
> >(std::set<SkipAcrossBlocks::OneJumpRecord, 
> std::less<SkipAcrossBlocks::OneJumpRecord>,
> std::allocator<SkipAcrossBlocks::OneJumpRecord> > const&,
> std::set<SkipAcrossBlocks::OneJumpRecord,
> std::less<SkipAcrossBlocks::OneJumpRecord>,
> std::allocator<SkipAcrossBlocks::OneJumpRecord> > const&) [14]
     

SkipAcrossBlocks :: OneJumpRecord =“value”

     

std :: set&lt; SkipAcrossBlocks :: OneJumpRecord&gt; “价值观”

gprof说 7 * 10 ^ 6次调用比较“值”的相等性 占用大部分时间。

为了完整性,

确定一对节点:

bool EdgePair::settle() {

       // if edge is internalRailORglobal should not aquire other rails

       if ( edge1->cannotAquire() && edge2->cannotAquire() ) {
          return false;
       }
       else if ( !edge1->cannotAquire() && edge2->cannotAquire() ) {
          if ( edge1->superSetOf( edge2 )) {
             return false;
          }
          edge1->spreadValues.insert( edge2->spreadValues.begin(), edge2->spreadValues.end());
          return true;
       }
       else if ( edge1->cannotAquire() && !edge2->cannotAquire() ) {
          if ( edge2->superSetOf( edge1 )) {
             return false;
          }
          edge2->spreadValues.insert( edge1->spreadValues.begin(), edge1->spreadValues.end());
          return true;
       }
       else {
          // neither are internalORglobal

          if ( edge1->spreadValues == edge2->spreadValues ) {
             return false;
          }
          edge1->spreadValues.insert( edge2->spreadValues.begin(), edge2->spreadValues.end());
          edge2->spreadValues = edge1->spreadValues;
          return true;
       }
    }

以下平等比较似乎需要时间:

          if ( edge1->spreadValues == edge2->spreadValues ) {
             return false;
          }

我会感兴趣:

  • 可以使比较更加有效
  • 其他算法/想法
  • 最好不要使用连接组件的概念,某些节点获得与其他节点不同的价值

由于

1 个答案:

答案 0 :(得分:1)

您实际上是以非常低效的方式计算连接组件。由于您的答案取决于连接的组件,因此您不太可能找到一些不使用它们的算法。

好消息是可以非常快速有效地计算连通组件,请参阅Boost.Graph库中的示例:http://www.boost.org/doc/libs/1_55_0/libs/graph/example/connected_components.cpp

你的整个流程可能是:

  1. numComponents = boost :: connected_components(G,componentsMap);
  2. vector allValues(numComponents);
  3. 一次通过componentsMap来填充allValues
  4. 一次通过allValues将它们与顶点相关联
  5. 复杂性几乎是线性的w.r.t.图表大小。