// Point : Forest to Tree // // While T has more than one component // For each component C of T : // Begin with an empty set of edges S // For each vertex v in C : // Find the cheapest edge from v to a vertex outside of C, and add it to S // Add the cheapest edge in S to T public WeightUnDirectedGraph MSTBySollin() { LinkedList<WeightUnDirectedGraph> graphLinkedList = new LinkedList<>(); for (int i = 0; i < vertices.size(); i++) { graphLinkedList.add(new WeightUnDirectedGraph()); } // 각각의 vertex에 대해서 graph라고 만듦 for (int i = 0; i < vertices.size(); i++) { graphLinkedList.get(i).insertVertex(new Data(vertices.get(i).getData().id)); } int index = 0; WeightUnDirectedGraph currentGraph; // While T has more than one component: while (graphLinkedList.size() > 1) { if (index >= graphLinkedList.size()) index = 0; // For each component C of T: currentGraph = graphLinkedList.get(index); // Begin with an empty set of edges S LinkedList<Edge> edgeList = new LinkedList<>(); // For each vertex v in C: for (Vertex currentVertex : currentGraph.vertices) { // Find the cheapest edge from v to a vertex outside of C, and add it to S // 현재 큰 그래프에서 찾음 Vertex vertex = retrieveVertex(currentVertex.getData().id); for (Edge edge : vertex.getEdges()) { if (currentGraph.retrieveVertex(edge.getToVertex().getData().id) == null) insertEdgeToList(edgeList, edge); } } int graphIndex = findGraphIndex(graphLinkedList, edgeList.getFirst().getToVertex()); // Add the cheapest edge in S to T if (mergeGraph(currentGraph, graphLinkedList.get(graphIndex), edgeList.removeFirst())) graphLinkedList.remove(graphIndex); index++; } return graphLinkedList.getFirst(); }
// Point : Vertex // 1. Remove Edge from PQ // 2. check edge's toVertex is in Graph // 3. if toVertex is not exist then add that vertex to the graph and edges // 3-1. if to Vertex is exist in Graph then ignore this Edge public WeightUnDirectedGraph MSTByPrim() { if (vertices.size() == 0) return null; WeightUnDirectedGraph tmpGraph = new WeightUnDirectedGraph(); LinkedList<Edge> edgeList = new LinkedList<>(); // Insert First Vertex to Graph tmpGraph.insertVertex(new Data(vertices.getFirst().getData().id)); // Get First tmpGraph Vertex Vertex currentVertex = vertices.getFirst(); Vertex nextVertex; // Insert First Vertex Edges for (Edge edge : currentVertex.getEdges()) { insertEdgeToList(edgeList, edge); } // keep make graph(actually tree) until edgeList size get to 0 while (edgeList.size() != 0) { // First One is lowest Weight Edge Edge edge = edgeList.removeFirst(); // Vertex Exist => Already lowest weight path exist if (tmpGraph.retrieveVertex(edge.getToVertex().getData().id) != null) continue; // insert Vertex tmpGraph.insertVertex(new Data(edge.getToVertex().getData().id)); nextVertex = edge.getToVertex(); // insert edge between two vertices tmpGraph.insertEdge( tmpGraph.retrieveVertex(edge.getFromVertex().getData().id), tmpGraph.retrieveVertex(edge.getToVertex().getData().id), edge.getWeight()); // insert next Vertex's Edges for (Edge tmpEdge : nextVertex.getEdges()) { insertEdgeToList(edgeList, tmpEdge); } } return tmpGraph; }
// merge toGraph and fromGraph, and put edge to the toGraph private boolean mergeGraph( WeightUnDirectedGraph toGraph, WeightUnDirectedGraph fromGraph, Edge edge) { // Add "fromGraph" To "toGraph" // Both graphs are disjoint!! LinkedList<Edge> edgeList = new LinkedList<>(); // move all vertices from fromGraph to toGraph for (int i = 0; i < fromGraph.size; i++) { if (!toGraph.vertices.contains(fromGraph.vertices.get(i))) toGraph.insertVertex(new Data(fromGraph.vertices.get(i).getData().id)); // add all edges from fromGraph to toGraph for (Edge tmpEdge : fromGraph.vertices.get(i).getEdges()) { insertEdgeToList(edgeList, tmpEdge); } } // add all vertices to toGraph // insert all edges to the toGraph for (Edge tmpEdge : edgeList) { toGraph.insertEdge( toGraph.retrieveVertex(tmpEdge.getFromVertex().getData().id), toGraph.retrieveVertex(tmpEdge.getToVertex().getData().id), tmpEdge.getWeight()); } // insert "edge"(see above parameter) to the toGraph toGraph.insertEdge( toGraph.retrieveVertex(edge.getFromVertex().getData().id), toGraph.retrieveVertex(edge.getToVertex().getData().id), edge.getWeight()); return true; }
// Point : Edge // 1. Put edges to the edgeList(sort by weight) (frankly it is Minimum Heap) // 2. remove edge element from heap and add to the graph // 3. if there is a cycle then remove that edge(which we inserted at step 2) public WeightUnDirectedGraph MSTByKruskal() { if (vertices.size() == 0) return null; WeightUnDirectedGraph tmpGraph = new WeightUnDirectedGraph(); // Use this as a Heap LinkedList<Edge> edgeList = new LinkedList<>(); // Put edges to the edgeList(sort by weight) for (Vertex currentVertex : vertices) { for (Edge currentEdge : currentVertex.getEdges()) { insertEdgeToList(edgeList, currentEdge); } } // Make new Graph(Tree) by using edgeList while (!edgeList.isEmpty()) { Edge edge = edgeList.removeFirst(); // Make new vertex for tmpGraph if (tmpGraph.retrieveVertex(edge.getFromVertex().getData().id) == null) tmpGraph.insertVertex(new Data(edge.getFromVertex().getData().id)); if (tmpGraph.retrieveVertex(edge.getToVertex().getData().id) == null) tmpGraph.insertVertex(new Data(edge.getToVertex().getData().id)); // insert Edge and Weight between vertices tmpGraph.insertEdge( tmpGraph.retrieveVertex(edge.getFromVertex().getData().id), tmpGraph.retrieveVertex(edge.getToVertex().getData().id), edge.getWeight()); // Check if there is a cycle if (tmpGraph.hasCycle()) { // if there is a cycle // then delete edge tmpGraph.deleteEdge( tmpGraph.retrieveVertex(edge.getFromVertex().getData().id), tmpGraph.retrieveVertex(edge.getToVertex().getData().id)); System.out.println("Cycle Exist"); } } return tmpGraph; }