java或c ++中的邻接矩阵,用于查找连接的节点

时间:2008-12-08 12:56:12

标签: java c++ graph-theory

我遇到了一个问题,我在图中给出了N个节点,这些节点彼此互连,然后给出一个矩阵,列出一个连接到另一个节点的节点(如果是,则为1,否则为0)。我想知道如何最好地解决这个问题。我认为这些是邻接矩阵?但是我该如何实现......

基本上我试图摆脱这些是找到一个特定节点是否连接到给定集合'S'中的所有其他节点。选择的项目是否是集团......

我很感激任何提示。

6 个答案:

答案 0 :(得分:7)

您可以使用二维布尔数组来实现此功能。因此,如果节点i连接到节点j,则myarray [i] [j]将为真。如果你的边缘不是方向性的话,那么myarray [j] [i]只要myarray [i] [j]就是真的。

通过使用整数(或其他数字类型)而不是布尔值作为数组的元素,这也可以扩展到加权边缘。

答案 1 :(得分:3)

最简单的方法是使用方形矩阵(2d数组),使用布尔表示是否存在连接,或使用整数来表示遍历的代价。但是,对于稀疏图形,通过使用锯齿状数组然后存储哪些节点与第一个节点相邻,可以获得更好的压缩效果。在Java中,我可能通过使用List<List<Integer>>来执行此操作,其中外部列表​​对应于相关节点,内部列表是与此节点相邻的所有节点。

假设您决定使用标准(未压缩)矩阵,您可以通过迭代列表,然后查找A [i] [j]来查明节点i是否与列表中的每个节点j相邻。如果它们中的任何一个是false,那么它与列表中的每个项都不相邻,否则它是真的。对于一个团队,您只需对列表中的每个项目执行此操作(删除i = j的情况并对无向图进行一些优化)。

一个例子(再次在Java中)

public boolean isClique(boolean[][] A, List<Integer> nodes){
  for(int i : nodes){
    for(int j : nodes){
      if(i != j){
        if(!A[i][j]) return false;
      }
    }
  }
  return true;
}

Max-Clique问题的优化和解决方案留给读者练习。

答案 2 :(得分:3)

试试这个:

public class AdjacencyMatrix {

private String [] nodes;

private int [][] matrix;

public AdjacencyMatrix(String [] nodes,int [][] matrix){
    this.nodes = nodes;
    this.matrix = matrix;
}

boolean isSymmetric(){
    boolean sym = true;
     for(int i=0;i<matrix.length;i++){
         for(int j=i+1; j < matrix[0].length ; j++){
             if (matrix[i][j] != matrix[j][i]){
                 sym = false;
                 break;
             }
         }
     }
     return sym;
}

public Graph createGraph(){
    Graph graph = new Graph();
     Node[] NODES = new Node[nodes.length];

    for (int i=0; i<nodes.length; i++){
        NODES[i] =  new Node(nodes[i]);
        graph.addNode(NODES[i]);
    }

    for(int i=0;i<matrix.length;i++){            
         for(int j=i;j<matrix[0].length;j++){
             int distance = matrix[i][j];
             if (distance != 0){                     
                 graph.addEdge(new Edge(NODES[i], NODES[j], distance));
             } 
         }
    }

    return graph;
}


public long pathLength(int[] path){
    long sum = 0;
    for (int i=0; i<path.length - 1; i++){
        if (matrix[path[i]][path[i+1]] != 0)
            sum += matrix[path[i]][path[i+1]];
        else {
            sum = 0;
            break;
        }
    }

    return sum;
}


public static void main(String[] args){
    String[] nodes = {"A", "B", "C", "D", "E"};
    int [][] matrix= {  {0, 2, 2, 1, 0}, 
                        {2, 0, 1, 0, 0}, 
                        {2, 1, 0, 0, 1}, 
                        {1, 0, 0, 0, 4}, 
                        {0, 0, 1, 4, 7}};
    AdjacencyMatrix am = new AdjacencyMatrix(nodes, matrix);
    Graph graph  = am.createGraph();
    int[] a = {0, 2, 4, 4, 3, 0};
    int[] b = {0, 1, 2, 4, 4, 3, 0};
    graph.writeGraph(); 
    am.pathLength(a);
    am.pathLength(b);
}

}

答案 3 :(得分:2)

提示:所以你有你的邻接矩阵M,告诉你两个节点是否直接相连。然后M ^ 2给你什么?它告诉您两个节点之间是否存在长度为2的路径。

我让你想象什么是M ^ 3,...,M ^ inf(当你到达固定点时)

答案 4 :(得分:1)

使用邻接矩阵,应用Floyd-Warshall algorithm将为您提供节点之间的所有路径。然后你可以检查特定的集合。

答案 5 :(得分:0)

您可能希望使用bitsetbit_vector代替bool [] []。

如果您不使用锯齿状阵列,并且您的连接是对称的,请考虑使用基于MIN()&amp ;;的访问器进行包装。 MAX()[宏]。在两个地方存储相同的数据是痛苦的一个方法。最后,array [i] [j]!= array [j] [i]。

E.g: getValue( int i, int j ) { return array [ MIN(i,j) ] [ MAX(i,j) ] }