【问题标题】:How do you transform Adjacency matrices to Incidence matrices and vice-versa?您如何将邻接矩阵转换为关联矩阵,反之亦然?
【发布时间】:2014-03-13 13:28:11
【问题描述】:

假设矩阵如下: (N = 4)

邻接:

0110 1001 1001 0110

发病率:

1100 1010 0101 0011

你怎么能从只有邻接矩阵得到发生矩阵,反之亦然?

P.S:我从 .txt 文档中获得的邻接矩阵,我已将其读入数组并通过以下算法得到它:

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];
}

【问题讨论】:

  • 大概这是一道数学题,不是 C++ 特有的。
  • 当然是,只是未能将其添加为标签 :) ** 现已添加,感谢您的指点!
  • 这个问题似乎是题外话,因为它是关于一个数学问题。让我们把它移到 math.stackexchange.com
  • 问题是它不让我把它贴在那里,它需要我有 1000 RP 才能添加我没有的“图形”标签。
  • @Shadpwness 嗯,它实际上更适合 mathoverflow.net。只需在此处使用图论标签即可。

标签: c++ math graph


【解决方案1】:

您可以通过查看顶点之间的每个可能连接,并且只要确实存在连接,就可以将邻接矩阵转换为关联矩阵,并在关联矩阵中添加一条边。不过,请注意每个顶点组合只查看一次。

反过来,您可以简单地查看每个边缘。关联矩阵为每条边指定它连接的两个顶点。

您无法重新创建的一种情况是多条边连接相同的两个顶点。

这里有一些源代码来说明上述解释(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;
}

当您的图表很大时,可能值得考虑在adjacency_to_incidence 中运行循环两次。第一次计算边的数量,然后用足够的空间初始化矩阵,然后再次循环邻接矩阵以填充关联矩阵。

【讨论】:

    猜你喜欢
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多