问题
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