diff --git a/Algoritmi_2/Laboratorio/Lab5/Test/TestLab.java b/Algoritmi_2/Laboratorio/Lab5/Test/TestLab.java index a058fc4382598a4587d595d14d82cd1aefa4ce29..7aaaf0da20eb20f1144c0c434af41ea1e9ee0088 100644 --- a/Algoritmi_2/Laboratorio/Lab5/Test/TestLab.java +++ b/Algoritmi_2/Laboratorio/Lab5/Test/TestLab.java @@ -72,11 +72,14 @@ class TestLab { DFS dfsTest = new DFS(dag); Assertions.assertTrue(dfsTest.topologicalOrderDag().indexOf(0) < dfsTest.topologicalOrder().indexOf(3)); + System.out.println(dfsTest.hasDirCycle()); + DirectedGraph cyclicGraph = new DirectedGraph("3; 0 1; 1 2; 2 0"); DFS dfsCyclicTest = new DFS(cyclicGraph); + System.out.println(dfsCyclicTest.hasDirCycle()); Assertions.assertThrows(IllegalArgumentException.class, () -> dfsCyclicTest.topologicalOrderDag()); - //Da sistemare, bisogna usare ordine fine visita invece che array di padri (per grafi orientati) + // Ora funziona anche con questo grafo DirectedGraph cyclicGraph2 = new DirectedGraph("2; 0 1; 1 0;"); DFS dfsCyclicTest2 = new DFS(cyclicGraph2); Assertions.assertThrows(IllegalArgumentException.class, () -> dfsCyclicTest2.topologicalOrderDag()); diff --git a/Algoritmi_2/Laboratorio/Lab5/src/DFS.java b/Algoritmi_2/Laboratorio/Lab5/src/DFS.java index a5a2aa78474ace6e9079beb354b290c07ae90f63..4dd95fc4e1f894dc3af9e4546b02e6eb17d1c6ab 100644 --- a/Algoritmi_2/Laboratorio/Lab5/src/DFS.java +++ b/Algoritmi_2/Laboratorio/Lab5/src/DFS.java @@ -12,7 +12,7 @@ class DFS { private GraphInterface myGraph; private boolean[] founded; private GraphInterface treeDFS; - private int[] fathers; + private ArrayList<Integer> terminated = new ArrayList<>(); private ArrayList<Integer> postVisitOrder = new ArrayList<>(); @@ -66,16 +66,16 @@ class DFS { private boolean hasDirCycleImpl(int sorg) { founded[sorg] = true; - for (Integer node : myGraph.getNeighbors(sorg)) { - if (!founded[node]) { - fathers[node] = sorg; - if (hasDirCycleImpl(node)) { - return true; + for (int neighbour : myGraph.getNeighbors(sorg)) { + if (!founded[neighbour]) { + if (hasDirCycleImpl(neighbour)) { // Check the result of the recursive call + return true; // If a cycle is detected in the recursive call, propagate it up } - } else if (fathers[sorg] != -1 && node != fathers[sorg]) { + } else if (!terminated.contains(neighbour)) { return true; } } + terminated.add(sorg); return false; } @@ -85,9 +85,7 @@ class DFS { throw new IllegalArgumentException("Impossibile usare hasDirCycle su un grafo non orientato"); } for (int i = 0; i < myGraph.getOrder(); i++) { - fathers = new int[myGraph.getOrder()]; - Arrays.fill(fathers, -1); - founded = new boolean[myGraph.getOrder()]; + terminated.clear(); Arrays.fill(founded, false); if (hasDirCycleImpl(i)) { return true; diff --git a/Algoritmi_2/Laboratorio/Lab6/.idea/workspace.xml b/Algoritmi_2/Laboratorio/Lab6/.idea/workspace.xml index d9a916e03dc6c3df822b73b9a2b9d3fbf3302fdf..4ea9dbc4a764e9041161f159440a3f762bdda554 100644 --- a/Algoritmi_2/Laboratorio/Lab6/.idea/workspace.xml +++ b/Algoritmi_2/Laboratorio/Lab6/.idea/workspace.xml @@ -5,12 +5,11 @@ </component> <component name="ChangeListManager"> <list default="true" id="47e80429-8a37-4045-98c6-d9f72531884e" name="Changes" comment=""> - <change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" /> - <change afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" /> - <change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" /> - <change afterPath="$PROJECT_DIR$/Test/TestVoli.java" afterDir="false" /> - <change afterPath="$PROJECT_DIR$/src/Voli.java" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/../Lab5/Test/TestLab.java" beforeDir="false" afterPath="$PROJECT_DIR$/../Lab5/Test/TestLab.java" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/Test/TestVoli.java" beforeDir="false" afterPath="$PROJECT_DIR$/Test/TestVoli.java" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/src/Voli.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Voli.java" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/../../Teoria/Grafi_Introduzione.pdf" beforeDir="false" afterPath="$PROJECT_DIR$/../../Teoria/Grafi_Introduzione.pdf" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/../../Teoria/Grafi_Introduzione.xopp" beforeDir="false" afterPath="$PROJECT_DIR$/../../Teoria/Grafi_Introduzione.xopp" afterDir="false" /> </list> <option name="SHOW_DIALOG" value="false" /> <option name="HIGHLIGHT_CONFLICTS" value="true" /> @@ -45,13 +44,21 @@ "keyToString": { "ASKED_ADD_EXTERNAL_FILES": "true", "Downloaded.Files.Path.Enabled": "false", + "JUnit.TestVoli.daEliminare.executor": "Run", + "JUnit.TestVoli.executor": "Run", + "JUnit.TestVoli.merda.executor": "Run", + "JUnit.TestVoli.testElencoScaliMinimo.executor": "Run", + "JUnit.TestVoli.testPercorsoTempoMinimo.executor": "Run", + "JUnit.TestVoli.testScali.executor": "Run", + "JUnit.TestVoli.testTempoMinimo.executor": "Run", "Repository.Attach.Annotations": "false", "Repository.Attach.JavaDocs": "false", "Repository.Attach.Sources": "false", "RunOnceActivity.OpenProjectViewOnStart": "true", "RunOnceActivity.ShowReadmeOnStart": "true", "git-widget-placeholder": "main", - "last_opened_file_path": "/home/20050114/Documents/appunti/Algoritmi_2/Laboratorio/Lab6/Test", + "kotlin-language-version-configured": "true", + "last_opened_file_path": "/home/gianluca/Documents/appunti/Algoritmi_2/Laboratorio/Lab6", "project.structure.last.edited": "Modules", "project.structure.proportion": "0.0", "project.structure.side.proportion": "0.2", @@ -73,21 +80,41 @@ <option name="Make" enabled="true" /> </method> </configuration> - <configuration name="TestVoli.testScali" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true"> + <configuration name="TestVoli.daEliminare" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true"> <module name="Lab6" /> <option name="PACKAGE_NAME" value="" /> <option name="MAIN_CLASS_NAME" value="TestVoli" /> - <option name="METHOD_NAME" value="testScali" /> + <option name="METHOD_NAME" value="daEliminare" /> <option name="TEST_OBJECT" value="method" /> <method v="2"> <option name="Make" enabled="true" /> </method> </configuration> - <configuration name="TestVoli.testTempo" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true"> + <configuration name="TestVoli.merda" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true"> <module name="Lab6" /> <option name="PACKAGE_NAME" value="" /> <option name="MAIN_CLASS_NAME" value="TestVoli" /> - <option name="METHOD_NAME" value="testTempo" /> + <option name="METHOD_NAME" value="merda" /> + <option name="TEST_OBJECT" value="method" /> + <method v="2"> + <option name="Make" enabled="true" /> + </method> + </configuration> + <configuration name="TestVoli.testElencoScaliMinimo" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true"> + <module name="Lab6" /> + <option name="PACKAGE_NAME" value="" /> + <option name="MAIN_CLASS_NAME" value="TestVoli" /> + <option name="METHOD_NAME" value="testElencoScaliMinimo" /> + <option name="TEST_OBJECT" value="method" /> + <method v="2"> + <option name="Make" enabled="true" /> + </method> + </configuration> + <configuration name="TestVoli.testPercorsoTempoMinimo" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true"> + <module name="Lab6" /> + <option name="PACKAGE_NAME" value="" /> + <option name="MAIN_CLASS_NAME" value="TestVoli" /> + <option name="METHOD_NAME" value="testPercorsoTempoMinimo" /> <option name="TEST_OBJECT" value="method" /> <method v="2"> <option name="Make" enabled="true" /> @@ -96,8 +123,10 @@ <recent_temporary> <list> <item itemvalue="JUnit.TestVoli" /> - <item itemvalue="JUnit.TestVoli.testTempo" /> - <item itemvalue="JUnit.TestVoli.testScali" /> + <item itemvalue="JUnit.TestVoli.testElencoScaliMinimo" /> + <item itemvalue="JUnit.TestVoli.merda" /> + <item itemvalue="JUnit.TestVoli.testPercorsoTempoMinimo" /> + <item itemvalue="JUnit.TestVoli.daEliminare" /> </list> </recent_temporary> </component> diff --git a/Algoritmi_2/Laboratorio/Lab6/Test/TestVoli.java b/Algoritmi_2/Laboratorio/Lab6/Test/TestVoli.java index 6ec5f6110f1b1998b718695c45dedfc5756be6bd..90abae66aae78efc6937dcb269b62b93f39345c1 100644 --- a/Algoritmi_2/Laboratorio/Lab6/Test/TestVoli.java +++ b/Algoritmi_2/Laboratorio/Lab6/Test/TestVoli.java @@ -1,7 +1,10 @@ import it.uniupo.graphLib.DirectedGraph; +import it.uniupo.graphLib.Edge; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.ArrayList; + import static org.junit.jupiter.api.Assertions.assertEquals; public class TestVoli { @@ -49,6 +52,8 @@ public class TestVoli { scali = testVoli.scali(0, 2); assertEquals(-1, scali); + testVoli = new Voli(new DirectedGraph("5;0 1 1;1 2 1;2 3 1;0 4 15;4 3 2")); + assertEquals(1, testVoli.scali(0, 3)); } @Test @@ -83,7 +88,6 @@ public class TestVoli { }); } -/* @Test public void testPercorsoTempoMinimo() { DirectedGraph graph = new DirectedGraph("3;0 1 3;0 2 6;1 2 1"); @@ -96,16 +100,15 @@ public class TestVoli { graph = new DirectedGraph("3;0 1 3"); testVoli = new Voli(graph); percTempMin = testVoli.trattaVeloce(0, 2); - assertTrue(percTempMin == null); + Assertions.assertNull(percTempMin); percTempMin = testVoli.trattaVeloce(0, 1); assertEquals(1, percTempMin.size()); - assertEquals(percTempMin.get(0), new Edge(0, 1)); - + assertEquals(percTempMin.getFirst(), new Edge(0, 1)); } - + @Test - public void testPercorsoScaliMinimo() { + public void testElencoScaliMinimo() { DirectedGraph graph = new DirectedGraph("3;0 1 3;0 2 6;1 2 1"); Voli testVoli = new Voli(graph); ArrayList<Integer> percScaliMin = testVoli.elencoScali(0, 2); @@ -114,7 +117,7 @@ public class TestVoli { graph = new DirectedGraph("3;0 1 3"); testVoli = new Voli(graph); percScaliMin = testVoli.elencoScali(0, 2); - assertTrue(percScaliMin == null); + Assertions.assertNull(percScaliMin); graph = new DirectedGraph("1"); testVoli = new Voli(graph); @@ -125,7 +128,7 @@ public class TestVoli { testVoli = new Voli(graph); percScaliMin = testVoli.elencoScali(2, 0); assertEquals(1, percScaliMin.size()); - assertEquals(1, percScaliMin.get(0).intValue()); + assertEquals(1, percScaliMin.getFirst().intValue()); } -*/ + } \ No newline at end of file diff --git a/Algoritmi_2/Laboratorio/Lab6/src/Voli.java b/Algoritmi_2/Laboratorio/Lab6/src/Voli.java index 388254b4a9467377f4f4b3c4edef5a902c183ebd..0d8483de78eca6fa593bb9120230fbbaa9f875c1 100644 --- a/Algoritmi_2/Laboratorio/Lab6/src/Voli.java +++ b/Algoritmi_2/Laboratorio/Lab6/src/Voli.java @@ -3,6 +3,7 @@ import it.uniupo.graphLib.DirectedGraph; import it.uniupo.graphLib.Edge; import it.uniupo.graphLib.GraphInterface; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; @@ -45,6 +46,41 @@ public class Voli { return distance; } + private boolean dijkstraTrattaVeloce(int sorg, int dest, ArrayList<Edge> returnArray) { + int[] distance = new int[myCollegamenti.getOrder()]; + //ArrayList<Edge> returnArray = new ArrayList<>(); + Arrays.fill(distance, -1); + + founded[sorg] = true; + distance[sorg] = 0; + MinHeap<Edge, Integer> heap = new MinHeap<Edge, Integer>(); + + for (Edge e : myCollegamenti.getOutEdges(sorg)) { + heap.add(e, distance[sorg] + e.getWeight()); + } + + while (!heap.isEmpty()) { + Edge heapReturnedEdge = heap.extractMin(); //arco (u,w), u alla prima iterazione è uguale a sorg + int nodeU = heapReturnedEdge.getTail(); + int nodeW = heapReturnedEdge.getHead(); + if (!returnArray.isEmpty() && nodeU == returnArray.getLast().getTail()) { + returnArray.removeLast(); + } + if (!founded[nodeW]) { + returnArray.add(heapReturnedEdge); + if (nodeW == dest) { + return true; + } + founded[nodeW] = true; + distance[nodeW] = distance[nodeU] + heapReturnedEdge.getWeight(); + for (Edge e : myCollegamenti.getOutEdges(nodeW)) { + heap.add(e, distance[nodeW] + e.getWeight()); + } + } + } + return false; + } + private int[] bfs(int sorg) { if (sorg >= this.myCollegamenti.getOrder()) { throw new IllegalArgumentException("Sorgente errata"); @@ -92,31 +128,77 @@ public class Voli { return bfsDistanceWeigth; } - public int tempoMinimo(int partenza, int destinazione) { - if (partenza >= myCollegamenti.getOrder() || destinazione >= myCollegamenti.getOrder() || partenza <= -1 || destinazione <= -1) { - throw new IllegalArgumentException("Aereoporto di partenza o di destinazione non esite"); + private ArrayList<Integer> bfsMinScali(int sorg, int dest) { + if (sorg >= this.myCollegamenti.getOrder()) { + throw new IllegalArgumentException("Sorgente errata"); } + ArrayList<Integer> returnArray = new ArrayList<>(); + founded[sorg] = true; + Queue<Integer> q = new LinkedList<>(); + q.add(sorg); + while (!q.isEmpty()) { + int u = q.remove(); + if (u != sorg) { + returnArray.add(u); + } + boolean noNewNodes = true; + for (int v : myCollegamenti.getNeighbors(u)) { + if (!founded[v]) { + founded[v] = true; + noNewNodes = false; + q.add(v); + //returnArray.add(v); + } + if (v == dest) { + return returnArray; + } + } + if (!returnArray.isEmpty() && noNewNodes) { + returnArray.removeLast(); + } + } + return null; + } + + private void checkAirport(int partenza, int destinazione) { + if (partenza < 0 || destinazione < 0 || partenza >= myCollegamenti.getOrder() || destinazione >= myCollegamenti.getOrder()) { + throw new IllegalArgumentException("Aeroporto di partenza o di destinazione non esite"); + } + } + + public int tempoMinimo(int partenza, int destinazione) { + checkAirport(partenza, destinazione); Arrays.fill(founded, false); int[] d = dijkstra(partenza); return d[destinazione]; } public int scali(int partenza, int destinazione) { - if (partenza >= myCollegamenti.getOrder() || destinazione >= myCollegamenti.getOrder() || partenza <= -1 || destinazione <= -1) { - throw new IllegalArgumentException("Aereoporto di partenza o di destinazione non esite"); - } - int[] res = bfs(partenza); + checkAirport(partenza, destinazione); if (partenza == destinazione) return 0; + int[] res = bfs(partenza); if (res[destinazione] != -1) return --res[destinazione]; else return res[destinazione]; } public int tempo(int partenza, int destinazione) { - if (partenza >= myCollegamenti.getOrder() || destinazione >= myCollegamenti.getOrder() || partenza <= -1 || destinazione <= -1) { - throw new IllegalArgumentException("Aereoporto di partenza o di destinazione non esite"); - } + checkAirport(partenza, destinazione); Arrays.fill(founded, false); return bfsTime(partenza)[destinazione]; } + + public ArrayList<Edge> trattaVeloce(int partenza, int destinazione) { + checkAirport(partenza, destinazione); + Arrays.fill(founded, false); + ArrayList<Edge> resultArray = new ArrayList<>(); + return dijkstraTrattaVeloce(partenza, destinazione, resultArray) ? resultArray : null; + } + + public ArrayList<Integer> elencoScali(int partenza, int destinazione) { + checkAirport(partenza, destinazione); + if (partenza == destinazione) return new ArrayList<>(); //Serve solo per ritornare un ArrayList vuota + Arrays.fill(founded, false); + return bfsMinScali(partenza, destinazione); + } } diff --git a/Algoritmi_2/Teoria/Alberi_di_visita_e_Array_dei_padri.pdf b/Algoritmi_2/Teoria/Alberi_di_visita_e_Array_dei_padri.pdf index 0955f36212772eb95b99574d5aaca451cda3a3c4..35ffe3388f36738698a2a5b58df891026b6fe600 100644 Binary files a/Algoritmi_2/Teoria/Alberi_di_visita_e_Array_dei_padri.pdf and b/Algoritmi_2/Teoria/Alberi_di_visita_e_Array_dei_padri.pdf differ diff --git a/Algoritmi_2/Teoria/Alberi_di_visita_e_Array_dei_padri.xopp b/Algoritmi_2/Teoria/Alberi_di_visita_e_Array_dei_padri.xopp index 1af22f5b57adfd545773aa42346e5c48cf2d241c..cb209789cb764d151e72fe848aa600e4ef3a505a 100644 Binary files a/Algoritmi_2/Teoria/Alberi_di_visita_e_Array_dei_padri.xopp and b/Algoritmi_2/Teoria/Alberi_di_visita_e_Array_dei_padri.xopp differ diff --git a/Algoritmi_2/Teoria/Grafi_Introduzione.pdf b/Algoritmi_2/Teoria/Grafi_Introduzione.pdf index f5c7901fc771300a2c78dfd5af1c4c9a4d85ad5a..b7cfa222d0c77ce50ba043df07700d2b4b1e8d5b 100644 Binary files a/Algoritmi_2/Teoria/Grafi_Introduzione.pdf and b/Algoritmi_2/Teoria/Grafi_Introduzione.pdf differ diff --git a/Algoritmi_2/Teoria/Grafi_Introduzione.xopp b/Algoritmi_2/Teoria/Grafi_Introduzione.xopp index 2faceec8f5b361bdf073bb5b6da5db3cb8770b4b..4ffabeb6ea5df6c427ad5db7a609149eb7a07b35 100644 Binary files a/Algoritmi_2/Teoria/Grafi_Introduzione.xopp and b/Algoritmi_2/Teoria/Grafi_Introduzione.xopp differ diff --git a/Algoritmi_2/Teoria/Minimo_Albero_Ricoprente.xopp b/Algoritmi_2/Teoria/Minimo_Albero_Ricoprente.xopp index f2c9a424fb4c61c5493b2d5b0a16ae8ce9a41710..0745b691e3f75da555300c0311ca24026b913505 100644 Binary files a/Algoritmi_2/Teoria/Minimo_Albero_Ricoprente.xopp and b/Algoritmi_2/Teoria/Minimo_Albero_Ricoprente.xopp differ