符号定向图使用来自文本文件的数据

时间:2015-04-27 05:10:51

标签: java algorithm std directed-graph

我很困惑,我非常感谢一些帮助。我目前正在学习算法,但我不知道从哪里开始。

我最近获得了代码(我们只是真的完成了理论,因此看到代码让我害怕我的核心)我已经被赋予了修改此代码的任务,以便从文本文件中获取详细信息并将其放入图形中。文本文件与此类似。

Trout is-a fish
Fish has gills
Fish has fins
Fish is food
Fish is-an animal

那里还有更多。我只是想知道。我怎么开始这整件事?我有一百万个问题要问,但是如果我知道如何使用文本文件分配顶点,我觉得我可以解决这些问题?我提供的代码和必须编辑的代码如下。任何帮助都会很棒,如果你愿意,只需向正确的方向努力。

(另外,在addEdge类中,重要的是什么?我知道它是"成本"遍历边缘,但我该如何分配权重?)

谢谢!

public class Graph {
    private final int MAX_VERTS = 20;
    private final int INFINITY = 1000000;
    private Vertex vertexList[]; // list of vertices
    private int adjMat[][]; // adjacency matrix
    private int nVerts; // current number of vertices
    private int nTree; // number of verts in tree
    private DistPar sPath[]; // array for shortest-path data
    private int currentVert; // current vertex
    private int startToCurrent; // distance to currentVert
// -------------------------------------------------------------
    public Graph() // constructor
    {
    vertexList = new Vertex[MAX_VERTS];
    // adjacency matrix
    adjMat = new int[MAX_VERTS][MAX_VERTS];
    nVerts = 0;
    nTree = 0;
    for(int j=0; j<MAX_VERTS; j++) // set adjacency
        for(int k=0; k<MAX_VERTS; k++) // matrix
            adjMat[j][k] = INFINITY; // to infinity
    sPath = new DistPar[MAX_VERTS]; // shortest paths
    } // end constructor
// -------------------------------------------------------------
    public void addVertex(char lab)
    {
    vertexList[nVerts++] = new Vertex(lab);
    }
// -------------------------------------------------------------
    public void addEdge(int start, int end, int weight)
    {
    adjMat[start][end] = weight; // (directed)
    }
// -------------------------------------------------------------
    public void path() // find all shortest paths
    {
    int startTree = 0; // start at vertex 0
    vertexList[startTree].isInTree = true;
    nTree = 1; // put it in tree
    // transfer row of distances from adjMat to sPath
    for(int j=0; j<nVerts; j++)
    {
        int tempDist = adjMat[startTree][j];
        sPath[j] = new DistPar(startTree, tempDist);
    }
    // until all vertices are in the tree
    while(nTree < nVerts)
    {
        int indexMin = getMin(); // get minimum from sPath
        int minDist = sPath[indexMin].distance;
        if(minDist == INFINITY) // if all infinite
        { // or in tree,
            System.out.println("There are unreachable vertices");
            break; // sPath is complete
        }
        else
        { // reset currentVert
            currentVert = indexMin; // to closest vert
            startToCurrent = sPath[indexMin].distance;
            // minimum distance from startTree is
            // to currentVert, and is startToCurrent
        }
        // put current vertex in tree
        vertexList[currentVert].isInTree = true;
        nTree++;
        adjust_sPath(); // update sPath[] array
   } // end while(nTree<nVerts)
    displayPaths(); // display sPath[] contents
    nTree = 0; // clear tree
    for(int j=0; j<nVerts; j++)
        vertexList[j].isInTree = false;
    } // end path()
// -------------------------------------------------------------
    public int getMin() // get entry from sPath
    { // with minimum distance
    int minDist = INFINITY; // assume minimum
    int indexMin = 0;
    for(int j=1; j<nVerts; j++) // for each vertex,
    { // if it’s in tree and
        if( !vertexList[j].isInTree && // smaller than old one
            sPath[j].distance < minDist )
        {
            minDist = sPath[j].distance;
            indexMin = j; // update minimum
        }
    } // end for
    return indexMin; // return index of minimum
    } // end getMin()
// -------------------------------------------------------------
    public void adjust_sPath()
    {
    // adjust values in shortest-path array sPath
    int column = 1; // skip starting vertex
    while(column < nVerts) // go across columns
    {
    // if this column’s vertex already in tree, skip it
    if( vertexList[column].isInTree )
    {
        column++;
        continue;
    }
    // calculate distance for one sPath entry
    // get edge from currentVert to column
    int currentToFringe = adjMat[currentVert][column];
    // add distance from start
    int startToFringe = startToCurrent + currentToFringe;
    // get distance of current sPath entry
    int sPathDist = sPath[column].distance;
    // compare distance from start with sPath entry
    if(startToFringe < sPathDist) // if shorter,
    { // update sPath
        sPath[column].parentVert = currentVert;
        sPath[column].distance = startToFringe;
    }
    column++;
    } // end while(column < nVerts)
    } // end adjust_sPath()
// -------------------------------------------------------------
    public void displayPaths()
    {
        for(int j=0; j<nVerts; j++) // display contents of sPath[]
    {
        System.out.print(vertexList[j].label + "="); // B=
        if(sPath[j].distance == INFINITY)
            System.out.print("inf"); // inf
        else
            System.out.print(sPath[j].distance); // 50
        char parent = vertexList[ sPath[j].parentVert ].label;
        System.out.print("(" + parent + ") "); // (A)
    }
        System.out.println("");
    }
// -------------------------------------------------------------
} // end class Graph

1 个答案:

答案 0 :(得分:0)

我做图形的方法是我有一个边列表或一个边数组,而不是将信息存储在矩阵中。我将创建一个包含两个节点的内部边缘类,因为这是一个有向图,因此两个节点必须彼此不同。您也可以使用edge类而不是DistPar类来跟踪最短路径。 (或者,您可以重新利用distPar类来为您实现边缘功能)。

权重是赋予边缘的属性。我想用的比喻是航空公司的航线。想象一下,有一条从纽约到洛杉矶的航空公司航线,但在那架飞机上获得机票要花费300美元,但是,如果您乘坐一条路线经过连接的机场,则机票只需花费150美元。在这种情况下,您可以将每个机场视为一个节点,并且机场之间的路线是将节点连接在一起的边。在这种情况下,节点的“权重”就是价格。如果您希望以尽可能便宜的价格从纽约到达洛杉矶,那么即使经过更多机场,您也可以选择更便宜的路线。

权重基本上将任何两个节点之间的最短路径的定义从连接节点的最少数量转移到这两个节点之间的最小权重。 Dijkstra的算法与您已实现的算法相似,但也利用了权重,如上文所述重新定义了最短路径。

我希望这会有所帮助!