diff --git a/lib/nblibraries.properties b/lib/nblibraries.properties index 1d6c048..399d680 100644 --- a/lib/nblibraries.properties +++ b/lib/nblibraries.properties @@ -1,14 +1,14 @@ -libs.CopyLibs.classpath=\ - ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar -libs.CopyLibs.displayName=CopyLibs Task -libs.CopyLibs.prop-version=3.0 -libs.junit_5.displayName=JUnit 5.6.0 -libs.junit_5.javadoc=\ - ${base}/junit_5/junit-jupiter-api-5.6.0-javadoc.jar;\ - ${base}/junit_5/junit-jupiter-params-5.6.0-javadoc.jar;\ - ${base}/junit_5/junit-jupiter-engine-5.6.0-javadoc.jar -libs.junit_5.prop-maven-dependencies=\n org.junit.jupiter:junit-jupiter-api:5.6.0:jar\n org.junit.jupiter:junit-jupiter-params:5.6.0:jar\n org.junit.jupiter:junit-jupiter-engine:5.6.0:jar\n -libs.junit_5.src=\ - ${base}/junit_5/junit-jupiter-api-5.6.0-sources.jar;\ - ${base}/junit_5/junit-jupiter-params-5.6.0-sources.jar;\ - ${base}/junit_5/junit-jupiter-engine-5.6.0-sources.jar +libs.CopyLibs.classpath=\ + ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar +libs.CopyLibs.displayName=CopyLibs Task +libs.CopyLibs.prop-version=3.0 +libs.junit_5.displayName=JUnit 5.6.0 +libs.junit_5.javadoc=\ + ${base}/junit_5/junit-jupiter-api-5.6.0-javadoc.jar;\ + ${base}/junit_5/junit-jupiter-params-5.6.0-javadoc.jar;\ + ${base}/junit_5/junit-jupiter-engine-5.6.0-javadoc.jar +libs.junit_5.prop-maven-dependencies=\n org.junit.jupiter:junit-jupiter-api:5.6.0:jar\n org.junit.jupiter:junit-jupiter-params:5.6.0:jar\n org.junit.jupiter:junit-jupiter-engine:5.6.0:jar\n +libs.junit_5.src=\ + ${base}/junit_5/junit-jupiter-api-5.6.0-sources.jar;\ + ${base}/junit_5/junit-jupiter-params-5.6.0-sources.jar;\ + ${base}/junit_5/junit-jupiter-engine-5.6.0-sources.jar diff --git a/nbproject/project.properties b/nbproject/project.properties index 6944e46..b6af278 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -1,97 +1,97 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=true -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.title=jlibgraph -application.vendor=Javier Marrero -auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.modulepath=\ - ${run.modulepath} -debug.test.classpath=\ - ${run.test.classpath} -debug.test.modulepath=\ - ${run.test.modulepath} -# Files in build.classes.dir which should be excluded from distribution jar -dist.archive.excludes= -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/jlibgraph.jar -dist.javadoc.dir=${dist.dir}/javadoc -dist.jlink.dir=${dist.dir}/jlink -dist.jlink.output=${dist.jlink.dir}/jlibgraph -endorsed.classpath= -excludes= -includes=** -jar.compress=false -javac.classpath= -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=true -javac.external.vm=true -javac.modulepath= -javac.processormodulepath= -javac.processorpath=\ - ${javac.classpath} -javac.source=9 -javac.target=9 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javac.test.modulepath=\ - ${javac.modulepath} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam= -javadoc.author=true -javadoc.encoding=${source.encoding} -javadoc.html5=false -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=true -javadoc.windowtitle=JLibGraph API Reference -# The jlink additional root modules to resolve -jlink.additionalmodules= -# The jlink additional command line parameters -jlink.additionalparam= -jlink.launcher=true -jlink.launcher.name=jlibgraph -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=true -platform.active=default_platform -project.license=lgpl21 -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project. -# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. -# To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs= -run.modulepath=\ - ${javac.modulepath} -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -run.test.modulepath=\ - ${javac.test.modulepath} -source.encoding=UTF-8 -src.dir=src -test.src.dir=test +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=true +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=jlibgraph +application.vendor=Javier Marrero +auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.modulepath=\ + ${run.modulepath} +debug.test.classpath=\ + ${run.test.classpath} +debug.test.modulepath=\ + ${run.test.modulepath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/jlibgraph.jar +dist.javadoc.dir=${dist.dir}/javadoc +dist.jlink.dir=${dist.dir}/jlink +dist.jlink.output=${dist.jlink.dir}/jlibgraph +endorsed.classpath= +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=true +javac.external.vm=true +javac.modulepath= +javac.processormodulepath= +javac.processorpath=\ + ${javac.classpath} +javac.source=9 +javac.target=9 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.modulepath=\ + ${javac.modulepath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=true +javadoc.encoding=${source.encoding} +javadoc.html5=false +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=true +javadoc.windowtitle=JLibGraph API Reference +# The jlink additional root modules to resolve +jlink.additionalmodules= +# The jlink additional command line parameters +jlink.additionalparam= +jlink.launcher=true +jlink.launcher.name=jlibgraph +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=true +platform.active=default_platform +project.license=lgpl21 +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.modulepath=\ + ${javac.modulepath} +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +run.test.modulepath=\ + ${javac.test.modulepath} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/src/cu/edu/cujae/graphy/algorithms/AbstractAlgorithm.java b/src/cu/edu/cujae/graphy/algorithms/AbstractAlgorithm.java index 91c474a..f7bfd14 100644 --- a/src/cu/edu/cujae/graphy/algorithms/AbstractAlgorithm.java +++ b/src/cu/edu/cujae/graphy/algorithms/AbstractAlgorithm.java @@ -27,7 +27,7 @@ public abstract class AbstractAlgorithm implements Algorithm { - private T result; + T result; protected AbstractAlgorithm(T result) { diff --git a/src/cu/edu/cujae/graphy/algorithms/ColorableAlgorithm.java b/src/cu/edu/cujae/graphy/algorithms/ColorableAlgorithm.java new file mode 100644 index 0000000..35c9200 --- /dev/null +++ b/src/cu/edu/cujae/graphy/algorithms/ColorableAlgorithm.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2022 Ananda. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.algorithms; + +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.iterators.GraphIterator; + +/** + *El objetivo de este algoritmo es determinar si un grafo no dirigido puede ser + * coloreado con m colores, de forma tal que dos vértices adyacentes no posean + * igual coloratura. + * + * @author Ananda + * @param + */ +public class ColorableAlgorithm extends AbstractAlgorithm { + private final Graph graph; + private final int m; + private final String color; + private final GraphIterator iter; + + public ColorableAlgorithm(Graph graph, int m, String color, GraphIterator iter){ + super(Boolean.TRUE); + if(graph.isDirected()){ + throw new IllegalArgumentException( + "Attempted to apply Colorable algorithm to an directed graph."); + } + this.graph = graph; + this.m = m; + this.color = color; + this.iter = (GraphIterator) graph.depthFirstSearchIterator(false); + } + + @Override + public Algorithm apply(){ + while(iter.hasNext()){ + + } + + return this; + } + +} diff --git a/src/cu/edu/cujae/graphy/algorithms/Dial.java b/src/cu/edu/cujae/graphy/algorithms/DialShortestPath.java similarity index 64% rename from src/cu/edu/cujae/graphy/algorithms/Dial.java rename to src/cu/edu/cujae/graphy/algorithms/DialShortestPath.java index 5748b7f..fe6d40d 100644 --- a/src/cu/edu/cujae/graphy/algorithms/Dial.java +++ b/src/cu/edu/cujae/graphy/algorithms/DialShortestPath.java @@ -18,8 +18,10 @@ */ package cu.edu.cujae.graphy.algorithms; -import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.WeightedGraph; +import cu.edu.cujae.graphy.core.iterators.GraphIterator; import cu.edu.cujae.graphy.utils.Pair; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,20 +35,25 @@ * @author Ananda * @param */ -public class Dial extends AbstractAlgorithm>>> +public class DialShortestPath extends AbstractAlgorithm>>> { + private final WeightedGraph graph; + private final GraphIterator iter; - private Graph graph; - - public Dial() - { - super(null); + public DialShortestPath(WeightedGraph graph, GraphIterator iter){ + super(new HashMap<>(graph.size())); + if (!graph.isWeighted()) + { + throw new IllegalArgumentException( + "Attempted to apply Dial algorithm to an unweighted graph."); + } + this.graph = graph; + this.iter = (GraphIterator) graph.depthFirstSearchIterator(false); } @Override - public Algorithm>>> apply() - { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + public Algorithm>>> apply(){ + + return this; } - } diff --git a/src/cu/edu/cujae/graphy/algorithms/DijkstraShortestPath.java b/src/cu/edu/cujae/graphy/algorithms/DijkstraShortestPath.java index 1c565e7..c41a385 100644 --- a/src/cu/edu/cujae/graphy/algorithms/DijkstraShortestPath.java +++ b/src/cu/edu/cujae/graphy/algorithms/DijkstraShortestPath.java @@ -1,185 +1,185 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.algorithms; - -import cu.edu.cujae.graphy.core.Edge; -import cu.edu.cujae.graphy.core.WeightedGraph; -import cu.edu.cujae.graphy.core.iterators.GraphIterator; -import cu.edu.cujae.graphy.utils.Pair; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.PriorityQueue; -import java.util.TreeMap; - -/** - * Given a graph and a source vertex in the graph, find the shortest paths from the source to all vertices in the given - * graph. - *

- * The name of the algorithm refers to the Dutch computation scientist Edsger Dijkstra, who described it in 1959. - * The algorithm solves the single-source shortest path problem for a weighted graph. This algorithm is greedy - * and keeps track of the weights of the edges for finding the path that minimizes the total distance. - *

- * The time complexity of this algorithm is at most O(n2) but on the average case it may - * achieve O(V + E log(V)). Dijkstra has several advantages such as its time complexity, that it is useful - * in finding the shortest distance quite fast. However it is unable to handle negative weights and, as every greedy - * algorithm it may not be optimal for certain conditions. - *

- * Dijkstra's algorithm fails on negative weights because since Dijkstra follows a greedy approach, once a node is - * marked as visited it cannot be reconsidered even if there is another path with less cost or distance. This issue - * arises only if there exists a negative weight or edge in the graph. If negative weights are needed, see the - * Bellman-Ford algorithm. In this implementation, whenever a graph with negative weights is encountered it may throw - * a {@link cu.edu.cujae.graphy.core.exceptions.InvalidOperationException}. - * - * @author Javier Marrero - * @param The type of the graph - */ -public class DijkstraShortestPath extends AbstractAlgorithm>>> -{ - - private final Map distances; - private final WeightedGraph G; - private final GraphIterator it; - private final Map previous; - private final int s; - private final PriorityQueue Q; - private final int V; - - public DijkstraShortestPath(WeightedGraph graph, GraphIterator iter) - { - super(new HashMap<>(graph.size())); - if (!graph.isWeighted()) - { - throw new IllegalArgumentException( - "Attempted to apply Dijkstra Shortest Path algorithm to an unweighted graph."); - } - - // Initialize the fields of the classes - this.distances = new HashMap<>(graph.size(), 0.25f); - this.G = graph; - this.it = iter; - this.previous = new TreeMap<>(); - this.s = iter.getLabel(); - this.Q = new PriorityQueue<>(graph.size(), (Integer u, Integer v) -> - { - int du = distances.get(u); - int dv = distances.get(v); - - return du - dv; - }); - this.V = graph.size(); - - // Get a set of all the integer vertices - int[] vertices = new int[V]; - int k = 0; - - GraphIterator depthFirstSearchIterator = (GraphIterator) graph.depthFirstSearchIterator(false); - while (depthFirstSearchIterator.hasNext()) - { - depthFirstSearchIterator.next(); - vertices[k++] = depthFirstSearchIterator.getLabel(); - } - - // Initialize the distances - for (int v : vertices) - { - if (G.isVertexAdjacent(s, v)) - { - distances.put(v, (Integer) iter.getAdjacentEdge(v).getWeight().getValue()); - previous.put(v, iter.getLabel()); - } - else - { - distances.put(v, Integer.MAX_VALUE); - previous.put(v, null); - } - - Q.add(v); - } - - // System.err.println(Q); - // Initialize the initial distances - distances.put(iter.getLabel(), 0); - } - - @Override - public Algorithm>>> apply() - { - // Code - while (!Q.isEmpty()) - { - // System.err.println(Q); - - int u = Q.poll(); - it.next(u); - - for (Edge edge : it.getAllAdjacentEdges()) - { - int v; - if (it.getEdgesDepartingSelf().contains(edge)) - { - v = edge.getFinalNode().getLabel(); - } - else - { - v = edge.getStartNode().getLabel(); - } - - if (Q.contains(v)) - { - int alt = distances.get(u) + (int) edge.getWeight().getValue(); - if (alt <= distances.get(v)) - { - distances.put(v, alt); - previous.put(v, u); - } - } - } - } - - // Create the shortest path sequence - // Create the final result - Map>> result = getResult(); - for (int k : distances.keySet()) - { - result.put(k, new Pair<>(distances.get(k), makeShortestPathSequence(s, k))); - } - - // Mandated by the specification - return this; - } - - private List makeShortestPathSequence(int source, int target) - { - LinkedList S = new LinkedList<>(); - int u = target; - - if (previous.get(u) != null) - { - while (previous.get(u) != null) - { - S.push(u); - u = previous.get(u); - } - } - S.push(source); - return S; - } -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.algorithms; + +import cu.edu.cujae.graphy.core.Edge; +import cu.edu.cujae.graphy.core.WeightedGraph; +import cu.edu.cujae.graphy.core.iterators.GraphIterator; +import cu.edu.cujae.graphy.utils.Pair; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.TreeMap; + +/** + * Given a graph and a source vertex in the graph, find the shortest paths from the source to all vertices in the given + * graph. + *

+ * The name of the algorithm refers to the Dutch computation scientist Edsger Dijkstra, who described it in 1959. + * The algorithm solves the single-source shortest path problem for a weighted graph. This algorithm is greedy + * and keeps track of the weights of the edges for finding the path that minimizes the total distance. + *

