import it.uniupo.graphLib.*; import java.awt.List; import java.util.*; public class BFS { private GraphInterface myGraph; public BFS(GraphInterface g) { //System.out.println(g); this.myGraph = g; } //ES 1 //Con questa variamente utilizzi founded al posto di S. //Founded è un array di Booleani, in questo modo puoi fare accesso posizionale ed ottimizzi l'algoritmo. (La contains ha costo n) public ArrayList<Integer> getNodesInOrderOfVisit(int sorgente) { if (this.myGraph.getOrder() <= sorgente) { throw new IllegalArgumentException("Sorgente errata"); } ArrayList<Integer> returnList = new ArrayList<>(); returnList.add(sorgente); boolean[] founded = new boolean[myGraph.getOrder()]; Queue<Integer> q = new LinkedList<>(); founded[sorgente] = true; q.add(sorgente); while (!q.isEmpty()) { int u = q.remove(); Iterable<Integer> neighbors = this.myGraph.getNeighbors(u); for (int v : neighbors) { if (!founded[v]) { founded[v] = true; q.add(v); returnList.add(v); } } } return returnList; } /* public ArrayList<Integer> getNodesInOrderOfVisit(int sorgente) { if (this.myGraph.getOrder() <= sorgente) { throw new IllegalArgumentException("Dimensione della Sorgente errata"); } ArrayList<Integer> s = new ArrayList<>(); ArrayList<Integer> valueToReturn = new ArrayList<>(); s.add(sorgente); valueToReturn.add(sorgente); Queue<Integer> q = new LinkedList<>(); q.add(sorgente); while (!q.isEmpty()) { int u = q.remove(); List<Integer> neighbors = (List<Integer>) this.myGraph.getNeighbors(u); for (Integer v : neighbors) { if (!s.contains(v)) { s.add(v); q.add(v); valueToReturn.add(v); } } } return valueToReturn; } */ //ES 2 public int[] getDistance(int sorgente) { if (this.myGraph.getOrder() <= sorgente) { throw new IllegalArgumentException("Dimensione della Sorgente errata"); } boolean[] founded = new boolean[this.myGraph.getOrder()]; Queue<Integer> q = new LinkedList<>(); int[] returnArray = new int[this.myGraph.getOrder()]; Arrays.fill(returnArray, -1); founded[sorgente] = true; q.add(sorgente); returnArray[sorgente] = 0; while (!q.isEmpty()) { int u = q.remove(); Iterable<Integer> neighbors = this.myGraph.getNeighbors(u); for (Integer v : neighbors) { if (!founded[v]) { founded[v] = true; q.add(v); returnArray[v] = returnArray[u] + 1; } } } return returnArray; } //Funzioni aggiuntive che trovi qui //https://www.dir.uniupo.it/pluginfile.php/1252187/mod_resource/content/23/BFSjava.pdf public int getDistance(int sorgente, int nodo) { if (this.myGraph.getOrder() <= sorgente) { throw new IllegalArgumentException("Nodo sorgente non presente nel grafo"); } if (this.myGraph.getOrder() <= nodo) { throw new IllegalArgumentException("Nodo destinazione non presente nel grafo"); } int[] distance = getDistance(sorgente); return distance[nodo]; } public GraphInterface bfsTree(int sorgente) { if (this.myGraph.getOrder() <= sorgente) { throw new IllegalArgumentException("Dimensione della Sorgente errata"); } boolean[] founded = new boolean[this.myGraph.getOrder()]; Queue<Integer> q = new LinkedList<>(); GraphInterface alberoBFSdallaSorgente = new UndirectedGraph(this.myGraph.getOrder()); founded[sorgente] = true; q.add(sorgente); while (!q.isEmpty()) { int u = q.remove(); Iterable<Integer> neighbors = this.myGraph.getNeighbors(u); for (Integer v : neighbors) { if (!founded[v]) { founded[v] = true; q.add(v); alberoBFSdallaSorgente.addEdge(u, v); //returnArray[v] = returnArray[u] + 1; } } } return alberoBFSdallaSorgente; } private DirectedGraph bfsTreeDirected(int sorgente) { if (this.myGraph.getOrder() <= sorgente) { throw new IllegalArgumentException("Dimensione della Sorgente errata"); } boolean[] founded = new boolean[this.myGraph.getOrder()]; Queue<Integer> q = new LinkedList<>(); DirectedGraph alberoBFSdallaSorgente = new DirectedGraph(this.myGraph.getOrder()); founded[sorgente] = true; q.add(sorgente); while (!q.isEmpty()) { int u = q.remove(); Iterable<Integer> neighbors = this.myGraph.getNeighbors(u); for (Integer v : neighbors) { if (!founded[v]) { founded[v] = true; q.add(v); alberoBFSdallaSorgente.addEdge(u, v); } } } return alberoBFSdallaSorgente; } private void cammminoMinimoImpl(DirectedGraph bfsAlbero, int sorg, int dest, ArrayList<Integer> path) { //Se ho trovato il nodo if (sorg == dest) { return; } //Se sono nella foglia sbagliata if (((Collection<?>) bfsAlbero.getNeighbors(sorg)).isEmpty()) { //Pulisco il percorso corrente perché errato path.clear(); } //Allora devo ancora esplorare for (Integer node : bfsAlbero.getNeighbors(sorg)) { path.add(node); //System.out.println(">>> Nodo: " + node); cammminoMinimoImpl(bfsAlbero, node, dest, path); if (node == dest) { break; } } } public ArrayList<Integer> camminoMinimo(int sorgente, int destinazione) { //L'idea è quella di usare il BFS Albero, perché aciclico, ed in questo modo trovare il percorso. //Proviamo con la ricorsione //Implementazione sbagliata, ma l'idea credo sia giusta DirectedGraph bfsAlbero = bfsTreeDirected(sorgente); boolean[] founded = new boolean[this.myGraph.getOrder()]; ArrayList<Integer> returnArray = new ArrayList<>(); System.out.println(bfsAlbero); cammminoMinimoImpl(bfsAlbero, sorgente, destinazione, returnArray); return returnArray; } }