【问题标题】:File input for Dijkstra's algorithmDijkstra 算法的文件输入
【发布时间】:2012-01-06 02:37:54
【问题描述】:

我无法弄清楚如何使用 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<Vertex> {

    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<Vertex> vertexQueue = new PriorityQueue<Vertex>();
        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<Vertex> getShortestPathTo(Vertex target) {
        ArrayList<Vertex> path = new ArrayList<Vertex>();
        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 文件格式转换为图形。欢迎提出任何建议。

【问题讨论】:

  • 我应该提到我正在尝试在 java 中执行此操作。
  • 能否请您链接该文件或提供一个简短但完整的示例?
  • 您的代码看起来应该可以工作; line.split("") 的目的到底是什么?此外,您可能希望在完成扫描仪后调用 input.close()。你现在得到了什么结果?
  • 我觉得奇怪的是你的边只有一个顶点。

标签: java file input graph-theory dijkstra


【解决方案1】:

使用Scanner 解析文件数据。对于每个元组,如果源顶点尚未创建,则创建它,否则在预先存在的图中找到它——创建一个搜索函数。对目标顶点执行相同的操作。接下来,创建一个权重等于元组中第三个标记的边,并将目标顶点添加到边上。最后,将边添加到源顶点的邻接表中。

对于前面提到的搜索功能,您可以实现一些可以从任何顶点开始搜索图的每个顶点的东西。递归将是必要的。

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

一个更简单的解决方案是保留您在构建图形时创建的所有顶点的列表并通过它进行搜索。

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

当您构建完图形并获得 Dijkstra 算法将开始的顶点名称后,您可以使用搜索功能来获取对顶点的引用。

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

而且,就是这样。以下是如何解析文件数据的示例:

List<Vertex> vertices = new ArrayList<Vertex>();
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】:

    这是一个镜头:

    /**
     * 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;
    }
    

    未测试。

    【讨论】:

    【解决方案3】:

    {import Stack.Dijkstra; {import java.io.File; {import java.io.FileNotFoundException; {import java.util.Scanner;

    {public class App { {public static void main(String[] args) 抛出 {FileNotFoundException { {Vertex v1 = new Vertex("A"); {Vertex v2 = new Vertex("B"); {Vertex v3 = new Vertex("C");

        {`v1.addNeighbour(new Edge(1, v1, v2));
        {`v1.addNeighbour(new Edge(10, v1, v2));
        {`v2.addNeighbour(new Edge(1, v2, v3));
    
        {`Dijkstra dijkstra = new Dijkstra();
        {`dijkstra.computePath(v1);
    
        {`System.out.println(dijkstra.getShortestPathTo(v3));
        {`final String test = "X:\\neon3\\eclipse\\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]);
        }
    }
    

    }`}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-13
      • 2011-06-27
      相关资源
      最近更新 更多