How do you transform Adjacency matrices to Incidence matrices and vice-versa?

与世无争的帅哥 提交于 2021-01-27 18:00:32

问题


Let's say the matrices are the following: (N = 4)

Adjacency:

0110 1001 1001 0110

Incidence:

1100 1010 0101 0011

How can you get the Incidence matrix from having just the Adjacency one, and vice-versa?

P.S: The Adjacency Matrix I'm getting from a .txt document, which I've read into an array and got it by the following algorithm:

int read(){

    ifstream graf("graf.txt");
    if(graf.is_open()){
        graf >> n;
        for (int i=0; i < n; i++) {
        for(int j = 0; j<2; j++)
                graf >> Graf[i][j];
        }
    }
    graf.close();
    return 0;
}

void adj() {
    for (int i=0; i<n; i++)
        for (int j=0; j<n; j++)
        sz[i][j] = 0;
    for (int i=0; i<n; i++)
        for (int j=0; j<2; j++)
        {sz[Graf[i][j]-1][Graf[i][j+1]-1] = 1;}
    for (int i=0; i<n; i++)
        for (int j=0; j<n; j++)
        sz[j][i] = sz[i][j];
}

回答1:


You can turn an adjacency matrix into an incidence matrix by looking at every possible connection between vertices and whenever there is indeed a connection, add an edge to your incidence matrix. Be careful to look at each combination of vertices only once, though.

The other way around, you can simply look at each edge. The incidence matrix specifies for each edge, which two vertices it connects.

The one situation you cannot recreate is when more than a single edge connects the same two vertices.

Here's some source code to illustrate the above explanations (See it work):

#include <vector>
#include <cassert>
#include <iostream>

typedef std::vector<bool> matrix_row;
typedef std::vector<matrix_row> matrix; // Saves some typing

// The initially given matrix. Uses C++11 initializer list.
matrix adj = 
{
    { 1, 1, 1, 0 },
    { 1, 0, 0, 1 },
    { 1, 0, 0, 1 },
    { 0, 1, 1, 0 }
};

matrix adjacency_to_incidence(const matrix &adj)
{
    int cols = adj.size();
    assert(cols > 0);

    int rows = adj[0].size();
    assert(rows > 0);

    assert(rows == cols);

    int edge = 0;
    matrix incidence;

    for (int col = 0; col < cols; ++col) {
        // We only look at half the adjacency matrix, so that we only add each
        // edge to the incidence matrix once.
        for (int row = 0; row <= col; ++row) {
            if (adj[col][row]) {
                incidence.push_back(matrix_row(cols, 0));
                incidence[edge][row] = incidence[edge][col] = 1;
                ++edge;
            }
        }
    }

    return incidence;
}

matrix incidence_to_adjacency(const matrix &inc)
{
    int edges = inc.size();
    assert(edges > 0);

    int vertices = inc[0].size();
    assert(vertices > 0);

    matrix adjacency(vertices, matrix_row(vertices, 0));

    for (int edge = 0; edge < edges; ++edge) {
        int a = -1, b = -1, vertex = 0;
        for (; vertex < vertices && a == -1; ++vertex) {
            if (inc[edge][vertex]) a = vertex;
        }
        for (; vertex < vertices && b == -1; ++vertex) {
            if (inc[edge][vertex]) b = vertex;
        }
        if (b == -1) b = a;
        adjacency[a][b] = adjacency[b][a] = 1;
    }

    return adjacency;
}

void print_matrix(const matrix &m)
{
    int cols = m.size();
    if (cols == 0) return;
    int rows = m[0].size();
    if (rows == 0) return;

    for (int c = 0; c < cols; ++c) {
        for (int r = 0; r < rows; ++r) {
            std::cout << m[c][r] << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

int main()
{
    matrix incidence = adjacency_to_incidence(adj);
    print_matrix(incidence);

    matrix adjacency = incidence_to_adjacency(incidence);
    print_matrix(adjacency);

    return 0;
}

When your graph is large, it might be worth considering running the loop in adjacency_to_incidence twice. The first time to count the amount of edges, then initialize the matrix with enough space and then loop over the adjacency matrix again to populate the incidence matrix.



来源:https://stackoverflow.com/questions/22380139/how-do-you-transform-adjacency-matrices-to-incidence-matrices-and-vice-versa

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!