+ * The time complexity of this algorithm is at most O(n2) but on the average case it may + * achieve O(V + E log(V)). Dijkstra has several advantages such as its time complexity, that it is useful + * in finding the shortest distance quite fast. However it is unable to handle negative weights and, as every greedy + * algorithm it may not be optimal for certain conditions. + *

+ * Dijkstra's algorithm fails on negative weights because since Dijkstra follows a greedy approach, once a node is + * marked as visited it cannot be reconsidered even if there is another path with less cost or distance. This issue + * arises only if there exists a negative weight or edge in the graph. If negative weights are needed, see the + * Bellman-Ford algorithm. In this implementation, whenever a graph with negative weights is encountered it may throw + * a {@link cu.edu.cujae.graphy.core.exceptions.InvalidOperationException}. + * + * @author Javier Marrero + * @param The type of the graph + */ +public class DijkstraShortestPath extends AbstractAlgorithm>>> +{ + + private final Map distances; + private final WeightedGraph G; + private final GraphIterator it; + private final Map previous; + private final int s; + private final PriorityQueue Q; + private final int V; + + public DijkstraShortestPath(WeightedGraph graph, GraphIterator iter) + { + super(new HashMap<>(graph.size())); + if (!graph.isWeighted()) + { + throw new IllegalArgumentException( + "Attempted to apply Dijkstra Shortest Path algorithm to an unweighted graph."); + } + + // Initialize the fields of the classes + this.distances = new HashMap<>(graph.size(), 0.25f); + this.G = graph; + this.it = iter; + this.previous = new TreeMap<>(); + this.s = iter.getLabel(); + this.Q = new PriorityQueue<>(graph.size(), (Integer u, Integer v) -> + { + int du = distances.get(u); + int dv = distances.get(v); + + return du - dv; + }); + this.V = graph.size(); + + // Get a set of all the integer vertices + int[] vertices = new int[V]; + int k = 0; + + GraphIterator depthFirstSearchIterator = (GraphIterator) graph.depthFirstSearchIterator(false); + while (depthFirstSearchIterator.hasNext()) + { + depthFirstSearchIterator.next(); + vertices[k++] = depthFirstSearchIterator.getLabel(); + } + + // Initialize the distances + for (int v : vertices) + { + if (G.isVertexAdjacent(s, v)) + { + distances.put(v, (Integer) iter.getAdjacentEdge(v).getWeight().getValue()); + previous.put(v, iter.getLabel()); + } + else + { + distances.put(v, Integer.MAX_VALUE); + previous.put(v, null); + } + + Q.add(v); + } + + // System.err.println(Q); + // Initialize the initial distances + distances.put(iter.getLabel(), 0); + } + + @Override + public Algorithm>>> apply() + { + // Code + while (!Q.isEmpty()) + { + // System.err.println(Q); + + int u = Q.poll(); + it.next(u); + + for (Edge edge : it.getAllAdjacentEdges()) + { + int v; + if (it.getEdgesDepartingSelf().contains(edge)) + { + v = edge.getFinalNode().getLabel(); + } + else + { + v = edge.getStartNode().getLabel(); + } + + if (Q.contains(v)) + { + int alt = distances.get(u) + (int) edge.getWeight().getValue(); + if (alt <= distances.get(v)) + { + distances.put(v, alt); + previous.put(v, u); + } + } + } + } + + // Create the shortest path sequence + // Create the final result + Map>> result = getResult(); + for (int k : distances.keySet()) + { + result.put(k, new Pair<>(distances.get(k), makeShortestPathSequence(s, k))); + } + + // Mandated by the specification + return this; + } + + private List makeShortestPathSequence(int source, int target) + { + LinkedList S = new LinkedList<>(); + int u = target; + + if (previous.get(u) != null) + { + while (previous.get(u) != null) + { + S.push(u); + u = previous.get(u); + } + } + S.push(source); + return S; + } +} diff --git a/src/cu/edu/cujae/graphy/algorithms/ExistSimpleRoad.java b/src/cu/edu/cujae/graphy/algorithms/ExistSimpleRoad.java index 89f70fe..3b96989 100644 --- a/src/cu/edu/cujae/graphy/algorithms/ExistSimpleRoad.java +++ b/src/cu/edu/cujae/graphy/algorithms/ExistSimpleRoad.java @@ -1,144 +1,144 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.algorithms; - -import cu.edu.cujae.graphy.core.Edge; -import cu.edu.cujae.graphy.core.WeightedGraph; -import cu.edu.cujae.graphy.core.iterators.GraphIterator; -import cu.edu.cujae.graphy.utils.MapTriArray; -import cu.edu.cujae.graphy.utils.Pair; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -/** - * - * @author Jose - * @param - */ -public class ExistSimpleRoad extends AbstractAlgorithm>> -{ - - private final WeightedGraph graph; - private final int k; - private final GraphIterator iteratorNI; - private final GraphIterator iteratorNF; - private final int vertices; - private final int pesoMayor; - - @SuppressWarnings ("unchecked") - public ExistSimpleRoad(WeightedGraph graph, GraphIterator iteratorNI, GraphIterator iteratorNF, int k, - int pesoMayor) - { - super(new Pair<>(0, new LinkedList())); - this.graph = graph; - this.iteratorNI = iteratorNI; - this.iteratorNF = iteratorNF; - this.k = k; - this.vertices = graph.size(); - this.pesoMayor = pesoMayor + 1; - } - - @Override - public Algorithm>> apply() - { - /* - * Tabla a rellenar usando DP. El valor trimatrix.get(i,j,l), donde i y j indican el nodo destino y el final respectivamente y l - * y l almacenará el peso del camino mas corto de i a j con exactamente k aristas - */ - MapTriArray trimatrix = new MapTriArray<>(); - ArrayList visitados = new ArrayList<>(graph.size()); - GraphIterator iter = (GraphIterator) graph.breadthFirstSearchIterator(false); - - // Guardando en una lista las etiquetas de cada nodo del grafo para acceder a ellas de forma secuencial - while (iter.hasNext()) - { - iter.next(); - visitados.add(iter.getLabel()); - } - - for (int l = 0; l <= k; l++) - { - for (int i = 0; i < vertices; i++) - { - for (int j = 0; j < vertices; j++) - { - GraphIterator iterat = graph.iterator(visitados.get(i)); - GraphIterator iterat2 = graph.iterator(visitados.get(j)); - int label1 = iterat.getLabel(); - int label2 = iterat2.getLabel(); - - //Inicializar valor, que al finalizar el algoritmo la distancia se mantenga con pesoMayor indica que no existe un camino entre esos nodos - trimatrix.put(iterat.getLabel(), iterat2.getLabel(), l, pesoMayor); - - //Casos bases - if (l == 0 && i == j) - { - trimatrix.put(iterat.getLabel(), iterat2.getLabel(), l, 0); - } - - //En el caso de que la distancia sea 1, los nodos deben ser adyacentes - if (l == 1 && graph.isVertexAdjacent(label1, label2)) - { - /*Al ser un grafo dirigido primero compruebo si es dirigido de i a j para obtener la arista entre ellos, sino es que es dirigido de j a i, - pero la arista y el peso sigue siendo la misma se realiza la comprobacion para no obtener un valor nulo*/ - Edge edge = iterat.getAdjacentEdge(label2) != null ? iterat.getAdjacentEdge(label2) : iterat2. - getAdjacentEdge(label1); - trimatrix.put(iterat.getLabel(), iterat2.getLabel(), l, (Integer) edge.getWeight().getValue()); - } - - //En el caso de que haya mas de una arista de distancia entre los nodos - if (l > 1) - { - for (int a = 0; a < vertices; a++) - { - GraphIterator iterat3 = graph.iterator(visitados.get(a)); - - /*Debe existir una arista de i a a teniendo en cuenta que los nodos a i y j sean diferentes - y debe existir una distancia entre a y j*/ - if (iterat.isAdjacent(iterat3) && i != a && j != a && trimatrix.get(iterat3.getLabel(), - iterat2.getLabel(), l - - 1) - != pesoMayor) - { - /*Se selecciona como distancia entre los nodosi y j el menor valor entre la distancia que ya se encuentra actualmente en la trimatrix y - el valor hasta la arista anterior sumado a la distancia entre a e i*/ - trimatrix.put(iterat.getLabel(), iterat2.getLabel(), l, Math.min(trimatrix.get(iterat. - getLabel(), iterat2.getLabel(), l), ((iterat.getAdjacentEdge( - iterat3.getLabel()) != null) - ? (Integer) iterat.getAdjacentEdge( - iterat3.getLabel()).getWeight(). - getValue() : (Integer) iterat3. - getAdjacentEdge(iterat.getLabel()). - getWeight().getValue()) + trimatrix. - get(iterat3.getLabel(), - iterat2.getLabel(), - l - 1))); - } - } - } - } - } - } - - setResult(new Pair<>(trimatrix.get(iteratorNI.getLabel(), iteratorNF.getLabel(), k), new LinkedList<>())); - return this; - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.algorithms; + +import cu.edu.cujae.graphy.core.Edge; +import cu.edu.cujae.graphy.core.WeightedGraph; +import cu.edu.cujae.graphy.core.iterators.GraphIterator; +import cu.edu.cujae.graphy.utils.MapTriArray; +import cu.edu.cujae.graphy.utils.Pair; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * + * @author Jose + * @param + */ +public class ExistSimpleRoad extends AbstractAlgorithm>> +{ + + private final WeightedGraph graph; + private final int k; + private final GraphIterator iteratorNI; + private final GraphIterator iteratorNF; + private final int vertices; + private final int pesoMayor; + + @SuppressWarnings ("unchecked") + public ExistSimpleRoad(WeightedGraph graph, GraphIterator iteratorNI, GraphIterator iteratorNF, int k, + int pesoMayor) + { + super(new Pair<>(0, new LinkedList())); + this.graph = graph; + this.iteratorNI = iteratorNI; + this.iteratorNF = iteratorNF; + this.k = k; + this.vertices = graph.size(); + this.pesoMayor = pesoMayor + 1; + } + + @Override + public Algorithm>> apply() + { + /* + * Tabla a rellenar usando DP. El valor trimatrix.get(i,j,l), donde i y j indican el nodo destino y el final respectivamente y l + * y l almacenará el peso del camino mas corto de i a j con exactamente k aristas + */ + MapTriArray trimatrix = new MapTriArray<>(); + ArrayList visitados = new ArrayList<>(graph.size()); + GraphIterator iter = (GraphIterator) graph.breadthFirstSearchIterator(false); + + // Guardando en una lista las etiquetas de cada nodo del grafo para acceder a ellas de forma secuencial + while (iter.hasNext()) + { + iter.next(); + visitados.add(iter.getLabel()); + } + + for (int l = 0; l <= k; l++) + { + for (int i = 0; i < vertices; i++) + { + for (int j = 0; j < vertices; j++) + { + GraphIterator iterat = graph.iterator(visitados.get(i)); + GraphIterator iterat2 = graph.iterator(visitados.get(j)); + int label1 = iterat.getLabel(); + int label2 = iterat2.getLabel(); + + //Inicializar valor, que al finalizar el algoritmo la distancia se mantenga con pesoMayor indica que no existe un camino entre esos nodos + trimatrix.put(iterat.getLabel(), iterat2.getLabel(), l, pesoMayor); + + //Casos bases + if (l == 0 && i == j) + { + trimatrix.put(iterat.getLabel(), iterat2.getLabel(), l, 0); + } + + //En el caso de que la distancia sea 1, los nodos deben ser adyacentes + if (l == 1 && graph.isVertexAdjacent(label1, label2)) + { + /*Al ser un grafo dirigido primero compruebo si es dirigido de i a j para obtener la arista entre ellos, sino es que es dirigido de j a i, + pero la arista y el peso sigue siendo la misma se realiza la comprobacion para no obtener un valor nulo*/ + Edge edge = iterat.getAdjacentEdge(label2) != null ? iterat.getAdjacentEdge(label2) : iterat2. + getAdjacentEdge(label1); + trimatrix.put(iterat.getLabel(), iterat2.getLabel(), l, (Integer) edge.getWeight().getValue()); + } + + //En el caso de que haya mas de una arista de distancia entre los nodos + if (l > 1) + { + for (int a = 0; a < vertices; a++) + { + GraphIterator iterat3 = graph.iterator(visitados.get(a)); + + /*Debe existir una arista de i a a teniendo en cuenta que los nodos a i y j sean diferentes + y debe existir una distancia entre a y j*/ + if (iterat.isAdjacent(iterat3) && i != a && j != a && trimatrix.get(iterat3.getLabel(), + iterat2.getLabel(), l + - 1) + != pesoMayor) + { + /*Se selecciona como distancia entre los nodosi y j el menor valor entre la distancia que ya se encuentra actualmente en la trimatrix y + el valor hasta la arista anterior sumado a la distancia entre a e i*/ + trimatrix.put(iterat.getLabel(), iterat2.getLabel(), l, Math.min(trimatrix.get(iterat. + getLabel(), iterat2.getLabel(), l), ((iterat.getAdjacentEdge( + iterat3.getLabel()) != null) + ? (Integer) iterat.getAdjacentEdge( + iterat3.getLabel()).getWeight(). + getValue() : (Integer) iterat3. + getAdjacentEdge(iterat.getLabel()). + getWeight().getValue()) + trimatrix. + get(iterat3.getLabel(), + iterat2.getLabel(), + l - 1))); + } + } + } + } + } + } + + setResult(new Pair<>(trimatrix.get(iteratorNI.getLabel(), iteratorNF.getLabel(), k), new LinkedList<>())); + return this; + } + +} diff --git a/src/cu/edu/cujae/graphy/algorithms/IsolatedVertices.java b/src/cu/edu/cujae/graphy/algorithms/IsolatedVertices.java new file mode 100644 index 0000000..853040a --- /dev/null +++ b/src/cu/edu/cujae/graphy/algorithms/IsolatedVertices.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2022 Jose. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.algorithms; + +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.iterators.GraphIterator; +import java.util.LinkedList; +import java.util.Set; +import java.util.TreeSet; + +/** + * + * @author Jose + */ + +/*IsolatedVertices se realiza para poder obtener todos los vértices aislados en un grafo*/ + +public class IsolatedVertices extends AbstractAlgorithm> +{ + private final Graph graph; + public IsolatedVertices (Graph graph) + { + //En el caso de que no existan vértices aislados se retorna una lista vacía + super( new LinkedList()); + this.graph = graph; + } + + @Override + public Algorithm> apply() + { + //Lista para ir guardando los vertices aislados + LinkedList aislados = new LinkedList(); + //Lista para guardar los nodos visitados y no analizarlos de nuevo + Set visited = new TreeSet<>(); + + GraphIterator dfs = (GraphIterator) graph.depthFirstSearchIterator(true); + while(dfs.hasNext()) + { + dfs.next(); + //Si no ha sido visitado y no tiene aristas adyacentes + if(!visited.contains(dfs.getLabel()) && dfs.getAllAdjacentEdges().isEmpty()) + { + aislados.add(dfs.getLabel()); + visited.add(dfs.getLabel()); + } + } + setResult(aislados); + return this; + } + +} diff --git a/src/cu/edu/cujae/graphy/algorithms/Kosaraju.java b/src/cu/edu/cujae/graphy/algorithms/KosarajuAlgorithm.java similarity index 61% rename from src/cu/edu/cujae/graphy/algorithms/Kosaraju.java rename to src/cu/edu/cujae/graphy/algorithms/KosarajuAlgorithm.java index 3304cac..26252de 100644 --- a/src/cu/edu/cujae/graphy/algorithms/Kosaraju.java +++ b/src/cu/edu/cujae/graphy/algorithms/KosarajuAlgorithm.java @@ -19,6 +19,8 @@ package cu.edu.cujae.graphy.algorithms; import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.iterators.GraphIterator; +import java.util.ArrayDeque; /** * El algoritmo de Kosaraju está basado en DFS utilizado para encontrar componentes @@ -30,20 +32,33 @@ * @author Ananda * @param */ -public class Kosaraju extends AbstractAlgorithm +public class KosarajuAlgorithm extends AbstractAlgorithm { + private final Graph graph; + private final GraphIterator iter; - private Graph graph; - - public Kosaraju() + public KosarajuAlgorithm(GraphIterator iter, Graph graph) { - super(null); + super(Boolean.TRUE); + if (!graph.isDirected()) + { + throw new IllegalArgumentException( + "Attempted to apply Kosaraju algorithm to an undirected graph."); + } + this.graph = graph; + this.iter = (GraphIterator) graph.depthFirstSearchIterator(iter.getLabel(), false); } @Override public Algorithm apply() { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + ArrayDeque stack = new ArrayDeque<>(); + while(iter.hasNext()){ + int label = iter.getLabel(); + stack.push(label); + iter.next(); + } + return this; } - -} + + } diff --git a/src/cu/edu/cujae/graphy/core/Edge.java b/src/cu/edu/cujae/graphy/core/Edge.java index 08246fe..9fa2362 100644 --- a/src/cu/edu/cujae/graphy/core/Edge.java +++ b/src/cu/edu/cujae/graphy/core/Edge.java @@ -1,105 +1,105 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core; - -/** - * An edge is an ordered pair of the form (u, v). The pair must be ordered because (u, v) is not the same - * as (v, u) in the case of a directed graph (di-graph). The pair of the form (u, v) indicates that - * there is an edge from vertex u to vertex v. The edges may contain an attribute known as weight. This - * attribute is arbitrary, but must be comparable; or in other words, a value. - *

