ダイクストラのアルゴリズムのファイル入力

私は、Javaで入力ファイルを読み込む方法を理解するのに問題があります。ファイルの形式は次のとおりです。

u1 v1 w1
u2 v2 w2
...
um vm wm
-1
source

各3タプルは、そのソース頂点、デスティネーション頂点、およびウェイト(例:newyork boston 30)によって指定されるエッジを示します。グラフの記述は、 "フラグ"、整数-1で終了します。このフラグの後に文字列が続きます。この文字列は、Dijkstra最短パスアルゴリズムのソース頂点の名前です。つまり、このソース頂点からグラフ内の他のすべての頂点までの最短経路を決定して出力します。 ここに私の現在の仕事があります。

import java.io.File;
import java.io.FileNotFoundException;
import java.util.PriorityQueue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

class Vertex implements Comparable {

    public final String name;
    public Edge[] adjacencies;
    public double minDistance = Double.POSITIVE_INFINITY;
    public Vertex previous;

    public Vertex(String argName) {
        name = argName;
    }

    public String toString() {
        return name;
    }

    public int compareTo(Vertex other) {
        return Double.compare(minDistance, other.minDistance);
    }

}

class Edge {
    public final Vertex target;
    public final double weight;

    public Edge(Vertex argTarget, double argWeight) {
        target = argTarget;
        weight = argWeight;
    }
}

public class Dijkstra {
    public static void computePaths(Vertex source) {
        source.minDistance = 0.;
        PriorityQueue vertexQueue = new PriorityQueue();
        vertexQueue.add(source);

        while (!vertexQueue.isEmpty()) {
            Vertex u = vertexQueue.poll();

           //Visit each edge exiting u
            for (Edge e : u.adjacencies) {
                Vertex v = e.target;
                double weight = e.weight;
                double distanceThroughU = u.minDistance + weight;
                if (distanceThroughU < v.minDistance) {
                    vertexQueue.remove(v);

                    v.minDistance = distanceThroughU;
                    v.previous = u;
                    vertexQueue.add(v);

                }

            }
        }
    }

    public static ArrayList getShortestPathTo(Vertex target) {
        ArrayList path = new ArrayList();
        for (Vertex vertex = target; vertex != null; vertex = vertex.previous)
            path.add(vertex);

        Collections.reverse(path);
        return path;
    }

    public String[] readFile(String fileName) throws FileNotFoundException {
        Scanner input = new Scanner(new File(fileName));
        String line = "";
        while (input.hasNext()) {
            line = line.concat(input.nextLine());
        }
        String[] graph = line.split("");
        return graph;

    }

