Skip to content
Snippets Groups Projects
BFS.java 6.72 KiB
Newer Older
  • Learn to ignore specific revisions
  • Gianluca's avatar
    Gianluca committed
    import it.uniupo.graphLib.*;
    
    Gianluca Mastrolonardo's avatar
    Gianluca Mastrolonardo committed
    
    
    Gianluca's avatar
    Gianluca committed
    import java.awt.List;
    
    Gianluca's avatar
    Gianluca committed
    import java.util.*;
    
    Gianluca Mastrolonardo's avatar
    Gianluca Mastrolonardo committed
    
    public class BFS {
    
        private GraphInterface myGraph;
    
        public BFS(GraphInterface g) {
            //System.out.println(g);
            this.myGraph = g;
        }
    
    
    Gianluca's avatar
    Gianluca committed
        //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;
        }
        /*
    
    Gianluca Mastrolonardo's avatar
    Gianluca Mastrolonardo committed
        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);
    
    Gianluca's avatar
    Gianluca committed
                for (Integer v : neighbors) {
                    if (!s.contains(v)) {
                        s.add(v);
                        q.add(v);
                        valueToReturn.add(v);
    
    Gianluca Mastrolonardo's avatar
    Gianluca Mastrolonardo committed
                    }
                }
            }
            return valueToReturn;
        }
    
    Gianluca's avatar
    Gianluca committed
        */
    
        //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;
        }
    
    
    Gianluca's avatar
    Gianluca committed
        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());
    
    Gianluca's avatar
    Gianluca committed
    
    
    Gianluca's avatar
    Gianluca committed
            founded[sorgente] = true;
            q.add(sorgente);
    
    Gianluca's avatar
    Gianluca committed
    
    
    Gianluca's avatar
    Gianluca committed
            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);
                    }
    
    Gianluca's avatar
    Gianluca committed
                }
    
    Gianluca's avatar
    Gianluca committed
            }
            return alberoBFSdallaSorgente;
        }
    
    Gianluca's avatar
    Gianluca committed
    
    
    Gianluca's avatar
    Gianluca committed
        private void cammminoMinimoImpl(DirectedGraph bfsAlbero, int sorg, int dest, ArrayList<Integer> path) {
            //Se ho trovato il nodo
            if (sorg == dest) {
                return;
    
    Gianluca's avatar
    Gianluca committed
            }
    
    Gianluca's avatar
    Gianluca committed
    
            //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;
                }
            }
    
    
    Gianluca's avatar
    Gianluca committed
        }
    
    
    Gianluca's avatar
    Gianluca committed
    
        public ArrayList<Integer> camminoMinimo(int sorgente, int destinazione) {
    
    Gianluca's avatar
    Gianluca committed
            //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
    
    
    Gianluca's avatar
    Gianluca committed
            DirectedGraph bfsAlbero = bfsTreeDirected(sorgente);
    
    Gianluca's avatar
    Gianluca committed
            boolean[] founded = new boolean[this.myGraph.getOrder()];
            ArrayList<Integer> returnArray = new ArrayList<>();
    
    
    Gianluca's avatar
    Gianluca committed
            System.out.println(bfsAlbero);
    
            cammminoMinimoImpl(bfsAlbero, sorgente, destinazione, returnArray);
    
    
    Gianluca's avatar
    Gianluca committed
    
            return returnArray;
    
    Gianluca's avatar
    Gianluca committed
        }
    
    Gianluca Mastrolonardo's avatar
    Gianluca Mastrolonardo committed
    }