使用文本文件中的数据的符号导向图

Symbol Directed Graph using data from text file

提问人:JvK92 提问时间:4/27/2015 更新时间:6/20/2020 访问量:975

问:

我被困住了,我将不胜感激。我目前正在学习算法,但我不知道从哪里开始。

我最近得到了代码(我们只真正做过理论,所以看到代码让我吓坏了)我被赋予了修改此代码的任务,以从文本文件中获取详细信息并将其放入图表中。文本文件与此类似。

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
Java 算法 std 有向图

评论

1赞 Edward Doolittle 4/27/2015
只有“是”关系才会在图中生成边,不是吗?另一方面,节点应包含“has a”项。像这样:鳟鱼 --是一种->鱼(有鳍,有鳍) --是一种>动物--是>食物。但是,必须注意最后两项。Fish is an Animal 和 Fish is Food 实际上看起来像是多重继承,考虑到您使用的是 Java,这有点讽刺意味。
0赞 JvK92 4/27/2015
我已经了解了图形的外观,我只是不知道如何将其转换为 java,如果这有意义?
0赞 Edward Doolittle 4/27/2015
忽略“has a”行,直到“is a”关系正常工作。您需要一个数据结构来将数字映射到名称,反之亦然(最原始的例子:use type )。然后,每当您看到“isa”行时,例如“Trout is a Fish”,请检查 Trout 和 Fish 是否有相应的数字,如果没有将它们相加,则 .据我所知,边缘权重都应该是 1。String[MAX_VERTS]add_edge(numberForTrout, numberForFish, 1)
1赞 sbeliakov 4/19/2016
我随时准备帮助你,但是这个问题似乎不是笼统的,除了你之外,可以帮助其他人。所以我的问题是:你还需要帮助吗?如果是这样,我会添加一个答案,否则如果没有人需要,我宁愿不浪费时间。

答:

0赞 FatherOfGold 6/20/2020 #1

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

权重是赋予边的属性。我喜欢用的比喻是航线。想象一下,从纽约到洛杉矶只有一条航线,但在那架飞机上买票要花 300 美元,但是,如果你乘坐的是转机机场的航线,机票只需 150 美元。在这种情况下,您可以将每个机场视为一个节点,机场之间的路由是将节点连接在一起的边。在这种情况下,节点的“权重”就是价格。如果您想以最便宜的价格从纽约到洛杉矶,即使它经过更多的机场,您也会选择更便宜的路线。

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

希望对您有所帮助!