Мне нужно дать самый широкий путь от одного выбранного узла к другому в самостоятельно сгенерированном графе. После этого мне нужно указать «узкое место» или наименьший вес на вычисляемом пути. На самом деле, я не знаю, где начать искать узкое место, и у меня возникают проблемы с указанием пути. В классе 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);
}
}