diff --git a/.idea/gradle.xml b/.idea/gradle.xml index ba1ec5c7e20c12eb5b893684698eab151c4a8803..ce1c62c7c60561be6b5a9bc9f115e8966e9e5a4a 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> + <component name="GradleMigrationSettings" migrationVersion="1" /> <component name="GradleSettings"> <option name="linkedExternalProjectsSettings"> <GradleProjectSettings> - <option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="modules"> <set> diff --git a/.idea/misc.xml b/.idea/misc.xml index cf8ff73dbdd0483209669347c493bf3336cbb89c..473dca4b4babf0dbef4bec3498024da911dfda2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ -<?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_18_PREVIEW" project-jdk-name="18" project-jdk-type="JavaSDK"> diff --git a/src/main/java/fr/univamu/graph/Algorithms.java b/src/main/java/fr/univamu/graph/Algorithms.java new file mode 100644 index 0000000000000000000000000000000000000000..b981587fc3083ee81b33893ae40dbe60cb802e42 --- /dev/null +++ b/src/main/java/fr/univamu/graph/Algorithms.java @@ -0,0 +1,115 @@ +package fr.univamu.graph; + +import fr.univamu.graph.rootedtrees.RootedTree; + +import java.util.*; + +public class Algorithms { + + private static final Random random = new Random(); + //3.1 + public static RootedTree primMST(UndirectedGraph graph){ + + int startVertex = random.nextInt(graph.order()); // arbitrary + List<Edge> edges = new ArrayList<>(graph.adjacencies.get(startVertex)); + + List<LinkedList<RootedTree>> childrenOfVertices = new ArrayList<>(graph.order()); + for (int i = 0; i < graph.order(); i++) { + childrenOfVertices.add(new LinkedList<>()); + } + + return primMST(startVertex, childrenOfVertices, edges, graph.adjacencies); + } + + + private static RootedTree primMST(int startVertex, List<LinkedList<RootedTree>> childrenOfVertices, List<Edge> edges, List<List<Edge>> graphAdjacencies){ + + int rootVertex = startVertex; + + int minVertex = -1; + Edge minEdge = new Edge(-1,-1,-1); + + RootedTree randChild = new RootedTree(-1,new ArrayList<>()); + childrenOfVertices.get(startVertex).add(randChild); + + for (Edge edge : edges) { + if((edge.weight() < minEdge.weight() || minVertex == -1)){ + if((!childrenOfVertices.get(edge.vertex1()).isEmpty()) && childrenOfVertices.get(edge.vertex2()).isEmpty()) { + rootVertex = edge.vertex1(); + minVertex = edge.vertex2(); + minEdge = edge; + } + else if ((!childrenOfVertices.get(edge.vertex2()).isEmpty()) && childrenOfVertices.get(edge.vertex1()).isEmpty()) { + rootVertex = edge.vertex2(); + minVertex = edge.vertex1(); + minEdge = edge; + } + } + } + if(minVertex == -1) { + childrenOfVertices.get(startVertex).remove(randChild); + return new RootedTree(startVertex, childrenOfVertices.get(startVertex)); + } + edges.addAll(graphAdjacencies.get(minVertex)); + + + childrenOfVertices.get(rootVertex).add(primMST(minVertex, childrenOfVertices, edges, graphAdjacencies)); + childrenOfVertices.get(startVertex).remove(randChild); + + return new RootedTree(startVertex,childrenOfVertices.get(startVertex)); + } + + + + public static RootedTree aldousBroderST(UndirectedGraph graph){ + + int startVertex = random.nextInt(graph.order()); // arbitrary + + List<Boolean> visitedVertex = new ArrayList<>(graph.order()); + for (int i = 0; i < graph.order(); i++) { + visitedVertex.add(false); + } + + List<LinkedList<RootedTree>> childrenOfVertices = new ArrayList<>(graph.order()); + for (int i = 0; i < graph.order(); i++) { + childrenOfVertices.add(new LinkedList<>()); + } + visitedVertex.set(startVertex, true); + return aldousBroderST(startVertex,1, visitedVertex, childrenOfVertices, graph); + } + + + + private static RootedTree aldousBroderST(int startVertex, int nbOfVisited, List<Boolean> visitedVertex, List<LinkedList<RootedTree>> childrenOfVertices, UndirectedGraph graph){ + + + System.out.print(" : " + startVertex); + if(nbOfVisited == graph.order()) { + return new RootedTree(startVertex,childrenOfVertices.get(startVertex)); + } + List<Integer> neighbors = new ArrayList<>(); + for (int neighbor : graph.neighboursOf(startVertex)) { + neighbors.add(neighbor); + } + + int vertex = neighbors.get(random.nextInt(neighbors.size())); + + boolean wasNotVisited = false; + if(!visitedVertex.get(vertex)) { + wasNotVisited = true; + visitedVertex.set(vertex, true); + nbOfVisited++; + } + + RootedTree child = aldousBroderST(vertex, nbOfVisited, visitedVertex, childrenOfVertices, graph); + + if(wasNotVisited) { + childrenOfVertices.get(startVertex).add(child); + } + return new RootedTree(startVertex,childrenOfVertices.get(startVertex)); + } + + + + +} diff --git a/src/main/java/fr/univamu/graph/Edge.java b/src/main/java/fr/univamu/graph/Edge.java index dcd39687c1df8a842bf22c0bce38a72da2f7880f..16b8b294413717ae3ae301cf35b85544ee5c26e8 100644 --- a/src/main/java/fr/univamu/graph/Edge.java +++ b/src/main/java/fr/univamu/graph/Edge.java @@ -1,10 +1,72 @@ package fr.univamu.graph; -public record Edge(int vertex1, int vertex2) { +import java.util.Objects; +import java.util.Random; + +public class Edge { + private final int vertex1; + private final int vertex2; + private double weight; + + public Edge(int vertex1, int vertex2) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + // Random Weight Generation + Random random = new Random(); + this.weight = random.nextDouble(); + } + + public Edge(int vertex1, int vertex2, double weight) { + this.vertex1 = vertex1; + this.vertex2 = vertex2; + this.weight = weight; + } public int opposite(int vertex) { if (vertex == vertex1) return vertex2; if (vertex == vertex2) return vertex1; - throw new IllegalArgumentException(this + ".opposite(" + vertex +")"); + throw new IllegalArgumentException(this + ".opposite(" + vertex + ")"); + } + + public int vertex1() { + return vertex1; + } + + public int vertex2() { + return vertex2; + } + + public double weight() { + return weight; } + + public void setWeight(double weight) { + this.weight = weight; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (Edge) obj; + return this.vertex1 == that.vertex1 && + this.vertex2 == that.vertex2 && + Objects.equals(this.weight, that.weight); + } + + @Override + public int hashCode() { + return Objects.hash(vertex1, vertex2, weight); + } + + @Override + public String toString() { + return "Edge[" + + vertex1 + ", " + + vertex2 + ", " + + + weight + ']'; + } + + } +