- * - * @author Javier Marrero - */ -public interface Edge -{ - - /** - * Returns a reference to the edge's final node. - * - * @return a reference to the edge's final node. - */ - public Node getFinalNode(); - - /** - * Returns the label associated to this edge. - * - * @return this edge's label. - */ - public Object getLabel(); - - /** - * Returns a reference to the edge's initial node. - * - * @return a reference to the edge's initial node. - */ - public Node getStartNode(); - - /** - * Returns the weight of this edge. It may return a null value in the case the edge is unweighted. - * - * @return the value of the weight. - */ - public Weight getWeight(); - - /** - * Returns true if the graph edge is directed. This will be true only if the containing graph is also directed. - * This method is established here as a convenience. - * - * @return if the graph's edge is directed. - */ - public boolean isDirected(); - - /** - * Returns true if this edge contains a label. A label uniquely identifies an edge. - * - * @return if the node is labeled or not. - */ - public boolean isLabeled(); - - /** - * Returns true if the edge is weighted. - * - * @return if the edge is weighted or unweighted. - */ - public boolean isWeighted(); - - /** - * Reverse the direction of the edge. The departing node becomes the destination node and vice-versa. Weights are - * not modified in any way. - *

- * This method only reverses the apparent direction of an edge. Edge direction reversal is a much more complicated - * process that is carried in conjunction with {@link Node} - */ - public void reverseApparentDirection(); - - /** - * Sets the label corresponding to this edge. - * - * @param label - */ - public void setLabel(Object label); - - /** - * Sets the weight of this edge. - * - * @param weight - */ - public void setWeight(Weight weight); -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core; + +/** + * An edge is an ordered pair of the form (u, v). The pair must be ordered because (u, v) is not the same + * as (v, u) in the case of a directed graph (di-graph). The pair of the form (u, v) indicates that + * there is an edge from vertex u to vertex v. The edges may contain an attribute known as weight. This + * attribute is arbitrary, but must be comparable; or in other words, a value. + *

+ * + * @author Javier Marrero + */ +public interface Edge +{ + + /** + * Returns a reference to the edge's final node. + * + * @return a reference to the edge's final node. + */ + public Node getFinalNode(); + + /** + * Returns the label associated to this edge. + * + * @return this edge's label. + */ + public Object getLabel(); + + /** + * Returns a reference to the edge's initial node. + * + * @return a reference to the edge's initial node. + */ + public Node getStartNode(); + + /** + * Returns the weight of this edge. It may return a null value in the case the edge is unweighted. + * + * @return the value of the weight. + */ + public Weight getWeight(); + + /** + * Returns true if the graph edge is directed. This will be true only if the containing graph is also directed. + * This method is established here as a convenience. + * + * @return if the graph's edge is directed. + */ + public boolean isDirected(); + + /** + * Returns true if this edge contains a label. A label uniquely identifies an edge. + * + * @return if the node is labeled or not. + */ + public boolean isLabeled(); + + /** + * Returns true if the edge is weighted. + * + * @return if the edge is weighted or unweighted. + */ + public boolean isWeighted(); + + /** + * Reverse the direction of the edge. The departing node becomes the destination node and vice-versa. Weights are + * not modified in any way. + *

+ * This method only reverses the apparent direction of an edge. Edge direction reversal is a much more complicated + * process that is carried in conjunction with {@link Node} + */ + public void reverseApparentDirection(); + + /** + * Sets the label corresponding to this edge. + * + * @param label + */ + public void setLabel(Object label); + + /** + * Sets the weight of this edge. + * + * @param weight + */ + public void setWeight(Weight weight); +} diff --git a/src/cu/edu/cujae/graphy/core/Graph.java b/src/cu/edu/cujae/graphy/core/Graph.java index cea86c1..cd488e0 100644 --- a/src/cu/edu/cujae/graphy/core/Graph.java +++ b/src/cu/edu/cujae/graphy/core/Graph.java @@ -1,251 +1,251 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core; - -import cu.edu.cujae.graphy.core.iterators.GraphIterator; -import java.util.Collection; -import java.util.Iterator; - -/** - * The Graph interface represents a graph as an abstract - * data structure.The graph does not make a distinction with the data - * type it holds, it just presents an abstract model of a graph. - * - * @author Javier Marrero - * @param - */ -public interface Graph extends Iterable -{ - - /** - * Adds a new node to this graph with the specified index. - * - * @param label - * @param data - * - * @return a truth value representing wether insertion was successful. - */ - public boolean add(int label, T data); - - /** - * Adds a new node to this graph with a default allocated index. - * - * @param data - * - * @return a truth value representing wether insertion was successful. - */ - public boolean add(T data); - - /** - * Returns a BFS iterator to the selected node. - * - * @param node - * @param includeDisconnected - * - * @return a {@link Iterator} instance that is a BFS iterator. - */ - public Iterator breadthFirstSearchIterator(Node node, boolean includeDisconnected); - - /** - * The same as {@link cu.edu.cujae.graphy.core.Graph#breadthFirstSearchIterator(cu.edu.cujae.graphy.core.Node) } but - * with the integer label of the node. - * - * @param includeDisconnected - * - * @see Graph#breadthFirstSearchIterator(cu.edu.cujae.graphy.core.Node) - * @param v - * - * @return a {@link Iterator} instance. - */ - public Iterator breadthFirstSearchIterator(int v, boolean includeDisconnected); - - /** - * Returns a BFS iterator to a random node in the graph. - * - * @param includeDisconnected - * - * @return a {@link Iterator} - */ - public Iterator breadthFirstSearchIterator(boolean includeDisconnected); - - /** - * Connects two nodes in this graph. This method should return true if the connection was successful and false - * otherwise. The two input parameters are the labels of the nodes within the graph. - * - * @param u - * @param v - * - * @return - */ - public boolean connect(int u, int v); - - /** - * Connects two nodes within the graph. This version of the method uses the nodes directly. - * - * @param u - * @param v - * - * @return - */ - public boolean connect(Node u, Node v); - - /** - * Generates an iterator that performs a depth first search.Depth first traversal for a graph is similar to depth - * first traversal of a tree, the only catch being that, unlike trees, graphs may contain cycles (a node may be - * visited twice). This iterator avoids processing a node more than once. A graph may have more than one DFS - * traversal. - *

- * Depth-first search is an algorithm for traversing or searching a graph. The algorithm starts at the root node - * (some arbitrary node in this case, passed as a parameter) and explores as far as possible along each branch - * before backtracking. - *

- * The basic idea is to start from the root or any arbitrary node, and move to the next adjacent unmarked node. - * - * @param start - * @param includeDisconnected - * - * @return a new {@link Iterator} - */ - public Iterator depthFirstSearchIterator(Node start, boolean includeDisconnected); - - /** - * @param includeDisconnected - * - * @see Graph#depthFirstSearchIterator(cu.edu.cujae.graphy.core.Node) - * - * @param v the label of the node. - * - * @return - */ - public Iterator depthFirstSearchIterator(int v, boolean includeDisconnected); - - /** - * Generates an iterator that performs a depth first search, grabbing a random node as the root. - * - * @param includeDisconnected - * - * @see Graph#depthFirstSearchIterator(cu.edu.cujae.graphy.core.Node, boolean) - * @return a new {@link Iterator} - */ - public Iterator depthFirstSearchIterator(boolean includeDisconnected); - - /** - * This method should be, at some extent, similar to the Java cloning mechanism in that returns a deep copy of this - * object.The returned graph is not a view of this graph but two independent objects. Changes are not guaranteed - * to persists across clone instances as they don't share data. - *

- * While the two graphs does not share any internal representation, they both point to the same data, so any - * data manipulation will be seen in the original graph. If deep cloning of the internal data is desired, - * perform a manual copy or rather use the utility methods provided by the class Graphs. - *

- * If by any means the duplication cannot be made, a {@link CloneNotSupportedException} will be thrown. - * - * @return - * - * @throws java.lang.CloneNotSupportedException - */ - public Graph duplicate() throws CloneNotSupportedException; - - /** - * Returns all the node labels of this graph. - * - * @return a {@link Collection} of integers representing node labels. - */ - public Collection getLabels(); - - /** - * Returns if the graph is a directed graph or not. - * - * @return true if the graph is a directed graph, false if otherwise. - */ - public boolean isDirected(); - - /** - * Returns if the graph is weighted or not. - * - * @return true if the graph is weighted, false if otherwise. - */ - public boolean isWeighted(); - - /** - * Returns true wether u and v are adjacent vertex in the graph. - * - * @param u - * @param v - * - * @return - */ - public boolean isVertexAdjacent(int u, int v); - - /** - * Returns a new {@link Iterator} for this graph. Order of iteration is not guaranteed, it may be insertion order or - * BSF or DSF. - * - * @return a new {@link Iterator} - */ - @Override - public Iterator iterator(); - - /** - * Returns a new {@link GraphIterator} for this node in the graph. Order of iteration is not guaranteed, commonly it - * will be a random access iterator, but this is implementation dependent. This method takes as a parameter the - * label of a particular node. - * - * @param v - * - * @return a new {@link GraphIterator} - */ - public GraphIterator iterator(int v); - - /** - * Registers an {@link EdgeFactory} instance to this class. This allows to vary the behavior of the graph as long as - * {@link Edge} creation refers. - * - * @param factory - */ - public void registerEdgeFactory(EdgeFactory factory); - - /** - * Removes a node from the graph. May throw a {@link IllegalArgumentException} if the node is not present in the - * graph. - * - * @param node the node to be removed. - * - * @return the value of the removed node. - */ - public T remove(Node node); - - /** - * Removes a node from the graph. - * - * @see Graph#remove(cu.edu.cujae.graphy.core.Node) - * @param u the node to be removed - * - * @return the value of the removed node - */ - public T remove(int u); - - /** - * Returns the count of nodes in the graph. - * - * @return - */ - public int size(); - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core; + +import cu.edu.cujae.graphy.core.iterators.GraphIterator; +import java.util.Collection; +import java.util.Iterator; + +/** + * The Graph interface represents a graph as an abstract + * data structure.The graph does not make a distinction with the data + * type it holds, it just presents an abstract model of a graph. + * + * @author Javier Marrero + * @param + */ +public interface Graph extends Iterable +{ + + /** + * Adds a new node to this graph with the specified index. + * + * @param label + * @param data + * + * @return a truth value representing wether insertion was successful. + */ + public boolean add(int label, T data); + + /** + * Adds a new node to this graph with a default allocated index. + * + * @param data + * + * @return a truth value representing wether insertion was successful. + */ + public boolean add(T data); + + /** + * Returns a BFS iterator to the selected node. + * + * @param node + * @param includeDisconnected + * + * @return a {@link Iterator} instance that is a BFS iterator. + */ + public Iterator breadthFirstSearchIterator(Node node, boolean includeDisconnected); + + /** + * The same as {@link cu.edu.cujae.graphy.core.Graph#breadthFirstSearchIterator(cu.edu.cujae.graphy.core.Node) } but + * with the integer label of the node. + * + * @param includeDisconnected + * + * @see Graph#breadthFirstSearchIterator(cu.edu.cujae.graphy.core.Node) + * @param v + * + * @return a {@link Iterator} instance. + */ + public Iterator breadthFirstSearchIterator(int v, boolean includeDisconnected); + + /** + * Returns a BFS iterator to a random node in the graph. + * + * @param includeDisconnected + * + * @return a {@link Iterator} + */ + public Iterator breadthFirstSearchIterator(boolean includeDisconnected); + + /** + * Connects two nodes in this graph. This method should return true if the connection was successful and false + * otherwise. The two input parameters are the labels of the nodes within the graph. + * + * @param u + * @param v + * + * @return + */ + public boolean connect(int u, int v); + + /** + * Connects two nodes within the graph. This version of the method uses the nodes directly. + * + * @param u + * @param v + * + * @return + */ + public boolean connect(Node u, Node v); + + /** + * Generates an iterator that performs a depth first search.Depth first traversal for a graph is similar to depth + * first traversal of a tree, the only catch being that, unlike trees, graphs may contain cycles (a node may be + * visited twice). This iterator avoids processing a node more than once. A graph may have more than one DFS + * traversal. + *

+ * Depth-first search is an algorithm for traversing or searching a graph. The algorithm starts at the root node + * (some arbitrary node in this case, passed as a parameter) and explores as far as possible along each branch + * before backtracking. + *

+ * The basic idea is to start from the root or any arbitrary node, and move to the next adjacent unmarked node. + * + * @param start + * @param includeDisconnected + * + * @return a new {@link Iterator} + */ + public Iterator depthFirstSearchIterator(Node start, boolean includeDisconnected); + + /** + * @param includeDisconnected + * + * @see Graph#depthFirstSearchIterator(cu.edu.cujae.graphy.core.Node) + * + * @param v the label of the node. + * + * @return + */ + public Iterator depthFirstSearchIterator(int v, boolean includeDisconnected); + + /** + * Generates an iterator that performs a depth first search, grabbing a random node as the root. + * + * @param includeDisconnected + * + * @see Graph#depthFirstSearchIterator(cu.edu.cujae.graphy.core.Node, boolean) + * @return a new {@link Iterator} + */ + public Iterator depthFirstSearchIterator(boolean includeDisconnected); + + /** + * This method should be, at some extent, similar to the Java cloning mechanism in that returns a deep copy of this + * object.The returned graph is not a view of this graph but two independent objects. Changes are not guaranteed + * to persists across clone instances as they don't share data. + *

+ * While the two graphs does not share any internal representation, they both point to the same data, so any + * data manipulation will be seen in the original graph. If deep cloning of the internal data is desired, + * perform a manual copy or rather use the utility methods provided by the class Graphs. + *

+ * If by any means the duplication cannot be made, a {@link CloneNotSupportedException} will be thrown. + * + * @return + * + * @throws java.lang.CloneNotSupportedException + */ + public Graph duplicate() throws CloneNotSupportedException; + + /** + * Returns all the node labels of this graph. + * + * @return a {@link Collection} of integers representing node labels. + */ + public Collection getLabels(); + + /** + * Returns if the graph is a directed graph or not. + * + * @return true if the graph is a directed graph, false if otherwise. + */ + public boolean isDirected(); + + /** + * Returns if the graph is weighted or not. + * + * @return true if the graph is weighted, false if otherwise. + */ + public boolean isWeighted(); + + /** + * Returns true wether u and v are adjacent vertex in the graph. + * + * @param u + * @param v + * + * @return + */ + public boolean isVertexAdjacent(int u, int v); + + /** + * Returns a new {@link Iterator} for this graph. Order of iteration is not guaranteed, it may be insertion order or + * BSF or DSF. + * + * @return a new {@link Iterator} + */ + @Override + public Iterator iterator(); + + /** + * Returns a new {@link GraphIterator} for this node in the graph. Order of iteration is not guaranteed, commonly it + * will be a random access iterator, but this is implementation dependent. This method takes as a parameter the + * label of a particular node. + * + * @param v + * + * @return a new {@link GraphIterator} + */ + public GraphIterator iterator(int v); + + /** + * Registers an {@link EdgeFactory} instance to this class. This allows to vary the behavior of the graph as long as + * {@link Edge} creation refers. + * + * @param factory + */ + public void registerEdgeFactory(EdgeFactory factory); + + /** + * Removes a node from the graph. May throw a {@link IllegalArgumentException} if the node is not present in the + * graph. + * + * @param node the node to be removed. + * + * @return the value of the removed node. + */ + public T remove(Node node); + + /** + * Removes a node from the graph. + * + * @see Graph#remove(cu.edu.cujae.graphy.core.Node) + * @param u the node to be removed + * + * @return the value of the removed node + */ + public T remove(int u); + + /** + * Returns the count of nodes in the graph. + * + * @return + */ + public int size(); + +} diff --git a/src/cu/edu/cujae/graphy/core/Weight.java b/src/cu/edu/cujae/graphy/core/Weight.java index 7fd6112..e159ba2 100644 --- a/src/cu/edu/cujae/graphy/core/Weight.java +++ b/src/cu/edu/cujae/graphy/core/Weight.java @@ -1,49 +1,49 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core; - -/** - * This interface is used to represents weights in a graph.It is mostly a wrapper over the {@link Comparable} - * interface. - * - * @author Javier Marrero - * @param - */ -public interface Weight extends Comparable, Cloneable -{ - - /** - * {@inheritDoc } - */ - public Object clone() throws CloneNotSupportedException; - - /** - * Returns the actual value of the weight. - * - * @return the actual value of the weight. - */ - public T getValue(); - - /** - * Sets the actual value of the weight object. - * - * @param value - */ - public void setValue(T value); -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core; + +/** + * This interface is used to represents weights in a graph.It is mostly a wrapper over the {@link Comparable} + * interface. + * + * @author Javier Marrero + * @param + */ +public interface Weight extends Comparable, Cloneable +{ + + /** + * {@inheritDoc } + */ + public Object clone() throws CloneNotSupportedException; + + /** + * Returns the actual value of the weight. + * + * @return the actual value of the weight. + */ + public T getValue(); + + /** + * Sets the actual value of the weight object. + * + * @param value + */ + public void setValue(T value); +} diff --git a/src/cu/edu/cujae/graphy/core/abstractions/AbstractEdge.java b/src/cu/edu/cujae/graphy/core/abstractions/AbstractEdge.java index 223635f..acde7ca 100644 --- a/src/cu/edu/cujae/graphy/core/abstractions/AbstractEdge.java +++ b/src/cu/edu/cujae/graphy/core/abstractions/AbstractEdge.java @@ -1,180 +1,180 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.abstractions; - -import cu.edu.cujae.graphy.core.Edge; -import cu.edu.cujae.graphy.core.Node; -import cu.edu.cujae.graphy.core.Weight; - -/** - * This class simplifies the construction of {@link Edge} objects, by providing a bridge to common functionality. - * - * @author Javier Marrero - */ -public abstract class AbstractEdge implements Edge -{ - - protected boolean directed; - protected Node finish; - protected Object label; - protected Node start; - protected Weight weight; - - /** - * Construct a new abstract edge from a set of initial parameters. - * - * @param label - * @param start - * @param finish - * @param weight - * @param directed - */ - protected AbstractEdge(Object label, Node start, Node finish, Weight weight, boolean directed) - { - this.label = label; - this.directed = directed; - this.finish = finish; - this.start = start; - this.weight = weight; - } - - /** - * Two edges are considered equals if and only if their start nodes match and their final nodes match too. - * In the case that the edge is not directed, the correspondence may be given regardless of the order of comparison; - * this meaning that: (u, v) == (v, u). - * - * @param obj - * - * @return a boolean value telling wether the two edges are equal or not. - */ - @Override - public boolean equals(Object obj) - { - if (obj instanceof Edge) - { - if (isDirected()) - { - return (getStartNode().equals(((Edge) obj).getStartNode())) - && (getFinalNode().equals(((Edge) obj).getFinalNode())); - } - else - { - Edge rhs = (Edge) obj; - return (getStartNode().equals(rhs.getStartNode()) || getStartNode().equals(rhs.getFinalNode())) - && (getFinalNode().equals(rhs.getStartNode()) || getFinalNode(). - equals(rhs.getFinalNode())); - } - } - throw new IllegalArgumentException("attempted to compare an edge to something that is not an edge."); - } - - /** - * {@inheritDoc} - */ - @Override - public Node getFinalNode() - { - return finish; - } - - /** - * {@inheritDoc} - */ - @Override - public Object getLabel() - { - return label; - } - - /** - * {@inheritDoc} - */ - @Override - public Node getStartNode() - { - return start; - } - - /** - * {@inheritDoc} - */ - @Override - public Weight getWeight() - { - return weight; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isDirected() - { - return directed; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isLabeled() - { - return label != null; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isWeighted() - { - return weight != null; - } - - /** - * {@inheritDoc} - */ - @Override - public void reverseApparentDirection() - { - Node temp = start; - this.start = finish; - this.finish = temp; - } - - /** - * {@inheritDoc} - */ - @Override - public void setLabel(Object label) - { - this.label = label; - } - - /** - * {@inheritDoc} - */ - @Override - public void setWeight( - Weight weight) - { - this.weight = weight; - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.abstractions; + +import cu.edu.cujae.graphy.core.Edge; +import cu.edu.cujae.graphy.core.Node; +import cu.edu.cujae.graphy.core.Weight; + +/** + * This class simplifies the construction of {@link Edge} objects, by providing a bridge to common functionality. + * + * @author Javier Marrero + */ +public abstract class AbstractEdge implements Edge +{ + + protected boolean directed; + protected Node finish; + protected Object label; + protected Node start; + protected Weight weight; + + /** + * Construct a new abstract edge from a set of initial parameters. + * + * @param label + * @param start + * @param finish + * @param weight + * @param directed + */ + protected AbstractEdge(Object label, Node start, Node finish, Weight weight, boolean directed) + { + this.label = label; + this.directed = directed; + this.finish = finish; + this.start = start; + this.weight = weight; + } + + /** + * Two edges are considered equals if and only if their start nodes match and their final nodes match too. + * In the case that the edge is not directed, the correspondence may be given regardless of the order of comparison; + * this meaning that: (u, v) == (v, u). + * + * @param obj + * + * @return a boolean value telling wether the two edges are equal or not. + */ + @Override + public boolean equals(Object obj) + { + if (obj instanceof Edge) + { + if (isDirected()) + { + return (getStartNode().equals(((Edge) obj).getStartNode())) + && (getFinalNode().equals(((Edge) obj).getFinalNode())); + } + else + { + Edge rhs = (Edge) obj; + return (getStartNode().equals(rhs.getStartNode()) || getStartNode().equals(rhs.getFinalNode())) + && (getFinalNode().equals(rhs.getStartNode()) || getFinalNode(). + equals(rhs.getFinalNode())); + } + } + throw new IllegalArgumentException("attempted to compare an edge to something that is not an edge."); + } + + /** + * {@inheritDoc} + */ + @Override + public Node getFinalNode() + { + return finish; + } + + /** + * {@inheritDoc} + */ + @Override + public Object getLabel() + { + return label; + } + + /** + * {@inheritDoc} + */ + @Override + public Node getStartNode() + { + return start; + } + + /** + * {@inheritDoc} + */ + @Override + public Weight getWeight() + { + return weight; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isDirected() + { + return directed; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isLabeled() + { + return label != null; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isWeighted() + { + return weight != null; + } + + /** + * {@inheritDoc} + */ + @Override + public void reverseApparentDirection() + { + Node temp = start; + this.start = finish; + this.finish = temp; + } + + /** + * {@inheritDoc} + */ + @Override + public void setLabel(Object label) + { + this.label = label; + } + + /** + * {@inheritDoc} + */ + @Override + public void setWeight( + Weight weight) + { + this.weight = weight; + } + +} diff --git a/src/cu/edu/cujae/graphy/core/abstractions/AbstractGraph.java b/src/cu/edu/cujae/graphy/core/abstractions/AbstractGraph.java index 0be1bd4..9d253fb 100644 --- a/src/cu/edu/cujae/graphy/core/abstractions/AbstractGraph.java +++ b/src/cu/edu/cujae/graphy/core/abstractions/AbstractGraph.java @@ -1,535 +1,535 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.abstractions; - -import cu.edu.cujae.graphy.core.Edge; -import cu.edu.cujae.graphy.core.EdgeFactory; -import cu.edu.cujae.graphy.core.Graph; -import cu.edu.cujae.graphy.core.Node; -import cu.edu.cujae.graphy.core.Weight; -import cu.edu.cujae.graphy.core.exceptions.InvalidOperationException; -import cu.edu.cujae.graphy.core.iterators.AbstractGraphIterator; -import cu.edu.cujae.graphy.core.iterators.GraphIterator; -import java.util.*; - -/** - * This class eases the implementation of the {@link Graph} interface by offering some default implementations for - * commonly used methods. However, any required specialization may be performed by descendant classes. - *

- * - * @see Graph - * - * @author Javier Marrero - * @param - */ -public abstract class AbstractGraph implements Graph -{ - - private boolean directed; - - private class RandomAccessIterator extends AbstractGraphIterator implements GraphIterator - { - - public RandomAccessIterator(Graph graph, Node node) - { - super(graph, node); - } - - @Override - public T back(Node target) - { - T result = getCurrent().get(); - setCurrent(target); - return result; - } - - @Override - public boolean hasNext() - { - return !getEdgesDepartingSelf().isEmpty(); - } - - @Override - public T next(Node target) - { - T result = getCurrent().get(); - setCurrent(target); - return result; - } - - @Override - public T next(int u) - { - return next(findNodeByLabel(u)); - } - - @Override - @SuppressWarnings ("unchecked") - public T next() - { - Iterator children = getEdgesDepartingSelf().iterator(); - Node target = children.next().getFinalNode(); - while (target.equals(getCurrent())) - { - target = children.next().getFinalNode(); - } - return next((Node) target); - } - - } - - private class DepthFirstSearchIterator extends AbstractGraphIterator implements GraphIterator - { - - private final ListIterator> iter; - private final List> dfsList; - - public DepthFirstSearchIterator(Graph graph, Node start, boolean includeDisconnected) - { - super(graph, start); - - // Create the list - dfsList = new LinkedList<>(); - - // Populate the list - Set visited = new HashSet<>(); - walk(start, visited); - - // Walk and add disconnected vertices - if (includeDisconnected) - { - for (Node node : getNodes()) - { - if (!visited.contains(node.getLabel())) - { - dfsList.add(node); - } - } - } - - // This was a test! - // System.out.println(dfsList); - // Create the iterator - iter = dfsList.listIterator(); - } - - @Override - public T back() - { - T data = getCurrent().get(); - setCurrent(iter.previous()); - return data; - } - - @Override - public T back(Node target) - { - throw new InvalidOperationException("This is not a random access iterator."); - } - - @Override - public boolean hasNext() - { - return iter.hasNext(); - } - - @Override - public T next() - { - /* Next node */ - setCurrent(iter.next()); - - /* Return the data within the node */ - return getCurrent().get(); - } - - private void walk(Node v, Set visited) - { - // Mark the current node as visited - visited.add(v.getLabel()); - - // Add the node to the list - dfsList.add(v); - - // Recur for all the vertices adjacent to this vertex - Iterator edges = v.getEdgesDepartingSelf().iterator(); - while (edges.hasNext()) - { - @SuppressWarnings ("unchecked") - Node n = (Node) edges.next().getFinalNode(); - if (!visited.contains(n.getLabel())) - { - walk(n, visited); - } - } - } - - } - - private class BreadthFirstSearchIterator extends AbstractGraphIterator implements GraphIterator - { - - private final ListIterator> iter; - private final List> bfsList; - - public BreadthFirstSearchIterator(Graph graph, Node start, boolean includeDisconnected) - { - super(graph, start); - - /* Create the list and populate it */ - bfsList = new LinkedList<>(); - - /* Populate the list */ - Set visited = new TreeSet<>(); - Queue> queue = new LinkedList<>(); - - // Insert the starting vertex - queue.add(start); - - // Initialize the visited set and mark the starting vertex as visited - visited.add(start.getLabel()); - - while (!queue.isEmpty()) - { - Node s = queue.poll(); - bfsList.add(s); - - // Get all adjacent vertices of the dequeued vertex s - // if an adjacent has not been visited, then mark it visited - // and enqueue it - Iterator i = s.getEdgesDepartingSelf().iterator(); - while (i.hasNext()) - { - @SuppressWarnings ("unchecked") - Node n = (Node) i.next().getFinalNode(); - if (!visited.contains(n.getLabel())) - { - visited.add(n.getLabel()); - queue.add(n); - } - } - } - - // Add the disconnected nodes - if (includeDisconnected) - { - for (Node node : getNodes()) - { - if (!visited.contains(node.getLabel())) - { - bfsList.add(node); - } - } - } - - /* Create the iterator */ - iter = bfsList.listIterator(); - } - - @Override - public T back(Node target) - { - throw new InvalidOperationException("This is not a random access iterator."); - } - - @Override - public T back() - { - T data = getCurrent().get(); - setCurrent(iter.previous()); - return data; - } - - @Override - public boolean hasNext() - { - return iter.hasNext(); - } - - @Override - public T next() - { - setCurrent(iter.next()); - return getCurrent().get(); - } - - } - - private final Set allocatedLabels; - private EdgeFactory edgeFactory; - private int lastAllocated; - - /** - * Default constructor for abstract graphs. - * - * @param directed - */ - protected AbstractGraph(boolean directed) - { - this.allocatedLabels = new TreeSet<>(); - this.directed = directed; - this.lastAllocated = 0; - } - - protected abstract boolean addNode(Node node); - - /** - * {@inheritDoc} - */ - @Override - public boolean add(T data) - { - return add(allocateLabel(), data); - } - - /** - * Internally allocates a label for a node, and handles conflicts. - * - * @return an integer representing the next allocatable label. - */ - protected int allocateLabel() - { - int result = lastAllocated++; - while (allocatedLabels.contains(result)) - { - result = lastAllocated++; - } - allocatedLabels.add(result); - return result; - } - - /** - * {@inheritDoc } - */ - @Override - public Iterator breadthFirstSearchIterator(boolean includeDisconnected) - { - return breadthFirstSearchIterator(getNodes().iterator().next(), includeDisconnected); - } - - /** - * {@inheritDoc } - */ - @Override - public Iterator breadthFirstSearchIterator(Node node, boolean includeDisconnected) - { - return new BreadthFirstSearchIterator(this, node, includeDisconnected); - } - - /** - * {@inheritDoc } - */ - @Override - public Iterator breadthFirstSearchIterator(int v, boolean includeDisconnected) - { - return breadthFirstSearchIterator(findNodeByLabel(v), includeDisconnected); - } - - /** - * {@inheritDoc } - */ - @Override - public boolean connect(int u, int v) - { - return connect(findNodeByLabel(u), findNodeByLabel(v)); - } - - /** - * {@inheritDoc } - */ - @Override - public boolean connect(Node u, Node v) - { - return u.addEdge(getEdgeFactory().build(u, v)); - } - - /** - * De-allocates a label and makes it available for use. - * - * @param label - */ - protected void deallocateLabel(int label) - { - allocatedLabels.remove(label); - } - - @SuppressWarnings ("unchecked") - protected Collection> duplicateInternalNodes() throws CloneNotSupportedException - { - // For each node, clone it - Map> clonedNodes = new HashMap<>(size()); - for (Node node : getNodes()) - { - clonedNodes.put(node.getLabel(), (Node) node.clone()); - } - - // Now every node is cloned - // Clone the edges and connect the nodes - for (Node node : getNodes()) - { - for (Edge edge : node.getEdgesDepartingSelf()) - { - Weight w = edge.getWeight(); - if (w != null) - { - w = (Weight) edge.getWeight().clone(); - } - - Edge clonedEdge = getEdgeFactory().build(edge.getLabel(), - clonedNodes.get(edge.getStartNode().getLabel()), - clonedNodes.get(edge.getFinalNode().getLabel()), - w); - clonedNodes.get(node.getLabel()).addEdge(clonedEdge); - } - } - - return clonedNodes.values(); - } - - /** - * {@inheritDoc } - */ - @Override - public Iterator depthFirstSearchIterator(Node start, boolean includeDisconnected) - { - return new DepthFirstSearchIterator(this, start, includeDisconnected); - } - - /** - * {@inheritDoc } - */ - @Override - public Iterator depthFirstSearchIterator(int v, boolean includeDisconnected) - { - return new DepthFirstSearchIterator(this, findNodeByLabel(v), includeDisconnected); - } - - /** - * {@inheritDoc } - */ - @Override - public Iterator depthFirstSearchIterator(boolean includeDisconnected) - { - return new DepthFirstSearchIterator(this, getNodes().iterator().next(), includeDisconnected); - } - - /** - * Returns a collection holding all the nodes within this graph. - * - * @return a {@link Collection} of {@link Node} - */ - protected abstract Collection> getNodes(); - - /** - * This abstract method should return a node with the identifier passed as argument. If the node is not present - * on the graph it is allowed to return null, or throw an {@link IllegalStateException}. - * - * @param label - * - * @return the found {@link Node}. - */ - public abstract Node findNodeByLabel(int label); - - /** - * {@inheritDoc} - */ - @Override - public boolean isDirected() - { - return directed; - } - - /** - * {@inheritDoc} - */ - @Override - public Iterator iterator() - { - return new RandomAccessIterator(this, getNodes().iterator().next()); - } - - /** - * {@inheritDoc } - */ - @Override - public GraphIterator iterator(int v) - { - return new RandomAccessIterator(this, findNodeByLabel(v)); - } - - /** - * Makes a graph directed. - */ - public void makeDirected() - { - setDirected(true); - } - - /** - * {@inheritDoc } - */ - @Override - public void registerEdgeFactory(EdgeFactory factory) - { - this.setEdgeFactory(factory); - } - - /** - * Prints this graph as a series of nodes with their corresponding connections. This shall return a string - * containing all of the graph's vertex in a human-readable format. - * - * @return - */ - @Override - public String toString() - { - StringBuilder builder = new StringBuilder("["); - for (Node node : getNodes()) - { - builder.append(node.toString()); - } - builder.append("]"); - return builder.toString(); - } - - /** - * @return the edgeFactory - */ - protected EdgeFactory getEdgeFactory() - { - return edgeFactory; - } - - /** - * @param edgeFactory the edgeFactory to set - */ - protected void setEdgeFactory(EdgeFactory edgeFactory) - { - this.edgeFactory = edgeFactory; - } - - /** - * @param directed the directed to set - */ - public void setDirected(boolean directed) - { - this.directed = directed; - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.abstractions; + +import cu.edu.cujae.graphy.core.Edge; +import cu.edu.cujae.graphy.core.EdgeFactory; +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.Node; +import cu.edu.cujae.graphy.core.Weight; +import cu.edu.cujae.graphy.core.exceptions.InvalidOperationException; +import cu.edu.cujae.graphy.core.iterators.AbstractGraphIterator; +import cu.edu.cujae.graphy.core.iterators.GraphIterator; +import java.util.*; + +/** + * This class eases the implementation of the {@link Graph} interface by offering some default implementations for + * commonly used methods. However, any required specialization may be performed by descendant classes. + *

+ * + * @see Graph + * + * @author Javier Marrero + * @param + */ +public abstract class AbstractGraph implements Graph +{ + + private boolean directed; + + private class RandomAccessIterator extends AbstractGraphIterator implements GraphIterator + { + + public RandomAccessIterator(Graph graph, Node node) + { + super(graph, node); + } + + @Override + public T back(Node target) + { + T result = getCurrent().get(); + setCurrent(target); + return result; + } + + @Override + public boolean hasNext() + { + return !getEdgesDepartingSelf().isEmpty(); + } + + @Override + public T next(Node target) + { + T result = getCurrent().get(); + setCurrent(target); + return result; + } + + @Override + public T next(int u) + { + return next(findNodeByLabel(u)); + } + + @Override + @SuppressWarnings ("unchecked") + public T next() + { + Iterator children = getEdgesDepartingSelf().iterator(); + Node target = children.next().getFinalNode(); + while (target.equals(getCurrent())) + { + target = children.next().getFinalNode(); + } + return next((Node) target); + } + + } + + private class DepthFirstSearchIterator extends AbstractGraphIterator implements GraphIterator + { + + private final ListIterator> iter; + private final List> dfsList; + + public DepthFirstSearchIterator(Graph graph, Node start, boolean includeDisconnected) + { + super(graph, start); + + // Create the list + dfsList = new LinkedList<>(); + + // Populate the list + Set visited = new HashSet<>(); + walk(start, visited); + + // Walk and add disconnected vertices + if (includeDisconnected) + { + for (Node node : getNodes()) + { + if (!visited.contains(node.getLabel())) + { + dfsList.add(node); + } + } + } + + // This was a test! + // System.out.println(dfsList); + // Create the iterator + iter = dfsList.listIterator(); + } + + @Override + public T back() + { + T data = getCurrent().get(); + setCurrent(iter.previous()); + return data; + } + + @Override + public T back(Node target) + { + throw new InvalidOperationException("This is not a random access iterator."); + } + + @Override + public boolean hasNext() + { + return iter.hasNext(); + } + + @Override + public T next() + { + /* Next node */ + setCurrent(iter.next()); + + /* Return the data within the node */ + return getCurrent().get(); + } + + private void walk(Node v, Set visited) + { + // Mark the current node as visited + visited.add(v.getLabel()); + + // Add the node to the list + dfsList.add(v); + + // Recur for all the vertices adjacent to this vertex + Iterator edges = v.getEdgesDepartingSelf().iterator(); + while (edges.hasNext()) + { + @SuppressWarnings ("unchecked") + Node n = (Node) edges.next().getFinalNode(); + if (!visited.contains(n.getLabel())) + { + walk(n, visited); + } + } + } + + } + + private class BreadthFirstSearchIterator extends AbstractGraphIterator implements GraphIterator + { + + private final ListIterator> iter; + private final List> bfsList; + + public BreadthFirstSearchIterator(Graph graph, Node start, boolean includeDisconnected) + { + super(graph, start); + + /* Create the list and populate it */ + bfsList = new LinkedList<>(); + + /* Populate the list */ + Set visited = new TreeSet<>(); + Queue> queue = new LinkedList<>(); + + // Insert the starting vertex + queue.add(start); + + // Initialize the visited set and mark the starting vertex as visited + visited.add(start.getLabel()); + + while (!queue.isEmpty()) + { + Node s = queue.poll(); + bfsList.add(s); + + // Get all adjacent vertices of the dequeued vertex s + // if an adjacent has not been visited, then mark it visited + // and enqueue it + Iterator i = s.getEdgesDepartingSelf().iterator(); + while (i.hasNext()) + { + @SuppressWarnings ("unchecked") + Node n = (Node) i.next().getFinalNode(); + if (!visited.contains(n.getLabel())) + { + visited.add(n.getLabel()); + queue.add(n); + } + } + } + + // Add the disconnected nodes + if (includeDisconnected) + { + for (Node node : getNodes()) + { + if (!visited.contains(node.getLabel())) + { + bfsList.add(node); + } + } + } + + /* Create the iterator */ + iter = bfsList.listIterator(); + } + + @Override + public T back(Node target) + { + throw new InvalidOperationException("This is not a random access iterator."); + } + + @Override + public T back() + { + T data = getCurrent().get(); + setCurrent(iter.previous()); + return data; + } + + @Override + public boolean hasNext() + { + return iter.hasNext(); + } + + @Override + public T next() + { + setCurrent(iter.next()); + return getCurrent().get(); + } + + } + + private final Set allocatedLabels; + private EdgeFactory edgeFactory; + private int lastAllocated; + + /** + * Default constructor for abstract graphs. + * + * @param directed + */ + protected AbstractGraph(boolean directed) + { + this.allocatedLabels = new TreeSet<>(); + this.directed = directed; + this.lastAllocated = 0; + } + + protected abstract boolean addNode(Node node); + + /** + * {@inheritDoc} + */ + @Override + public boolean add(T data) + { + return add(allocateLabel(), data); + } + + /** + * Internally allocates a label for a node, and handles conflicts. + * + * @return an integer representing the next allocatable label. + */ + protected int allocateLabel() + { + int result = lastAllocated++; + while (allocatedLabels.contains(result)) + { + result = lastAllocated++; + } + allocatedLabels.add(result); + return result; + } + + /** + * {@inheritDoc } + */ + @Override + public Iterator breadthFirstSearchIterator(boolean includeDisconnected) + { + return breadthFirstSearchIterator(getNodes().iterator().next(), includeDisconnected); + } + + /** + * {@inheritDoc } + */ + @Override + public Iterator breadthFirstSearchIterator(Node node, boolean includeDisconnected) + { + return new BreadthFirstSearchIterator(this, node, includeDisconnected); + } + + /** + * {@inheritDoc } + */ + @Override + public Iterator breadthFirstSearchIterator(int v, boolean includeDisconnected) + { + return breadthFirstSearchIterator(findNodeByLabel(v), includeDisconnected); + } + + /** + * {@inheritDoc } + */ + @Override + public boolean connect(int u, int v) + { + return connect(findNodeByLabel(u), findNodeByLabel(v)); + } + + /** + * {@inheritDoc } + */ + @Override + public boolean connect(Node u, Node v) + { + return u.addEdge(getEdgeFactory().build(u, v)); + } + + /** + * De-allocates a label and makes it available for use. + * + * @param label + */ + protected void deallocateLabel(int label) + { + allocatedLabels.remove(label); + } + + @SuppressWarnings ("unchecked") + protected Collection> duplicateInternalNodes() throws CloneNotSupportedException + { + // For each node, clone it + Map> clonedNodes = new HashMap<>(size()); + for (Node node : getNodes()) + { + clonedNodes.put(node.getLabel(), (Node) node.clone()); + } + + // Now every node is cloned + // Clone the edges and connect the nodes + for (Node node : getNodes()) + { + for (Edge edge : node.getEdgesDepartingSelf()) + { + Weight w = edge.getWeight(); + if (w != null) + { + w = (Weight) edge.getWeight().clone(); + } + + Edge clonedEdge = getEdgeFactory().build(edge.getLabel(), + clonedNodes.get(edge.getStartNode().getLabel()), + clonedNodes.get(edge.getFinalNode().getLabel()), + w); + clonedNodes.get(node.getLabel()).addEdge(clonedEdge); + } + } + + return clonedNodes.values(); + } + + /** + * {@inheritDoc } + */ + @Override + public Iterator depthFirstSearchIterator(Node start, boolean includeDisconnected) + { + return new DepthFirstSearchIterator(this, start, includeDisconnected); + } + + /** + * {@inheritDoc } + */ + @Override + public Iterator depthFirstSearchIterator(int v, boolean includeDisconnected) + { + return new DepthFirstSearchIterator(this, findNodeByLabel(v), includeDisconnected); + } + + /** + * {@inheritDoc } + */ + @Override + public Iterator depthFirstSearchIterator(boolean includeDisconnected) + { + return new DepthFirstSearchIterator(this, getNodes().iterator().next(), includeDisconnected); + } + + /** + * Returns a collection holding all the nodes within this graph. + * + * @return a {@link Collection} of {@link Node} + */ + protected abstract Collection> getNodes(); + + /** + * This abstract method should return a node with the identifier passed as argument. If the node is not present + * on the graph it is allowed to return null, or throw an {@link IllegalStateException}. + * + * @param label + * + * @return the found {@link Node}. + */ + public abstract Node findNodeByLabel(int label); + + /** + * {@inheritDoc} + */ + @Override + public boolean isDirected() + { + return directed; + } + + /** + * {@inheritDoc} + */ + @Override + public Iterator iterator() + { + return new RandomAccessIterator(this, getNodes().iterator().next()); + } + + /** + * {@inheritDoc } + */ + @Override + public GraphIterator iterator(int v) + { + return new RandomAccessIterator(this, findNodeByLabel(v)); + } + + /** + * Makes a graph directed. + */ + public void makeDirected() + { + setDirected(true); + } + + /** + * {@inheritDoc } + */ + @Override + public void registerEdgeFactory(EdgeFactory factory) + { + this.setEdgeFactory(factory); + } + + /** + * Prints this graph as a series of nodes with their corresponding connections. This shall return a string + * containing all of the graph's vertex in a human-readable format. + * + * @return + */ + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("["); + for (Node node : getNodes()) + { + builder.append(node.toString()); + } + builder.append("]"); + return builder.toString(); + } + + /** + * @return the edgeFactory + */ + protected EdgeFactory getEdgeFactory() + { + return edgeFactory; + } + + /** + * @param edgeFactory the edgeFactory to set + */ + protected void setEdgeFactory(EdgeFactory edgeFactory) + { + this.edgeFactory = edgeFactory; + } + + /** + * @param directed the directed to set + */ + public void setDirected(boolean directed) + { + this.directed = directed; + } + +} diff --git a/src/cu/edu/cujae/graphy/core/abstractions/AbstractWeight.java b/src/cu/edu/cujae/graphy/core/abstractions/AbstractWeight.java index 6ff2791..32c87f3 100644 --- a/src/cu/edu/cujae/graphy/core/abstractions/AbstractWeight.java +++ b/src/cu/edu/cujae/graphy/core/abstractions/AbstractWeight.java @@ -1,97 +1,97 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.abstractions; - -import cu.edu.cujae.graphy.core.Weight; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * Default abstract {@link Weight} implementation. - * - * @author Javier Marrero - * @param - */ -public abstract class AbstractWeight implements Weight -{ - - private T value; - - public AbstractWeight(T value) - { - this.value = value; - } - - @Override - public Object clone() throws CloneNotSupportedException - { - @SuppressWarnings ("unchecked") - Weight weight = (Weight) super.clone(); - if (weight.getValue() instanceof Cloneable) - { - try - { - Method cloneMethod = Object.class.getDeclaredMethod("clone", Void.class); - cloneMethod.setAccessible(true); - - @SuppressWarnings ("unchecked") - T weightClonedData = (T) cloneMethod.invoke(value); - - weight.setValue(weightClonedData); - } - catch (NoSuchMethodException | SecurityException ex) - { - throw new CloneNotSupportedException("could not find the clone method via reflection."); - } - catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) - { - throw new CloneNotSupportedException("unable to invoke clone method for target"); - } - } - return weight; - } - - /** - * {@inheritDoc } - */ - @Override - public T getValue() - { - return value; - } - - /** - * {@inheritDoc } - */ - @Override - public void setValue(T value) - { - this.value = value; - } - - /** - * {@inheritDoc } - */ - @Override - public String toString() - { - return value.toString(); - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.abstractions; + +import cu.edu.cujae.graphy.core.Weight; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Default abstract {@link Weight} implementation. + * + * @author Javier Marrero + * @param + */ +public abstract class AbstractWeight implements Weight +{ + + private T value; + + public AbstractWeight(T value) + { + this.value = value; + } + + @Override + public Object clone() throws CloneNotSupportedException + { + @SuppressWarnings ("unchecked") + Weight weight = (Weight) super.clone(); + if (weight.getValue() instanceof Cloneable) + { + try + { + Method cloneMethod = Object.class.getDeclaredMethod("clone", Void.class); + cloneMethod.setAccessible(true); + + @SuppressWarnings ("unchecked") + T weightClonedData = (T) cloneMethod.invoke(value); + + weight.setValue(weightClonedData); + } + catch (NoSuchMethodException | SecurityException ex) + { + throw new CloneNotSupportedException("could not find the clone method via reflection."); + } + catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) + { + throw new CloneNotSupportedException("unable to invoke clone method for target"); + } + } + return weight; + } + + /** + * {@inheritDoc } + */ + @Override + public T getValue() + { + return value; + } + + /** + * {@inheritDoc } + */ + @Override + public void setValue(T value) + { + this.value = value; + } + + /** + * {@inheritDoc } + */ + @Override + public String toString() + { + return value.toString(); + } + +} diff --git a/src/cu/edu/cujae/graphy/core/abstractions/AdjacencyListGraph.java b/src/cu/edu/cujae/graphy/core/abstractions/AdjacencyListGraph.java index daedf3b..fa4ff61 100644 --- a/src/cu/edu/cujae/graphy/core/abstractions/AdjacencyListGraph.java +++ b/src/cu/edu/cujae/graphy/core/abstractions/AdjacencyListGraph.java @@ -1,156 +1,156 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.abstractions; - -import cu.edu.cujae.graphy.core.Edge; -import cu.edu.cujae.graphy.core.Graph; -import cu.edu.cujae.graphy.core.Node; -import cu.edu.cujae.graphy.core.defaults.DefaultNode; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * An implementation of a graph using an adjacency list to keep track of the nodes. - * - * @author Javier Marrero - * @param - */ -public abstract class AdjacencyListGraph extends AbstractGraph implements Graph, Cloneable -{ - - private final Map> nodes; - - protected AdjacencyListGraph(boolean directed) - { - super(directed); - - nodes = new HashMap<>(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean add(int label, T data) - { - return nodes.putIfAbsent(label, new DefaultNode<>(label, data)) == null; - } - - @Override - protected boolean addNode(Node node) - { - return nodes.putIfAbsent(node.getLabel(), node) == null; - } - - /** - * {@inheritDoc } - */ - @Override - public Node findNodeByLabel(int label) - { - return nodes.get(label); - } - - /** - * {@inheritDoc } - */ - @Override - public Collection getLabels() - { - return nodes.keySet(); - } - - /** - * {@inheritDoc } - */ - @Override - protected Collection> getNodes() - { - return nodes.values(); - } - - /** - * {@inheritDoc } - */ - @Override - public boolean isVertexAdjacent(int u, int v) - { - return findNodeByLabel(u).isAdjacent(findNodeByLabel(v)); - } - - /** - * {@inheritDoc} - */ - @Override - public T remove(Node node) - { - if (!nodes.containsKey(node.getLabel())) - { - throw new IllegalArgumentException("The node to remove is not present in this graph."); - } - - // Remove all the edges from the graph that ends in or departs from this node - for (Edge edge : node.getEdgesDepartingSelf()) - { - node.removeEdge(edge); - } - - return node.get(); - } - - /** - * {@inheritDoc} - */ - @Override - public T remove(int u) - { - return remove(findNodeByLabel(u)); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() - { - StringBuilder builder = new StringBuilder("[\n"); - for (Iterator> it = nodes.values().iterator(); it.hasNext();) - { - Node node = it.next(); - builder.append(node.toString()); - if (it.hasNext()) - { - builder.append(",\n"); - } - } - return builder.append("\n]").toString(); - } - - /** - * {@inheritDoc } - */ - @Override - public int size() - { - return nodes.size(); - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.abstractions; + +import cu.edu.cujae.graphy.core.Edge; +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.Node; +import cu.edu.cujae.graphy.core.defaults.DefaultNode; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * An implementation of a graph using an adjacency list to keep track of the nodes. + * + * @author Javier Marrero + * @param + */ +public abstract class AdjacencyListGraph extends AbstractGraph implements Graph, Cloneable +{ + + private final Map> nodes; + + protected AdjacencyListGraph(boolean directed) + { + super(directed); + + nodes = new HashMap<>(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean add(int label, T data) + { + return nodes.putIfAbsent(label, new DefaultNode<>(label, data)) == null; + } + + @Override + protected boolean addNode(Node node) + { + return nodes.putIfAbsent(node.getLabel(), node) == null; + } + + /** + * {@inheritDoc } + */ + @Override + public Node findNodeByLabel(int label) + { + return nodes.get(label); + } + + /** + * {@inheritDoc } + */ + @Override + public Collection getLabels() + { + return nodes.keySet(); + } + + /** + * {@inheritDoc } + */ + @Override + protected Collection> getNodes() + { + return nodes.values(); + } + + /** + * {@inheritDoc } + */ + @Override + public boolean isVertexAdjacent(int u, int v) + { + return findNodeByLabel(u).isAdjacent(findNodeByLabel(v)); + } + + /** + * {@inheritDoc} + */ + @Override + public T remove(Node node) + { + if (!nodes.containsKey(node.getLabel())) + { + throw new IllegalArgumentException("The node to remove is not present in this graph."); + } + + // Remove all the edges from the graph that ends in or departs from this node + for (Edge edge : node.getEdgesDepartingSelf()) + { + node.removeEdge(edge); + } + + return node.get(); + } + + /** + * {@inheritDoc} + */ + @Override + public T remove(int u) + { + return remove(findNodeByLabel(u)); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("[\n"); + for (Iterator> it = nodes.values().iterator(); it.hasNext();) + { + Node node = it.next(); + builder.append(node.toString()); + if (it.hasNext()) + { + builder.append(",\n"); + } + } + return builder.append("\n]").toString(); + } + + /** + * {@inheritDoc } + */ + @Override + public int size() + { + return nodes.size(); + } + +} diff --git a/src/cu/edu/cujae/graphy/core/defaults/DefaultNode.java b/src/cu/edu/cujae/graphy/core/defaults/DefaultNode.java index f84d12c..42728e1 100644 --- a/src/cu/edu/cujae/graphy/core/defaults/DefaultNode.java +++ b/src/cu/edu/cujae/graphy/core/defaults/DefaultNode.java @@ -217,4 +217,4 @@ protected Map, Edge> getConnectionsToVertex() { return Collections.unmodifiableMap(connectionsToVertex); } -} +} \ No newline at end of file diff --git a/src/cu/edu/cujae/graphy/core/defaults/DefaultNotDirectedEdgeFactory.java b/src/cu/edu/cujae/graphy/core/defaults/DefaultNotDirectedEdgeFactory.java index 4663239..0013c45 100644 --- a/src/cu/edu/cujae/graphy/core/defaults/DefaultNotDirectedEdgeFactory.java +++ b/src/cu/edu/cujae/graphy/core/defaults/DefaultNotDirectedEdgeFactory.java @@ -1,24 +1,24 @@ -package cu.edu.cujae.graphy.core.defaults; - -import cu.edu.cujae.graphy.core.Edge; -import cu.edu.cujae.graphy.core.EdgeFactory; -import cu.edu.cujae.graphy.core.Node; -import cu.edu.cujae.graphy.core.Weight; -import cu.edu.cujae.graphy.core.abstractions.AbstractEdge; - -public class DefaultNotDirectedEdgeFactory extends DefaultEdgeFactory implements EdgeFactory -{ - - /** - * {@inheritDoc}} - */ - @Override - public Edge build(Object label, Node u, Node v, Weight w) - { - return new AbstractEdge(label, u, v, w, false) - { - - }; - } - -} +package cu.edu.cujae.graphy.core.defaults; + +import cu.edu.cujae.graphy.core.Edge; +import cu.edu.cujae.graphy.core.EdgeFactory; +import cu.edu.cujae.graphy.core.Node; +import cu.edu.cujae.graphy.core.Weight; +import cu.edu.cujae.graphy.core.abstractions.AbstractEdge; + +public class DefaultNotDirectedEdgeFactory extends DefaultEdgeFactory implements EdgeFactory +{ + + /** + * {@inheritDoc}} + */ + @Override + public Edge build(Object label, Node u, Node v, Weight w) + { + return new AbstractEdge(label, u, v, w, false) + { + + }; + } + +} diff --git a/src/cu/edu/cujae/graphy/core/defaults/DefaultSimpleGraph.java b/src/cu/edu/cujae/graphy/core/defaults/DefaultSimpleGraph.java index 9801d9b..eb4a134 100644 --- a/src/cu/edu/cujae/graphy/core/defaults/DefaultSimpleGraph.java +++ b/src/cu/edu/cujae/graphy/core/defaults/DefaultSimpleGraph.java @@ -1,74 +1,74 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.defaults; - -import cu.edu.cujae.graphy.core.Graph; -import cu.edu.cujae.graphy.core.Node; -import cu.edu.cujae.graphy.core.abstractions.AdjacencyListGraph; - -/** - * This is a default implementation of the {@link Graph} interface.It is a simple graph (not simple in the mathematical - * sense of a "simple graph", but in the sense of the most basic implementation you will find in this library). - * It does not aim to be the ultimate representation of a graph, but rather a default implementation that uncaring - * users may rely upon. - *

- * For more complex or more specific needs, the entire library is customizable via design patterns and the use of this - * library's API. - * - * @author Javier Marrero - * @param - */ -public class DefaultSimpleGraph extends AdjacencyListGraph implements Graph, Cloneable -{ - - public DefaultSimpleGraph() - { - super(false); - } - - public DefaultSimpleGraph(boolean directed) - { - super(directed); - } - - /** - * {@inheritDoc } - */ - @Override - public Graph duplicate() throws CloneNotSupportedException - { - DefaultSimpleGraph graph = new DefaultSimpleGraph<>(true); - // Clone all the nodes - for (Node node : duplicateInternalNodes()) - { - graph.addNode(node); - } - return graph; - } - - /** - * {@inheritDoc } - */ - @Override - public boolean isWeighted() - { - return false; - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.defaults; + +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.Node; +import cu.edu.cujae.graphy.core.abstractions.AdjacencyListGraph; + +/** + * This is a default implementation of the {@link Graph} interface.It is a simple graph (not simple in the mathematical + * sense of a "simple graph", but in the sense of the most basic implementation you will find in this library). + * It does not aim to be the ultimate representation of a graph, but rather a default implementation that uncaring + * users may rely upon. + *

+ * For more complex or more specific needs, the entire library is customizable via design patterns and the use of this + * library's API. + * + * @author Javier Marrero + * @param + */ +public class DefaultSimpleGraph extends AdjacencyListGraph implements Graph, Cloneable +{ + + public DefaultSimpleGraph() + { + super(false); + } + + public DefaultSimpleGraph(boolean directed) + { + super(directed); + } + + /** + * {@inheritDoc } + */ + @Override + public Graph duplicate() throws CloneNotSupportedException + { + DefaultSimpleGraph graph = new DefaultSimpleGraph<>(true); + // Clone all the nodes + for (Node node : duplicateInternalNodes()) + { + graph.addNode(node); + } + return graph; + } + + /** + * {@inheritDoc } + */ + @Override + public boolean isWeighted() + { + return false; + } + +} diff --git a/src/cu/edu/cujae/graphy/core/defaults/DefaultWeightedGraph.java b/src/cu/edu/cujae/graphy/core/defaults/DefaultWeightedGraph.java index 4db0310..f998aeb 100644 --- a/src/cu/edu/cujae/graphy/core/defaults/DefaultWeightedGraph.java +++ b/src/cu/edu/cujae/graphy/core/defaults/DefaultWeightedGraph.java @@ -1,85 +1,85 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.defaults; - -import cu.edu.cujae.graphy.core.Graph; -import cu.edu.cujae.graphy.core.Node; -import cu.edu.cujae.graphy.core.Weight; -import cu.edu.cujae.graphy.core.WeightedGraph; -import cu.edu.cujae.graphy.core.abstractions.AdjacencyListGraph; - -/** - * This is a default implementation of a {@link WeightedGraph}. - * - * @author Javier Marrero - * @param - */ -public class DefaultWeightedGraph extends AdjacencyListGraph implements WeightedGraph -{ - - public DefaultWeightedGraph() - { - super(false); - } - - public DefaultWeightedGraph(boolean directed) - { - super(directed); - } - - /** - * {@inheritDoc } - */ - @Override - public boolean connect(int u, int v, - Weight w) - { - return connect(findNodeByLabel(u), findNodeByLabel(v), w); - } - - /** - * {@inheritDoc } - */ - @Override - public boolean connect(Node u, Node v, Weight w) - { - return u.addEdge(getEdgeFactory().build(w, u, v, w)); - } - - @Override - public Graph duplicate() throws CloneNotSupportedException - { - DefaultWeightedGraph graph = new DefaultWeightedGraph<>(isDirected()); - for (Node node : duplicateInternalNodes()) - { - graph.addNode(node); - } - return graph; - } - - /** - * {@inheritDoc } - */ - @Override - public boolean isWeighted() - { - return true; - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.defaults; + +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.Node; +import cu.edu.cujae.graphy.core.Weight; +import cu.edu.cujae.graphy.core.WeightedGraph; +import cu.edu.cujae.graphy.core.abstractions.AdjacencyListGraph; + +/** + * This is a default implementation of a {@link WeightedGraph}. + * + * @author Javier Marrero + * @param + */ +public class DefaultWeightedGraph extends AdjacencyListGraph implements WeightedGraph +{ + + public DefaultWeightedGraph() + { + super(false); + } + + public DefaultWeightedGraph(boolean directed) + { + super(directed); + } + + /** + * {@inheritDoc } + */ + @Override + public boolean connect(int u, int v, + Weight w) + { + return connect(findNodeByLabel(u), findNodeByLabel(v), w); + } + + /** + * {@inheritDoc } + */ + @Override + public boolean connect(Node u, Node v, Weight w) + { + return u.addEdge(getEdgeFactory().build(w, u, v, w)); + } + + @Override + public Graph duplicate() throws CloneNotSupportedException + { + DefaultWeightedGraph graph = new DefaultWeightedGraph<>(isDirected()); + for (Node node : duplicateInternalNodes()) + { + graph.addNode(node); + } + return graph; + } + + /** + * {@inheritDoc } + */ + @Override + public boolean isWeighted() + { + return true; + } + +} diff --git a/src/cu/edu/cujae/graphy/core/exceptions/InvalidOperationException.java b/src/cu/edu/cujae/graphy/core/exceptions/InvalidOperationException.java index a1a7ab2..9938809 100644 --- a/src/cu/edu/cujae/graphy/core/exceptions/InvalidOperationException.java +++ b/src/cu/edu/cujae/graphy/core/exceptions/InvalidOperationException.java @@ -1,41 +1,41 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.exceptions; - -/** - * This is an exception class that is raised every time an invalid operation is performed on either a {@link Graph} or - * a {@link GraphIterator}. - * - * @author Javier Marrero - */ -public class InvalidOperationException extends RuntimeException -{ - - private static final long serialVersionUID = 2349393202055925741L; - - public InvalidOperationException() - { - this("Invalid operation"); - } - - public InvalidOperationException(String message) - { - super(message); - } -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.exceptions; + +/** + * This is an exception class that is raised every time an invalid operation is performed on either a {@link Graph} or + * a {@link GraphIterator}. + * + * @author Javier Marrero + */ +public class InvalidOperationException extends RuntimeException +{ + + private static final long serialVersionUID = 2349393202055925741L; + + public InvalidOperationException() + { + this("Invalid operation"); + } + + public InvalidOperationException(String message) + { + super(message); + } +} diff --git a/src/cu/edu/cujae/graphy/core/trees/AbstractTreeNode.java b/src/cu/edu/cujae/graphy/core/trees/AbstractTreeNode.java index 568c9cf..f5f9c2d 100644 --- a/src/cu/edu/cujae/graphy/core/trees/AbstractTreeNode.java +++ b/src/cu/edu/cujae/graphy/core/trees/AbstractTreeNode.java @@ -1,65 +1,65 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.trees; - -import cu.edu.cujae.graphy.core.TreeNode; - -/** - * Abstract implementation of the {@link TreeNode} interface. - * - * @author Javier Marrero - * @param - */ -public abstract class AbstractTreeNode implements TreeNode -{ - - private E data; - private final int label; - - public AbstractTreeNode(Object label, E data) - { - this.data = data; - this.label = label.hashCode(); - } - - @Override - public Object clone() throws CloneNotSupportedException - { - return super.clone(); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody - } - - @Override - public E get() - { - return data; - } - - @Override - public int getLabel() - { - return label; - } - - @Override - public void set(E data) - { - this.data = data; - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.trees; + +import cu.edu.cujae.graphy.core.TreeNode; + +/** + * Abstract implementation of the {@link TreeNode} interface. + * + * @author Javier Marrero + * @param + */ +public abstract class AbstractTreeNode implements TreeNode +{ + + private E data; + private final int label; + + public AbstractTreeNode(Object label, E data) + { + this.data = data; + this.label = label.hashCode(); + } + + @Override + public Object clone() throws CloneNotSupportedException + { + return super.clone(); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody + } + + @Override + public E get() + { + return data; + } + + @Override + public int getLabel() + { + return label; + } + + @Override + public void set(E data) + { + this.data = data; + } + +} diff --git a/src/cu/edu/cujae/graphy/core/trees/DefaultGeneralTree.java b/src/cu/edu/cujae/graphy/core/trees/DefaultGeneralTree.java index e913e9a..2cf69de 100644 --- a/src/cu/edu/cujae/graphy/core/trees/DefaultGeneralTree.java +++ b/src/cu/edu/cujae/graphy/core/trees/DefaultGeneralTree.java @@ -1,143 +1,143 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.trees; - -import cu.edu.cujae.graphy.core.Graph; -import cu.edu.cujae.graphy.core.Node; -import cu.edu.cujae.graphy.core.TreeNode; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * Default implementation of the {@link Tree} interface. - * - * @author Javier Marrero - * @param - */ -public class DefaultGeneralTree extends AbstractTree -{ - - private final Map> nodes; - private TreeNode root; - - public DefaultGeneralTree() - { - this.nodes = new HashMap<>(); - this.root = null; - } - - @Override - public boolean add(int label, E data) - { - TreeNode newNode = new DefaultGeneralTreeNode<>(label, data); - if (root == null) - { - root = newNode; - } - return nodes.put(label, newNode) == null; - } - - @Override - public boolean add(TreeNode parent, E data) - { - throw new UnsupportedOperationException("not supported yet!"); - } - - @Override - public Graph duplicate() throws CloneNotSupportedException - { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody - } - - @Override - public Node findNodeByLabel(int label) - { - return nodes.get(label); - } - - @Override - public Collection getLabels() - { - return nodes.keySet(); - } - - @Override - public TreeNode getRoot() - { - return root; - } - - @Override - public boolean isRoot(TreeNode node) - { - return root.equals(node); - } - - @Override - public boolean isVertexAdjacent(int u, int v) - { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody - } - - @Override - public boolean isWeighted() - { - ///TODO: Fixme - return false; - } - - @Override - public E remove(Node node) - { - if (nodes.containsKey(node.getLabel()) == false) - { - throw new IllegalArgumentException("Attempted to remove a node not belonging to this graph."); - } - - // Find the parent and remove the child node NODE - return node.get(); - } - - @Override - public E remove(int u) - { - return remove(findNodeByLabel(u)); - } - - @Override - public int size() - { - return nodes.size(); - } - - @Override - protected boolean addNode(Node node) - { - ///TODO: Fix this - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody - } - - @Override - protected Collection> getNodes() - { - return nodes.values(); - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.trees; + +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.Node; +import cu.edu.cujae.graphy.core.TreeNode; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * Default implementation of the {@link Tree} interface. + * + * @author Javier Marrero + * @param + */ +public class DefaultGeneralTree extends AbstractTree +{ + + private final Map> nodes; + private TreeNode root; + + public DefaultGeneralTree() + { + this.nodes = new HashMap<>(); + this.root = null; + } + + @Override + public boolean add(int label, E data) + { + TreeNode newNode = new DefaultGeneralTreeNode<>(label, data); + if (root == null) + { + root = newNode; + } + return nodes.put(label, newNode) == null; + } + + @Override + public boolean add(TreeNode parent, E data) + { + throw new UnsupportedOperationException("not supported yet!"); + } + + @Override + public Graph duplicate() throws CloneNotSupportedException + { + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + + @Override + public Node findNodeByLabel(int label) + { + return nodes.get(label); + } + + @Override + public Collection getLabels() + { + return nodes.keySet(); + } + + @Override + public TreeNode getRoot() + { + return root; + } + + @Override + public boolean isRoot(TreeNode node) + { + return root.equals(node); + } + + @Override + public boolean isVertexAdjacent(int u, int v) + { + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + + @Override + public boolean isWeighted() + { + ///TODO: Fixme + return false; + } + + @Override + public E remove(Node node) + { + if (nodes.containsKey(node.getLabel()) == false) + { + throw new IllegalArgumentException("Attempted to remove a node not belonging to this graph."); + } + + // Find the parent and remove the child node NODE + return node.get(); + } + + @Override + public E remove(int u) + { + return remove(findNodeByLabel(u)); + } + + @Override + public int size() + { + return nodes.size(); + } + + @Override + protected boolean addNode(Node node) + { + ///TODO: Fix this + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + + @Override + protected Collection> getNodes() + { + return nodes.values(); + } + +} diff --git a/src/cu/edu/cujae/graphy/core/trees/DefaultGeneralTreeNode.java b/src/cu/edu/cujae/graphy/core/trees/DefaultGeneralTreeNode.java index 6c9a9ed..fbc58e3 100644 --- a/src/cu/edu/cujae/graphy/core/trees/DefaultGeneralTreeNode.java +++ b/src/cu/edu/cujae/graphy/core/trees/DefaultGeneralTreeNode.java @@ -138,4 +138,4 @@ public boolean removeEdge(Edge edge) return children.remove(edge); } -} +} \ No newline at end of file diff --git a/src/cu/edu/cujae/graphy/core/utility/Graphs.java b/src/cu/edu/cujae/graphy/core/utility/Graphs.java index 12683dc..9519bb8 100644 --- a/src/cu/edu/cujae/graphy/core/utility/Graphs.java +++ b/src/cu/edu/cujae/graphy/core/utility/Graphs.java @@ -1,195 +1,195 @@ -/* - * Copyright (C) 2022 Javier Marrero. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.core.utility; - -import cu.edu.cujae.graphy.core.EdgeFactory; -import cu.edu.cujae.graphy.core.Graph; -import cu.edu.cujae.graphy.core.Node; -import cu.edu.cujae.graphy.core.iterators.GraphIterator; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; - -/** - * Utility class to perform some operations on graphs. - * - * @author Javier Marrero - */ -public class Graphs -{ - - private static class ImmutableGraph implements Graph - { - - private Graph graph; - - public ImmutableGraph(Graph graph) - { - if (graph == null) - { - throw new IllegalArgumentException("unable to make a 'null' graph immutable."); - } - this.graph = graph; - } - - @Override - public boolean add(int label, T data) - { - throw new UnsupportedOperationException("This graph instance is immutable."); - } - - @Override - public boolean add(T data) - { - throw new UnsupportedOperationException("This graph instance is immutable."); - } - - @Override - public Iterator breadthFirstSearchIterator(Node node, boolean includeDisconnected) - { - return graph.breadthFirstSearchIterator(node, includeDisconnected); - } - - @Override - public Iterator breadthFirstSearchIterator(int v, boolean includeDisconnected) - { - return graph.breadthFirstSearchIterator(v, includeDisconnected); - } - - @Override - public Iterator breadthFirstSearchIterator(boolean includeDisconnected) - { - return graph.breadthFirstSearchIterator(includeDisconnected); - } - - @Override - public boolean connect(int u, int v) - { - throw new UnsupportedOperationException("This graph instance is immutable."); - } - - @Override - public boolean connect(Node u, Node v) - { - throw new UnsupportedOperationException("This graph instance is immutable."); - } - - @Override - public Iterator depthFirstSearchIterator(Node start, boolean includeDisconnected) - { - return graph.depthFirstSearchIterator(start, includeDisconnected); - } - - @Override - public Iterator depthFirstSearchIterator(int v, boolean includeDisconnected) - { - return graph.depthFirstSearchIterator(v, includeDisconnected); - } - - @Override - public Iterator depthFirstSearchIterator(boolean includeDisconnected) - { - return graph.depthFirstSearchIterator(includeDisconnected); - } - - @Override - public Graph duplicate() throws CloneNotSupportedException - { - throw new CloneNotSupportedException(); - } - - @Override - public Collection getLabels() - { - return Collections.unmodifiableCollection(graph.getLabels()); - } - - @Override - public boolean isDirected() - { - return graph.isDirected(); - } - - @Override - public boolean isVertexAdjacent(int u, int v) - { - return graph.isVertexAdjacent(u, v); - } - - @Override - public boolean isWeighted() - { - return graph.isWeighted(); - } - - @Override - public Iterator iterator() - { - return graph.iterator(); - } - - @Override - public GraphIterator iterator(int v) - { - return graph.iterator(v); - } - - @Override - public void registerEdgeFactory(EdgeFactory factory) - { - throw new UnsupportedOperationException("This graph instance is immutable."); - } - - @Override - public T remove(Node node) - { - throw new UnsupportedOperationException("This graph instance is immutable."); - } - - @Override - public T remove(int u) - { - throw new UnsupportedOperationException("This graph instance is immutable."); - } - - @Override - public int size() - { - return graph.size(); - } - } - - /** - * Returns a new graph view that is immutable, meaning that no changes to the graph's structure can be made. The - * returned graph is a view of the original graph, in the sense that any change to the original graph gets reflected - * in the returned graph. - *

- * If one attempts to modify the graph via its standard methods, a {@link UnsupportedOperationException} will be - * thrown. - * - * @param - * @param graph - * - * @return - */ - public static Graph makeImmutableGraph(Graph graph) - { - return new ImmutableGraph<>(graph); - } -} +/* + * Copyright (C) 2022 Javier Marrero. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.core.utility; + +import cu.edu.cujae.graphy.core.EdgeFactory; +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.Node; +import cu.edu.cujae.graphy.core.iterators.GraphIterator; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +/** + * Utility class to perform some operations on graphs. + * + * @author Javier Marrero + */ +public class Graphs +{ + + private static class ImmutableGraph implements Graph + { + + private Graph graph; + + public ImmutableGraph(Graph graph) + { + if (graph == null) + { + throw new IllegalArgumentException("unable to make a 'null' graph immutable."); + } + this.graph = graph; + } + + @Override + public boolean add(int label, T data) + { + throw new UnsupportedOperationException("This graph instance is immutable."); + } + + @Override + public boolean add(T data) + { + throw new UnsupportedOperationException("This graph instance is immutable."); + } + + @Override + public Iterator breadthFirstSearchIterator(Node node, boolean includeDisconnected) + { + return graph.breadthFirstSearchIterator(node, includeDisconnected); + } + + @Override + public Iterator breadthFirstSearchIterator(int v, boolean includeDisconnected) + { + return graph.breadthFirstSearchIterator(v, includeDisconnected); + } + + @Override + public Iterator breadthFirstSearchIterator(boolean includeDisconnected) + { + return graph.breadthFirstSearchIterator(includeDisconnected); + } + + @Override + public boolean connect(int u, int v) + { + throw new UnsupportedOperationException("This graph instance is immutable."); + } + + @Override + public boolean connect(Node u, Node v) + { + throw new UnsupportedOperationException("This graph instance is immutable."); + } + + @Override + public Iterator depthFirstSearchIterator(Node start, boolean includeDisconnected) + { + return graph.depthFirstSearchIterator(start, includeDisconnected); + } + + @Override + public Iterator depthFirstSearchIterator(int v, boolean includeDisconnected) + { + return graph.depthFirstSearchIterator(v, includeDisconnected); + } + + @Override + public Iterator depthFirstSearchIterator(boolean includeDisconnected) + { + return graph.depthFirstSearchIterator(includeDisconnected); + } + + @Override + public Graph duplicate() throws CloneNotSupportedException + { + throw new CloneNotSupportedException(); + } + + @Override + public Collection getLabels() + { + return Collections.unmodifiableCollection(graph.getLabels()); + } + + @Override + public boolean isDirected() + { + return graph.isDirected(); + } + + @Override + public boolean isVertexAdjacent(int u, int v) + { + return graph.isVertexAdjacent(u, v); + } + + @Override + public boolean isWeighted() + { + return graph.isWeighted(); + } + + @Override + public Iterator iterator() + { + return graph.iterator(); + } + + @Override + public GraphIterator iterator(int v) + { + return graph.iterator(v); + } + + @Override + public void registerEdgeFactory(EdgeFactory factory) + { + throw new UnsupportedOperationException("This graph instance is immutable."); + } + + @Override + public T remove(Node node) + { + throw new UnsupportedOperationException("This graph instance is immutable."); + } + + @Override + public T remove(int u) + { + throw new UnsupportedOperationException("This graph instance is immutable."); + } + + @Override + public int size() + { + return graph.size(); + } + } + + /** + * Returns a new graph view that is immutable, meaning that no changes to the graph's structure can be made. The + * returned graph is a view of the original graph, in the sense that any change to the original graph gets reflected + * in the returned graph. + *

+ * If one attempts to modify the graph via its standard methods, a {@link UnsupportedOperationException} will be + * thrown. + * + * @param + * @param graph + * + * @return + */ + public static Graph makeImmutableGraph(Graph graph) + { + return new ImmutableGraph<>(graph); + } +} diff --git a/test/cu/edu/cujae/graphy/tests/CloneTest.java b/test/cu/edu/cujae/graphy/tests/CloneTest.java index c6d6571..a0bfbf3 100644 --- a/test/cu/edu/cujae/graphy/tests/CloneTest.java +++ b/test/cu/edu/cujae/graphy/tests/CloneTest.java @@ -1,100 +1,100 @@ -/* - * Copyright (C) 2022 CUJAE. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -package cu.edu.cujae.graphy.tests; - -import cu.edu.cujae.graphy.core.Graph; -import cu.edu.cujae.graphy.core.WeightedGraph; -import cu.edu.cujae.graphy.core.utility.GraphBuilders; -import cu.edu.cujae.graphy.core.utility.Weights; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Test for cloning a graph - * - * @author Javier Marrero - */ -public class CloneTest -{ - - private static void testSimpleGraphs() - { - // This is for normal, simple graphs - Graph graph = GraphBuilders.makeSimpleGraph(true); - for (int i = 0; i < 3; ++i) - { - graph.add(i); - } - - graph.connect(0, 1); - graph.connect(1, 2); - graph.connect(2, 0); - - System.out.println(graph); - - try - { - Graph clone = graph.duplicate(); - System.out.println(clone); - } - catch (CloneNotSupportedException ex) - { - Logger.getLogger(CloneTest.class.getName()).log(Level.SEVERE, null, ex); - } - } - - private static void testWeightedGraphs() - { - // This is for normal, simple graphs - WeightedGraph weightedGraph = GraphBuilders.makeSimpleWeightedGraph(true); - for (int i = 0; i < 3; ++i) - { - weightedGraph.add(i); - } - - weightedGraph.connect(0, 1, Weights.makeWeight(1)); - weightedGraph.connect(1, 2, Weights.makeWeight(6)); - weightedGraph.connect(2, 0, Weights.makeWeight(18)); - - System.out.println(weightedGraph); - - try - { - WeightedGraph clone = (WeightedGraph) weightedGraph.duplicate(); - System.out.println(clone); - } - catch (CloneNotSupportedException ex) - { - Logger.getLogger(CloneTest.class.getName()).log(Level.SEVERE, null, ex); - } - } - - /** - * @param args the command line arguments - */ - public static void main(String[] args) - { - System.out.println("Testing for simple graphs:\n"); - testSimpleGraphs(); - - System.out.println("\nTesting for weighted graphs:\n"); - testWeightedGraphs(); - } - -} +/* + * Copyright (C) 2022 CUJAE. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.tests; + +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.WeightedGraph; +import cu.edu.cujae.graphy.core.utility.GraphBuilders; +import cu.edu.cujae.graphy.core.utility.Weights; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Test for cloning a graph + * + * @author Javier Marrero + */ +public class CloneTest +{ + + private static void testSimpleGraphs() + { + // This is for normal, simple graphs + Graph graph = GraphBuilders.makeSimpleGraph(true); + for (int i = 0; i < 3; ++i) + { + graph.add(i); + } + + graph.connect(0, 1); + graph.connect(1, 2); + graph.connect(2, 0); + + System.out.println(graph); + + try + { + Graph clone = graph.duplicate(); + System.out.println(clone); + } + catch (CloneNotSupportedException ex) + { + Logger.getLogger(CloneTest.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private static void testWeightedGraphs() + { + // This is for normal, simple graphs + WeightedGraph weightedGraph = GraphBuilders.makeSimpleWeightedGraph(true); + for (int i = 0; i < 3; ++i) + { + weightedGraph.add(i); + } + + weightedGraph.connect(0, 1, Weights.makeWeight(1)); + weightedGraph.connect(1, 2, Weights.makeWeight(6)); + weightedGraph.connect(2, 0, Weights.makeWeight(18)); + + System.out.println(weightedGraph); + + try + { + WeightedGraph clone = (WeightedGraph) weightedGraph.duplicate(); + System.out.println(clone); + } + catch (CloneNotSupportedException ex) + { + Logger.getLogger(CloneTest.class.getName()).log(Level.SEVERE, null, ex); + } + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) + { + System.out.println("Testing for simple graphs:\n"); + testSimpleGraphs(); + + System.out.println("\nTesting for weighted graphs:\n"); + testWeightedGraphs(); + } + +} diff --git a/test/cu/edu/cujae/graphy/tests/algorithms/IsolatedVerticesTest.java b/test/cu/edu/cujae/graphy/tests/algorithms/IsolatedVerticesTest.java new file mode 100644 index 0000000..502f14a --- /dev/null +++ b/test/cu/edu/cujae/graphy/tests/algorithms/IsolatedVerticesTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2022 Jose. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package cu.edu.cujae.graphy.tests.algorithms; + +import cu.edu.cujae.graphy.algorithms.IsolatedVertices; +import cu.edu.cujae.graphy.core.Graph; +import cu.edu.cujae.graphy.core.defaults.DefaultGraphBuilder; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * + * @author Jose + */ +public class IsolatedVerticesTest +{ + + public static void getIsolatedVertices (Graph graph) + { + LinkedList aux = (LinkedList) (new IsolatedVertices(graph)).apply().get(); + Iterator iter = aux.iterator(); + + if(!aux.isEmpty()) + { + while(iter.hasNext()) + { + Integer in = iter.next(); + System.out.println(in); + } + } + else + { + System.out.println("No existen vértices aislados en el grafo"); + } + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) + { + //Juego de datos para cuando existen vertices aislados + Graph graph = new DefaultGraphBuilder().buildGraph().directed(false).get(); + + for(int i = 0;i<10;i++) + { + graph.add(i, i); + } + + graph.connect(0, 1); + graph.connect(0, 2); + graph.connect(2, 3); + graph.connect(2, 4); + graph.connect(4, 5); + graph.connect(5, 6); + graph.connect(1, 9); + + getIsolatedVertices(graph); + + //Juego de datos para cuando no existen vertices aislados + Graph graph2 = new DefaultGraphBuilder().buildGraph().directed(false).get(); + + for(int i =0;i<10;i++) + { + graph2.add(i, i); + } + + graph2.connect(0, 1); + graph2.connect(0, 2); + graph2.connect(2, 3); + graph2.connect(2, 4); + graph2.connect(4, 5); + graph2.connect(5, 6); + graph2.connect(1, 9); + graph2.connect(7, 8); + + getIsolatedVertices(graph2); + } + +}