简体   繁体   English

代表节点数目未知的图?

[英]Representing a graph with an unknown number of nodes?

For the last few days I cannot think about how to represent a given graph in a text file into an adjacency matrix without knowing the number of vertices in the graph beforehand. 在最近的几天里,我无法在不事先知道图形中顶点数的情况下考虑如何将文本文件中的给定图形表示为邻接矩阵。

The input file has vertices defined as Strings and a pair of consecutive lines representing an edge between both vertices. 输入文件具有定义为“字符串”的顶点和代表两个顶点之间的边的一对连续线。 For example: 例如:

VertexA
VertexB
VertexC
VertexD

There is an edge from VertexA -> VertexB and VertexC -> VertexD in the above example. 在上面的示例中,VertexA-> VertexB和VertexC-> VertexD有优势。 Directed, weights are arbitrarily 1. 定向权重任意为1。

I would like to implement this in it's own class which doesn't parse the file directly and instead has only a method which adds a directed between a given source and destination vertex. 我想在它自己的类中实现这一点,该类不直接解析文件,而仅具有在给定源顶点和目标顶点之间添加定向的方法 For example: 例如:

// adds a directed edge from vertex1 -> vertex2
addEdgeBetweenVertices(String vertex1, String vertex2);

In this method so far I have made a HashMap and if either vertex is not in the map, add it with it's own unique index. 到目前为止,我已经使用此方法制作了一个HashMap,如果地图上未包含任何一个顶点,请添加其自己的唯一索引。 (The key being the name of the vertex and the value being its index.) (键是顶点的名称,值是其索引。)

How can I construct this adjacency matrix using such a method, while maintaining this edge information, but without knowing the number of vertices ( |V| ) prior? 我如何使用这种方法构造该邻接矩阵,同时保持该边缘信息,但又不事先知道顶点数(| V |)?

I was thinking an ArrayList of ArrayLists but I can't wrap my head around this. 我当时在想ArrayLists的ArrayList,但是我无法解决这个问题。

You can use ArrayList of ArrayList and your idea is perfect that you can map the String s with unique Integer ids and then directly add the corresponding vertex to the list. 您可以使用ArrayList of ArrayList ,您的想法很完美,您可以使用唯一的Integer ID映射String ,然后将相应的顶点直接添加到列表中。

The problem with Adjacency Matrix is that you need to know the maximum limit of the vertexes. Adjacency Matrix的问题是,您需要知道顶点的最大限制。 Adjacency Matrix is not memory efficient and also not feasible for dynamic operations. Adjacency Matrix memory efficientmemory efficient ,动态操作也不可行。 So here Adjacency List comes into the picture. 因此,这里有Adjacency List I have written a small code to demonstrate the creation of Adjacency List and also how to add new Vertex or and Edge . 我编写了一个小代码来演示邻接列表的创建以及如何添加新的Vertex或and Edge

import java.util.ArrayList;
import java.util.HashMap;

public class AdjacencyListDemo {

    static int availableId=0;                            //Represents the available id for mapping
    static HashMap<String,Integer> mapping;              //To store the String-Integer mapping for Vertexes
    static ArrayList<ArrayList<Integer>> adjacencyList;

    public static void main(String args[])
    {
        adjacencyList = new ArrayList<ArrayList<Integer>>();

        mapping  = new HashMap<String,Integer>();

        String sampleVertexes[] = {"Vertex1","Vertex2","Vertex3","Vertex4"};

        for(String vertex : sampleVertexes)
            addNewVertex(vertex);

        addEdgeBetween("Vertex1","Vertex2");
        addEdgeBetween("Vertex3","Vertex4");

        System.out.println("Old List: ");
        printList();

        //Add New Vertex if required
        addNewVertex("Vertex5");

        addEdgeBetween("Vertex5","Vertex1");
        addEdgeBetween("Vertex2","Vertex1");
        addEdgeBetween("Vertex3","Vertex2");
        addEdgeBetween("Vertex5","Vertex2");

        System.out.println("\n\nNew List: ");
        printList();

    }

    private static void printList()
    {
        for(String vertex : mapping.keySet()) {
            int index = mapping.get(vertex);
            System.out.println(vertex+" ID: "+index+" List: "+adjacencyList.get(index));
        }
    }
    private static void addEdgeBetween(String vertex1, String vertex2) {
        //get both indexes
        int index1 = mapping.get(vertex1);
        int index2 = mapping.get(vertex2);

        //add index2 into the arraylist of index1 
        adjacencyList.get(index1).add(index2);
    }

    private static void addNewVertex(String vertex) {

        if(!mapping.containsKey(vertex))
        {  
            //assign available ID
            mapping.put(vertex,availableId);
            availableId++;                                   //make increment in available id
            adjacencyList.add(new ArrayList<Integer>());     //Add an Empty ArrayList
        }
    }
}

Output : 输出:

Old List: 
Vertex2 ID: 1 List: []
Vertex3 ID: 2 List: [3]
Vertex1 ID: 0 List: [1]
Vertex4 ID: 3 List: []


New List: 
Vertex2 ID: 1 List: [0]
Vertex3 ID: 2 List: [3, 1]
Vertex1 ID: 0 List: [1]
Vertex4 ID: 3 List: []
Vertex5 ID: 4 List: [0, 1]

I would say that both the Map and the ArrayList of ArrayList s can be part or a solution. 我想说ArrayListMapArrayList可以是一部分,也可以是解决方案。 Use the Map<String,int> to obtain the unique id for each vertex string, as you already described. 正如您已经描述的,使用Map<String,int>获取每个vertex字符串的唯一id Then something like this might work (sorry just more or less Java) 然后可能会发生类似的事情(对不起,Java或多或少)

HashMap<String,Integer> map;
ArrayList< ArrayList<Boolean> > adjacency;

addEdgeBetweenVertices(String vertex1, String vertex2) {
  Integer idx1 = (map.containsValue(vertex1)) ? map.get(vertex1) : map.put(vertex1,getNextIndex());
  Integer idx2 = (map.containsValue(vertex1)) ? map.get(vertex2) : map.put(vertex2,getNextIndex());

  adjacency[idx1].set(idx2,true);
}

If you don't need to use that adjacency matrix after most of calls to addEdgeBetweenVertices , then you can add data about your edges to some array. 如果在大多数调用addEdgeBetweenVertices之后不需要使用邻接矩阵,则可以将有关边的数据添加到某个数组。 And just before you want to use it call Build (or Rebuild ) member function of your class (you will need to add this one). 在您要使用它之前,请调用类的Build (或Rebuild )成员函数(您需要添加此成员)。 Which will actually build your adjacency matrix. 这实际上将建立您的邻接矩阵。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM