【问题标题】:inverse an oriented Graph逆向图
【发布时间】:2020-08-12 17:52:53
【问题描述】:

如何反转不转置有向图?

 Graphe *Graphe::grapheInverse( void ){
     Graphe *r = new Graphe (_adjacences.size() );
      for (unsigned i = 0; i < _adjacences.size(); i++){
          for (unsigned j = 0; j < _adjacences[i]->size(); j++){
              //r->addArcs(j,i); this doesn't work
          }
      }
      return r;
  }

_adjances 在哪里:vector&lt; vector&lt; int &gt; * &gt; _adjacences;

addArcs 是:

void Graphe::addArcs( int a_sommet1, int a_sommet2 ){
    assert( 0 <= a_sommet1 && a_sommet1 < _adjacences.size() );
    assert( nullptr != _adjacences[a_sommet1] );
    _adjacences[a_sommet1]->push_back( a_sommet2 );
}

例子:

    Graphe g( 5 );
    g.addArcs( 0, 1 );
    g.addArcs( 0, 4 );
    g.addArcs( 1, 0 );
    g.addArcs( 1, 4 );
    g.addArcs( 2, 0 );
    g.addArcs( 2, 1 );
    g.addArcs( 2, 3 );
    g.addArcs( 2, 4 );
    g.addArcs( 4, 3 );
    g.addArcs( 4, 1 );

    // inversion du graphe :
    Graphe *r = g.grapheInverse();

我的完整代码如下:

Graphe.hpp

#include <iostream>
#include <vector>

using namespace std;

class Graphe
{
private:
    vector< vector< int > * > _adjacences;
public:
    Graphe( void );
    Graphe( int a_nbSommet );
    virtual ~Graphe( void );

    int nbSommet( void ) const;
    vector< int > * adjacences( int a_sommet );
    void addArcs( int a_sommet1, int a_sommet2 );

    Graphe * grapheInverse( void );

    friend ostream & operator <<( ostream &, Graphe const & );
};

Graphe.cpp

#include "Graphe.hpp"

#include <algorithm>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <vector>

using namespace std;

Graphe::Graphe( void )
{
}


Graphe::Graphe( int a_nbSommet ): _adjacences( a_nbSommet ){
    int i;
    for( i = 0; i < a_nbSommet; ++ i ){
        _adjacences[i] = new vector< int >();
    }
}


Graphe::~Graphe( void )
{
}


void Graphe::addArcs( int a_sommet1, int a_sommet2 ){
    assert( 0 <= a_sommet1 && a_sommet1 < _adjacences.size() );
    assert( nullptr != _adjacences[a_sommet1] );
    _adjacences[a_sommet1]->push_back( a_sommet2 );
}


int Graphe::nbSommet( void ) const{
    return _adjacences.size();
}


vector< int > *Graphe::adjacences( int a_sommet ){
    assert( 0 <= a_sommet && a_sommet < _adjacences.size() );
    return _adjacences[ a_sommet ];
}


Graphe *Graphe::grapheInverse( void ){
    Graphe *r = new Graphe (_adjacences.size() );
    for (unsigned i = 0; i < _adjacences.size(); i++)
        for ( unsigned j = 0; j < _adjacences[i]->size(); j++ )
            r->addArcs ((*_adjacences[i])[j],i); 
    return r;
}


ostream &operator <<( ostream & a_out, Graphe const & a_graphe ){
    int i = 0;
    int j = 0;

    for( i = 0; i < a_graphe._adjacences.size(); ++ i ){
        a_out << i << " : ";
        for( j = 0; j < a_graphe._adjacences[i]->size(); ++ j ){
            if( 0 != j ){
                a_out << ", ";
            }
            a_out << ( a_graphe._adjacences[i]->at(j) );
        }
        a_out << endl;
    }

    return a_out;
}

我的主

#include "Graphe.hpp"


#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <vector>

using namespace std;

int main( int argn, char * argv[] ){
    // construction of the graph :
    Graphe g( 5 );
    g.addArcs( 0, 1 );
    g.addArcs( 0, 4 );
    g.addArcs( 1, 0 );
    g.addArcs( 1, 4 );
    g.addArcs( 2, 0 );
    g.addArcs( 2, 1 );
    g.addArcs( 2, 3 );
    g.addArcs( 2, 4 );
    g.addArcs( 4, 3 );
    g.addArcs( 4, 1 );

    // inversion of the graph :
    Graphe *r = g.grapheInverse();

    // printing the both lists for verification
    cout << g << endl;
    cout << *r << endl;
}

这给了我:

g:
0 : 1, 4
1 : 0, 4
2 : 0, 1, 3, 4
3 : 
4 : 3, 1

r:
0 : 1, 2
1 : 0, 2, 4
2 : 
3 : 2, 4
4 : 0, 1, 2

【问题讨论】:

  • 1.你为什么使用指针而不是普通对象,2.为什么邻接表是指针向量,即为什么vector&lt;vector&lt;int&gt;*&gt; _adjacences而不是vector&lt;vector&lt;int&gt;&gt; _adjacences
  • 因为我主要有一些使用这些指针的测试要运行。无论如何它仍然给出相同的结果
  • 避免拥有裸指针。
  • 我看到你现在已经添加了一些代码。好的。虽然它不是最小的。这是您的程序的my version。由于它都在一个大块中,每个人都可以轻松地复制/编译它。我已经删除了您不使用的所有内容并修复了有关符号等的所有警告。我已经删除了参数 sepc 中的 ( void ) 到我在您不需要之前告诉您的函数,并按值返回倒置图(为什么要返回一个指针?!)。当然,它仍然有可怕的内存泄漏。您使用哪些编译器选项?您需要提高警告级别并照顾好所有人。
  • @TedLyngmo 先生,它按预期工作,是的,没有一个指针,我可以看到大声笑。再次感谢 TED

标签: c++ graph


【解决方案1】:

制作反向列表时,不想将原列表中的索引作为源顶点,需要对列表进行解引用。所以你会想要使用

r->addArcs((*_adjacences[i])[j],i);

有更好的方法来编写该函数(例如基于范围的 for 循环)。

【讨论】:

  • 我怎么能超越这个error: no viable conversion from 'std::__1::vector&lt;int, std::__1::allocator&lt;int&gt; &gt;' to 'int',因为那个vector&lt;vector&lt;int&gt;*&gt;
  • @azaiz 我已经更新了代码以在取下标之前取消引用内部向量。
  • @azaiz 没有提供带有示例输入和预期输出的minimal reproducible example 的问题是人们无法检查他们的答案是否真的符合提问者的要求。
  • @azaiz 我采用了您的代码,我的修复程序,并添加了许多其他代码,以使我能够编译和运行您的代码,包括添加打印功能。我得到了预期的换位。编辑您的问题以包含我们可以编译和运行的代码,因为您评论中的问题似乎在您未显示的代码中。
  • @1201ProgramAlarm 好的先生,我马上修改
猜你喜欢
  • 2011-03-20
  • 2010-09-10
  • 2018-06-22
  • 2019-04-06
  • 2021-09-29
  • 2018-10-30
  • 2012-08-26
  • 2013-01-13
  • 1970-01-01
相关资源
最近更新 更多