提问人:JvK92 提问时间:4/27/2015 更新时间:6/20/2020 访问量:975
使用文本文件中的数据的符号导向图
Symbol Directed Graph using data from text file
问:
我被困住了,我将不胜感激。我目前正在学习算法,但我不知道从哪里开始。
我最近得到了代码(我们只真正做过理论,所以看到代码让我吓坏了)我被赋予了修改此代码的任务,以从文本文件中获取详细信息并将其放入图表中。文本文件与此类似。
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
答:
我做图表的方式是,我有一个边缘列表或数组,而不是将这些信息存储在矩阵中。我将创建一个包含两个节点的内部边缘类,因为这是一个方向图,因此两个节点必须彼此不同。您还可以使用 edge 类而不是 DistPar 类来跟踪最短路径。(或者,您可以重新调整 distPar 类的用途,以为您实现边缘功能)。
权重是赋予边的属性。我喜欢用的比喻是航线。想象一下,从纽约到洛杉矶只有一条航线,但在那架飞机上买票要花 300 美元,但是,如果你乘坐的是转机机场的航线,机票只需 150 美元。在这种情况下,您可以将每个机场视为一个节点,机场之间的路由是将节点连接在一起的边。在这种情况下,节点的“权重”就是价格。如果您想以最便宜的价格从纽约到洛杉矶,即使它经过更多的机场,您也会选择更便宜的路线。
权重基本上将任意两个节点之间最短路径的定义从连接节点的最少数量转移到这两个节点之间的最小权重。Dijkstra 的算法与您实现的算法类似,但也利用了权重,重新定义了最短路径,如上所述。
希望对您有所帮助!
评论
String[MAX_VERTS]
add_edge(numberForTrout, numberForFish, 1)