用Java实现Dijkstra算法

用Java实现Dijkstra算法,java,algorithm,dijkstra,Java,Algorithm,Dijkstra,我正在尝试制作一个程序,支持自动机(图)上的多个操作。 这就是我的数据结构的样子: public class Automaton { private ArrayList<Node> $Q; /* All the nodes */ private Node $startingNode; /* The startingNode */ private ArrayList<Connection> $delta; /* All the connections */ private

我正在尝试制作一个程序,支持自动机(图)上的多个操作。 这就是我的数据结构的样子:

public class Automaton {
private ArrayList<Node> $Q; /* All the nodes */
private Node $startingNode; /* The startingNode */
private ArrayList<Connection> $delta; /* All the connections */
private ArrayList<Node> $F; /* All the end nodes */
private ArrayList<Character> $E; 


public class Connection { 
private Node $start; 
private Node $end; 
private char $condition; }


public class Node { 
private boolean $startingNode; 
private boolean $endNode; 
private String $name; }
公共类自动机{
private ArrayList$Q;/*所有节点*/
专用节点$startingNode;/*启动节点*/
private ArrayList$delta;/*所有连接*/
private ArrayList$F;/*所有结束节点*/
私人ArrayList$E;
公共类连接{
私有节点$start;
私有节点$end;
私有字符$condition;}
公共类节点{
私有布尔$startingNode;
私有布尔$endNode;
私有字符串$name;}
其中一个操作是Dijkstra算法,这是到目前为止我的代码,问题是如果(D[v]>=(D[w]+值))它永远不会进入这个过程,因为1永远不会小于1,我在寻找一种方法,如何计算路径的长度,使其大于1。例如:从a->D是长度3,因为你从a到B,从B到C,从C到D

public String[] shortestPath() {
    boolean[] visited = new boolean[$Q.size()];
    String[] P = new String[$Q.size()];
    int[] D = new int[$Q.size()];
    char c;
    int w;
    int value = 0;
    Node source = null;
    boolean found = false;

    for (int i = 0; i < visited.length; i++) {
        if ($Q.get(i).getStartingNode()) {
            visited[i] = true;
            source = $Q.get(i);
        } else
            visited[i] = false;
    }

    for (int i = 0; i < $Q.size(); i++) {
        /* If the source and the node are not the same */
        if (!($Q.get(i).getName().equals(source.getName()))) {
            P[i] = source.getName();
            /* If there is a connection */
            c = checkConnection(source, $Q.get(i));
            if (c != '\u0000') {/* There is a connection */
                if (c == '$')/* Epsilon transition */
                    D[i] = 0;
                else
                    D[i] = 1;
            } else
                /* There isnt a connection, put it on -1 */
                D[i] = -1;
        }

    }
    for(int i = 0; i < visited.length; i++)
        System.out.println(visited[i]);

    for (int i = 1; i < $Q.size() && !found; i++) {
        w = findMinimum(D, visited);
        visited[w] = true;

        System.out.println(w);

        for (int v = 0; v < $Q.size() && !found; v++) {
            if (!(visited[v])) {
                c = checkConnection($Q.get(w), $Q.get(v));
                if (c != '\u0000') {/* There is a connection */
                    if (c == '$')/* Epsilon transition */
                        value = 0;
                    else
                        value = 1;
                    /*Check if from source to v is shorter if you go via w*/
                    if (D[v] >= (D[w] + value)) {
                        D[v] = D[w] + value;
                        P[v] = $Q.get(w).getName();

                        if ($Q.get(w).getEndNode())
                            found = true;
                    }
                }/*Connection if*/
            }
        }
    }
    return P;

}

/** Returns the minimum cost of the connections from the source
 * @param d the array with the costs from the source to the other nodes
 * @param visited an array that remembers which node is already visited
 * @return returns the index of the position with the minimum cost
 */
private int findMinimum(int[] d, boolean[] visited) {
    // TODO Auto-generated method stub
    int min = 2; /* Since the cost will be 0 of 1 we can use 2 as a higher number */
    int index = 0;

    for (int i = 0; i < d.length; i++) {
        /* If we didnt visit the node yet, so a node outside s */
        if (!(visited[i])) {
            /* If there really is a connection */
            if (d[i] != -1) {
                /* If the cost is lower than our current minimum */
                if (d[i] <= min){
                    index = i;
                    min = d[i];
                }

            }
        }
    }

    /**
 * Checks if there is a connection between 2 nodes
 * @param start the startnode of the connection
 * @param end the endnode of the connection
 * @return returns the cost of the edge between the 2 nodes, else return null
 */
private char checkConnection(Node start, Node end){
    for(int i = 0; i < $delta.size(); i++){
        /*If the start node and the end node are the same*/
        if(($delta.get(i).getStart().getName().equals(start.getName())) && $delta.get(i).getEnd().getName().equals(end.getName())){
            return $delta.get(i).getCondition();
        }
    }
    return '\u0000'; /*Empty char*/
}
    return index;
}
公共字符串[]最短路径(){
布尔值[]已访问=新布尔值[$Q.size()];
String[]P=新字符串[$Q.size()];
int[]D=新的int[$Q.size()];
字符c;
int w;
int值=0;
节点源=null;
布尔值=false;
for(int i=0;i<0.length;i++){
if($Q.get(i).getStartingNode()){
访问[我]=真实;
来源=$Q.get(i);
}否则
访问[i]=错误;
}
对于(int i=0;i<$Q.size();i++){
/*如果源和节点不相同*/
if(!($Q.get(i).getName().equals(source.getName())){
P[i]=source.getName();
/*如果有联系*/
c=检查连接(源,$Q.get(i));
如果(c!='\u0000'){/*存在连接*/
如果(c='$')/*ε转换*/
D[i]=0;
其他的
D[i]=1;
}否则
/*没有连接,请打开-1*/
D[i]=-1;
}
}
for(int i=0;i<0.length;i++)
System.out.println(已访问[i]);
对于(int i=1;i<$Q.size()&&&!found;i++){
w=findMinimum(D,访问);
访问[w]=真;
系统输出打印LN(w);
对于(int v=0;v<$Q.size()&&&!found;v++){
如果(!(访问过[v])){
c=检查连接($Q.get(w),$Q.get(v));
如果(c!='\u0000'){/*存在连接*/
如果(c='$')/*ε转换*/
数值=0;
其他的
数值=1;
/*如果通过w,检查从源到v是否较短*/
如果(D[v]>=(D[w]+值)){
D[v]=D[w]+值;
P[v]=$Q.get(w).getName();
if($Q.get(w).getEndNode())
发现=真;
}
}/*连接如果*/
}
}
}
返回P;
}
/**返回源连接的最低成本
*@param d使用从源到其他节点的成本创建阵列
*@param访问了一个数组,该数组记住了已访问的节点
*@return返回具有最小成本的位置索引
*/
私有int findminium(int[]d,布尔[]d){
//TODO自动生成的方法存根
int min=2;/*由于成本为1的0,我们可以使用2作为更高的数字*/
int指数=0;
对于(int i=0;i如果(d[i]Juset一个问题:为什么变量名以
$
开头?你应该用邻接列表或矩阵来表示你的图形(这可能只是意味着节点有它们连接的节点列表)。将所有边存储在列表中是一个缓慢算法的诀窍。