    public static void main(String[] args) throws FileNotFoundException {

        final String TEST = "/TestInput.txt";
        Scanner input = new Scanner(new File(TEST));
        String line = "";
        while (input.hasNext()) {
            line = line.concat(input.nextLine());
        }
        String[] graph = line.split(" ");

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

        Vertex[] verts = new Vertex[graph.length];
        Edge[] edges = new Edge[graph.length];
        Vertex v1 = new Vertex("");
        Vertex v2 = new Vertex("");
        Vertex source = new Vertex("");
        int count = 0;

        outerloop: for (int i = 0; i < (graph.length); i++) {

            if (graph[i].equals("-1")) {
               //do algorithm initialization here w/ source
            }
            if (i == 0) {
                verts[i] = new Vertex(graph[i]);
                count++;
            } else {
                innerloop: for (int j = count; j >= 0; j--) {
                    if (i/3 == 0) {

                        if (graph[i].equals(verts[j].toString())) {
                            break innerloop;
                        } else if (j == 0) {
                            verts[count] = new Vertex(graph[i]);
                            v1 = verts[count];
                            count++;
                        }
                    }

                    if (i/3 == 1) {

                        if (graph[i].equals(verts[j])) {
                            break innerloop;
                        } else if (j == 0) {
                            verts[count] = new Vertex(graph[i]);
                            v2 = verts[count];
                            count++;
                        }
                    }
                    if (i/3 == 2) {

                    }
                }
            }

        }

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

ですから、私の唯一の問題は、与えられた.txtファイル形式からグラフを得る方法です。どんな提案も大歓迎です。

1
あなたのコードはおそらく動作するはずです。 line.split( "")の意図した目的は正確に何ですか?また、スキャナの終了後にinput.close()を呼び出すこともできます。結果は何ですか?
追加された 著者 CCJ,
ファイルをリンクしたり、短いものの完全なサンプルを提供してください。
追加された 著者 Thomas Jungblut,
私はあなたのエッジが1つの頂点しか持たないのは奇妙だと思います。
追加された 著者 user180100,
私はjavaでこれをやろうとしていると言わざるを得ない。
追加された 著者 user1065042,

2 答え

ファイル・データを解析するには、スキャナを使用します。各タプルについて、ソース頂点が作成されていない場合は作成し、そうでない場合は既存のグラフで検索して検索機能を作成します。ターゲット頂点に対しても同じ処理を行います。次に、タプル内の3番目のトークンに等しいウェイトを持つエッジを作成し、ターゲットの頂点をエッジに追加します。最後に、ソース頂点の隣接リストにエッジを追加します。

前述の検索機能では、任意の頂点からグラフの各頂点を検索することができます。再帰が必要です。

public static Vertex search(Vertex src, String name);

より簡単な解決策は、作成するすべての頂点のリストをグラフの作成とそれを検索することです。

public static Vertex search(List vertices, String name);

あなたがグラフを構築し、Dijkstraのアルゴリズムが始まる頂点の名前があれば、検索機能を使って頂点への参照を得ることができます。

Dijkstra.computePath(search(vertices, startVertexName));

以上です。次に、ファイルデータを解析する方法の例を示します。

List vertices = new ArrayList();
String src = 
    "Pittsburgh Philadelphia 323 "+
    "Pittsburgh Ohio 125 "+
    "Ohio Philadelphia 400 "+
    "-1 Ohio";
            //new Scanner(new File(fileName));
Scanner scnr = new Scanner(src); 
String src, target;
int weight;
while(scnr.hasNext())
{
    src = scnr.next();
    if(src.equals("-1"))
        break;
    else {
        target = scnr.next();
        weight = scnr.nextInt();
    }
    //call search(), implement logic in addToGraph()
    addVertexToGraph(src, target, weight, vertices);    
}   
String startVertexName = scnr.next();
scnr.close();

Scanner.next は空白で区切られた次のトークン(デフォルトの区切り文字)を返します。そのため、ファイルデータはそのようにフォーマットされている必要があります。

2
追加された
+1良い答え。
追加された 著者 user180100,

ここにショットがあります:

/**
 * Read the file using provided filename, construct vertices etc.
 * 
 * @param fileName name of the file to read.
 * @return true if everything is OK
 * @throws FileNotFoundException if file is not found or not readable
 */
public boolean readFile(final String fileName) throws FileNotFoundException {
    final Scanner input = new Scanner(new File(fileName));
    boolean result = false;

    while (input.hasNext()) {
        final String line = line = input.nextLine();
        if ("-1".equals(line)) {
           //end of data
            if (input.hasNext()) {
                final String nameOfTheSource = input.next();
               //TODO: do something with nameOfTheSource
                result = true;
            } else {
               //bad input format: there should be something after -1
            }
        } else {
            final String Scanner vert = new Scanner(line);

            try {
                final String sourceName = vert.next();
                final String targetName = vert.next();
                final int weight = vert.nextInt();//assuming int for weight
               //TODO: create Vertices and Edge here
            } catch (final NoSuchElementException ex) {
               //bad input format for "line"!
            }
        }
    }

    return result;
}

未検証。

1
追加された