Попытка найти наименьший вес самого широкого пути графа, используя модифицированный алгоритм Дейкстры в Java - PullRequest
0 голосов
/ 04 мая 2020

Мне нужно дать самый широкий путь от одного выбранного узла к другому в самостоятельно сгенерированном графе. После этого мне нужно указать «узкое место» или наименьший вес на вычисляемом пути. На самом деле, я не знаю, где начать искать узкое место, и у меня возникают проблемы с указанием пути. В классе Graph, в методе printPath, я в настоящее время получаю ошибку StackOverflow от предположительно бесконечной рекурсии, хотя я не понимаю, как она повторяется бесконечно во-первых. Я использовал здесь некоторый код: https://www.geeksforgeeks.org/printing-paths-dijkstras-shortest-path-algorithm/ с небольшими изменениями, чтобы найти самый большой путь, а не самый короткий, а также переименование переменных. Я чувствую, что ошибка в указанной модификации, скорее всего, является одним из источников проблемы. Ниже приведены результаты моего последнего теста:

Enter a positive integer.
5
Node list: {1,2,3,4,5}
Edge list: {(2,3,17),(2,4,8),(3,5,3)}
Enter a source node.
1
Enter a destination node
5
Vertex: 1 --> 5
Distance: 20
Path: Exception in thread "main" java.lang.StackOverflowError
    at Graph.printPath(Graph.java:104)
    at Graph.printPath(Graph.java:104)
    at Graph.printPath(Graph.java:104)

Вот мой код. У меня был код в отдельных классах, поэтому я прошу прощения за любые ошибки, которые я, возможно, сделал, объединяя их в один файл. Я также извиняюсь за большой и грязный блок кода, но я не думаю, что здесь есть что-то, что я мог бы отсеять перед публикацией.

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Random;

public class Graph{

    private ArrayList<Node> nodes = new ArrayList<Node>();
    private ArrayList<Edge> edges = new ArrayList<Edge>();
    private int[][] adjMatrix; 

    Graph(int numNodes, int weightBound, double probability){
        ArrayList<Node> tempNodeList = new ArrayList<Node>(numNodes);
        for(int i = 0; i < numNodes; i++) {
            Node tempNode = new Node(i+1);
            tempNodeList.add(tempNode);
        }
        this.nodes = tempNodeList;
        Random rand = new Random();
        for(int i = 0; i < numNodes; i++) {
            for(int j = i+1; j < numNodes; j++) {
                if(rand.nextInt((int)Math.round(1/probability)) == 0) {
                    Edge tempEdge = new Edge(rand.nextInt(5*numNodes-1)+1, nodes.get(i), nodes.get(j));
                    edges.add(tempEdge);
                }
            }
        }

        adjMatrix = new int[numNodes][numNodes];
        for(int i = 0; i < edges.size(); i++) {
            adjMatrix[edges.get(i).getNode(0).getID()-1][edges.get(i).getNode(1).getID()-1] = edges.get(i).getWeight();
            adjMatrix[edges.get(i).getNode(1).getID()-1][edges.get(i).getNode(0).getID()-1] = edges.get(i).getWeight();
        }

    }

    public void printGraph() {
        System.out.print("Node list: {");
        for(int i = 0; i < nodes.size(); i++) {
            nodes.get(i).printNode();
            if(i != nodes.size()-1) {
                System.out.print(",");
            }
        }
        System.out.println("}");
        System.out.print("Edge list: {");
        for(int i = 0; i < edges.size(); i++) {
            edges.get(i).printEdge();
            if(i != edges.size()-1) {
                System.out.print(",");
            }
        }
        System.out.println("}");
    }

    public void widestPath(int source, int dest){

        int numVertices = adjMatrix[0].length;
        int[] longestDists = new int[numVertices];
        boolean[] inPath = new boolean[numVertices];
        for(int i = 0; i < numVertices; i++) {
            inPath[i] = false;
        }
        longestDists[source] = 0;
        Node tempNode = nodes.get(source);
        tempNode.setParent(-1);
        nodes.set(source, tempNode);
        for(int i = 1; i < numVertices; i++) {
            int furthestNode = -1;
            int longestDist = Integer.MIN_VALUE;
            for(int index = 0; index < numVertices; index++) {
                if(!inPath[index] && longestDists[index] > longestDist) {
                    furthestNode = index;
                    longestDist = longestDists[index];
                }
            }

            inPath[furthestNode] = true;
            for(int index = 0; index < numVertices; index++) {
                int edgeWeight = adjMatrix[furthestNode][index];
                if(edgeWeight > 0 && ((longestDist + edgeWeight) > (longestDists[index]))){
                    tempNode = nodes.get(index);
                    tempNode.setParent(furthestNode);
                    nodes.set(index, tempNode);
                    longestDists[index] = longestDist + edgeWeight;
                }
            }
        }


        printResult(source, longestDists, dest);

    }

    public void printResult(int source, int[] dists, int dest) {
        System.out.println("Vertex: " + (source+1) + " --> " + (dest+1));
        System.out.println("Distance: " + dists[dest]);
        System.out.print("Path: ");
        printPath(dest);
    }

    public void printPath(int dest) {
        if(nodes.get(dest).getParent() == -1) {
            return;
        }
        printPath(nodes.get(dest).getParent()); // StackOverflow here
        System.out.print((dest+1) + " ");
    }



}


public class Node {

    private int ID;
    private int distance = Integer.MIN_VALUE;
    private int parent;


    Node(int id){
        this.ID = id;
    }

    public int getID() {
        return this.ID;
    }

    public void printNode() {
        System.out.print(this.ID);
    }

    public void setDist(int dist) {
        this.distance = dist;
    }

    public int getDist() {
        return this.distance;
    }

    public void setParent(int p) {
        this.parent = p;
    }

    public int getParent() {
        return this.parent;
    }




}


public class Edge {

    private int weight;
    private ArrayList<Node> vertices = new ArrayList<Node>(2);

    Edge(int weight){
        this.weight = weight;
    }

    Edge(int weight, Node n1, Node n2){
        this.weight = weight;
        this.vertices.add(n1);
        this.vertices.add(n2);
    }

    public int getWeight() {
        return weight;
    }

    public void setNodes(Node n1, Node n2) {
        this.vertices.set(0, n1);
        this.vertices.set(1, n2);
    }

    public ArrayList<Node> getNodes(){
        return vertices;
    }

    public void printEdge() {
        System.out.print("(" + vertices.get(0).getID() + "," + vertices.get(1).getID() + "," + this.weight + ")");
    }

    public int otherNodeIndex(int ID) {
        if(vertices.get(0).getID() == ID) {
            return 1;
        }else if(vertices.get(1).getID() == ID) {
            return 0;
        } else {
            return -1;
        }
    }

    public Node getNode(int index) {
        return vertices.get(index);
    }


}

public class Driver {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int input = -1;
        while(input <= 0) {
            System.out.println("Enter a positive integer.");
            input = sc.nextInt();
        }

        double probability = 0.25;
        Graph gr = new Graph(input, input*5, probability);

        gr.printGraph();
        int source = -1;
        int dest = -1;
        while(source < 0 || source > input) {
            System.out.println("Enter a source node.");
            source = sc.nextInt()-1;
        }
        while(dest < 0 || dest > input) {
            System.out.println("Enter a destination node");
            dest = sc.nextInt()-1;
        }

        gr.widestPath(source, dest);

    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...