continuata implementazione di graph. bfs dfs kruskal dijkstra
This commit is contained in:
131
graph/BFS.java
Normal file
131
graph/BFS.java
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
|
||||||
|
//gioel
|
||||||
|
|
||||||
|
package graph;
|
||||||
|
|
||||||
|
|
||||||
|
import arraylist.ArrayIndexList;
|
||||||
|
import arraylist.IndexList;
|
||||||
|
import position.NodePositionList;
|
||||||
|
import position.PositionList;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
|
public abstract class BFS<V, E, I, R> {
|
||||||
|
protected Graph<V, E> graph;
|
||||||
|
protected Vertex<V> start;
|
||||||
|
protected I info;
|
||||||
|
protected R visitResult;
|
||||||
|
protected static Object STATUS = new Object();
|
||||||
|
protected static Object VISITED = new Object();
|
||||||
|
protected static Object UNVISITED = new Object();
|
||||||
|
|
||||||
|
protected IndexList<PositionList<Vertex<V>>> layers;
|
||||||
|
|
||||||
|
public R execute(Graph<V, E> g, Vertex<V> s, I in) throws InvalidKeyException{
|
||||||
|
graph = g;
|
||||||
|
layers = new ArrayIndexList<PositionList<Vertex<V>>>(
|
||||||
|
graph.numVertices());
|
||||||
|
start = s;
|
||||||
|
info = in;
|
||||||
|
for (Vertex<V> v : graph.vertices())
|
||||||
|
unVisit(v);
|
||||||
|
for (Edge<E> e : graph.edges())
|
||||||
|
unVisit(e);
|
||||||
|
|
||||||
|
setup();
|
||||||
|
return finalResult(bfsTraversal(start));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected R bfsTraversal(Vertex<V> v) throws InvalidKeyException{
|
||||||
|
initResult();
|
||||||
|
if (!isDone())
|
||||||
|
startVisit(v);
|
||||||
|
|
||||||
|
if (!isDone()) {
|
||||||
|
visit(v);
|
||||||
|
|
||||||
|
layers.add(0, new NodePositionList<Vertex<V>>());
|
||||||
|
layers.get(0).addLast(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (!layers.get(i).isEmpty()) {
|
||||||
|
layers.add(i + 1, new NodePositionList<Vertex<V>>());
|
||||||
|
|
||||||
|
for (Vertex<V> vertexInLayer : layers.get(i)) {
|
||||||
|
for (Edge<E> e : graph.incidentEdges(vertexInLayer)) {
|
||||||
|
if (!isVisited(e)) {
|
||||||
|
visit(e);
|
||||||
|
Vertex<V> w = graph.opposite(vertexInLayer, e);
|
||||||
|
if (!isVisited(w)) {
|
||||||
|
traverseDiscovery(e, vertexInLayer);
|
||||||
|
|
||||||
|
if (isDone())
|
||||||
|
break;
|
||||||
|
|
||||||
|
visit(w);
|
||||||
|
layers.get(i + 1).addLast(w);
|
||||||
|
|
||||||
|
if (isDone())
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
traverseCross(e, v);
|
||||||
|
if (isDone())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDone())
|
||||||
|
finishVisit(vertexInLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initResult() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void startVisit(Vertex<V> v) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void traverseCross(Edge<E> e, Vertex<V> v) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void traverseDiscovery(Edge<E> e, Vertex<V> v) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void finishVisit(Vertex<V> v) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isDone() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected R result() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected R finalResult(R r) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void visit(DecorablePosition<?> p) throws InvalidKeyException{
|
||||||
|
p.put(STATUS, VISITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void unVisit(DecorablePosition<?> p) throws InvalidKeyException {
|
||||||
|
p.put(STATUS, UNVISITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isVisited(DecorablePosition<?> p) throws InvalidKeyException {
|
||||||
|
return p.get(STATUS) == VISITED;
|
||||||
|
}
|
||||||
|
}
|
||||||
39
graph/ComponentsBFS.java
Normal file
39
graph/ComponentsBFS.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//gioel
|
||||||
|
|
||||||
|
package graph;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
|
public class ComponentsBFS<V, E> extends BFS<V, E, Object, Integer> {
|
||||||
|
protected Integer compNumber;
|
||||||
|
protected Object COMPONENT = new Object();
|
||||||
|
|
||||||
|
protected void setup() {
|
||||||
|
compNumber = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void startVisit(Vertex<V> v) {
|
||||||
|
try {
|
||||||
|
v.put(COMPONENT, compNumber);
|
||||||
|
}
|
||||||
|
catch (InvalidKeyException e){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Integer finalResult(Integer bfsResult) {
|
||||||
|
try {
|
||||||
|
for(Vertex<V> v : graph.vertices())
|
||||||
|
if(!isVisited(v)) {
|
||||||
|
compNumber++;
|
||||||
|
bfsTraversal(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return compNumber;
|
||||||
|
}
|
||||||
|
catch (InvalidKeyException e){
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
graph/ComponentsDFS.java
Normal file
35
graph/ComponentsDFS.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package graph;
|
||||||
|
|
||||||
|
//begin#fragment CC
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
|
/** This class extends DFS to compute the connected components of a graph. */
|
||||||
|
public class ComponentsDFS<V, E> extends DFS<V, E, Object, Integer> {
|
||||||
|
protected Integer compNumber; // Connected component number
|
||||||
|
protected Object COMPONENT = new Object(); // Connected comp. selector
|
||||||
|
protected void setup() { compNumber = 1; }
|
||||||
|
protected void startVisit(Vertex<V> v) {
|
||||||
|
try{
|
||||||
|
v.put(COMPONENT, compNumber);
|
||||||
|
}
|
||||||
|
catch (InvalidKeyException e){
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected Integer finalResult(Integer dfsResult) {
|
||||||
|
try{
|
||||||
|
for (Vertex<V> v : graph.vertices()) // check for any unvisited vertices
|
||||||
|
if (v.get(STATUS) == UNVISITED) {
|
||||||
|
compNumber += 1; // we have found another connected component
|
||||||
|
dfsTraversal(v); // visit all the vertices of this component
|
||||||
|
}
|
||||||
|
return compNumber;
|
||||||
|
}
|
||||||
|
catch (InvalidKeyException e){
|
||||||
|
//
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end#fragment CC
|
||||||
106
graph/DFS.java
Normal file
106
graph/DFS.java
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package graph;
|
||||||
|
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
|
/** Generic DFS traversal of a graph using the template method pattern.
|
||||||
|
* Parameterized types:
|
||||||
|
* V, the type for the elements stored at vertices
|
||||||
|
* E, the type for the elements stored at edges
|
||||||
|
* I, the type for the information object passed to the execute method
|
||||||
|
* R, the type for the result object returned by the DFS
|
||||||
|
*/
|
||||||
|
public class DFS<V, E, I, R> {
|
||||||
|
protected Graph<V, E> graph; // The graph being traversed
|
||||||
|
protected Vertex<V> start; // The start vertex for the DFS
|
||||||
|
protected I info; // Information object passed to DFS
|
||||||
|
protected R visitResult; // The result of a recursive traversal call
|
||||||
|
protected static Object STATUS = new Object(); // The status attribute
|
||||||
|
protected static Object VISITED = new Object(); // Visited value
|
||||||
|
protected static Object UNVISITED = new Object(); // Unvisited value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Execute a depth first search traversal on graph g, starting
|
||||||
|
* from a start vertex s, passing in an information object (in) */
|
||||||
|
public R execute(Graph<V, E> g, Vertex<V> s, I in) throws InvalidKeyException {
|
||||||
|
graph = g;
|
||||||
|
start = s;
|
||||||
|
info = in;
|
||||||
|
for(Vertex<V> v: graph.vertices()) unVisit(v); // mark vertices as unvisited
|
||||||
|
for(Edge<E> e: graph.edges()) unVisit(e); // mark edges as unvisited
|
||||||
|
setup(); // perform any necessary setup prior to DFS traversal
|
||||||
|
return finalResult(dfsTraversal(start));
|
||||||
|
}
|
||||||
|
/** Recursive template method for a generic DFS traversal. */
|
||||||
|
protected R dfsTraversal(Vertex<V> v) throws InvalidKeyException{
|
||||||
|
initResult();
|
||||||
|
if (!isDone())
|
||||||
|
startVisit(v);
|
||||||
|
if (!isDone()) {
|
||||||
|
visit(v);
|
||||||
|
for (Edge<E> e: graph.incidentEdges(v)) {
|
||||||
|
if (!isVisited(e)) {
|
||||||
|
// found an unexplored edge, explore it
|
||||||
|
visit(e);
|
||||||
|
Vertex<V> w = graph.opposite(v, e);
|
||||||
|
if (!isVisited(w)) {
|
||||||
|
// w is unexplored, this is a discovery edge
|
||||||
|
traverseDiscovery(e, v);
|
||||||
|
if (isDone()) break;
|
||||||
|
visitResult = dfsTraversal(w); // get result from DFS-tree child
|
||||||
|
if (isDone()) break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// w is explored, this is a back edge
|
||||||
|
traverseBack(e, v);
|
||||||
|
if (isDone()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!isDone())
|
||||||
|
finishVisit(v);
|
||||||
|
return result();
|
||||||
|
}
|
||||||
|
//end#fragment DFS2
|
||||||
|
|
||||||
|
//begin#fragment decorations
|
||||||
|
/** Mark a position (vertex or edge) as visited. */
|
||||||
|
protected void visit(DecorablePosition<?> p) throws InvalidKeyException{
|
||||||
|
p.put(STATUS, VISITED);
|
||||||
|
}
|
||||||
|
/** Mark a position (vertex or edge) as unvisited. */
|
||||||
|
protected void unVisit(DecorablePosition<?> p) throws InvalidKeyException {
|
||||||
|
p.put(STATUS, UNVISITED);
|
||||||
|
}
|
||||||
|
/** Test if a position (vertex or edge) has been visited. */
|
||||||
|
protected boolean isVisited(DecorablePosition<?> p) throws InvalidKeyException {
|
||||||
|
return (p.get(STATUS) == VISITED);
|
||||||
|
}
|
||||||
|
//end#fragment decorations
|
||||||
|
|
||||||
|
// Auxiliary methods (all initially null) for specializing a generic DFS
|
||||||
|
//begin#fragment auxiliary
|
||||||
|
/** Setup method that is called prior to the DFS execution. */
|
||||||
|
protected void setup() {}
|
||||||
|
/** Initializes result (called first, once per vertex visited). */
|
||||||
|
protected void initResult() {}
|
||||||
|
/** Called when we encounter a vertex (v). */
|
||||||
|
protected void startVisit(Vertex<V> v) {}
|
||||||
|
/** Called after we finish the visit for a vertex (v). */
|
||||||
|
protected void finishVisit(Vertex<V> v) {}
|
||||||
|
/** Called when we traverse a discovery edge (e) from a vertex (from). */
|
||||||
|
protected void traverseDiscovery(Edge<E> e, Vertex<V> from) {}
|
||||||
|
/** Called when we traverse a back edge (e) from a vertex (from). */
|
||||||
|
protected void traverseBack(Edge<E> e, Vertex<V> from) {}
|
||||||
|
/** Determines whether the traversal is done early. */
|
||||||
|
protected boolean isDone() { return false; /* default value */ }
|
||||||
|
/** Returns a result of a visit (if needed). */
|
||||||
|
protected R result() { return null; /* default value */ }
|
||||||
|
/** Returns the final result of the DFS execute method. */
|
||||||
|
protected R finalResult(R r) { return r; /* default value */ }
|
||||||
|
//end#fragment auxiliary
|
||||||
|
//begin#fragment Tail
|
||||||
|
} // end of DFS class
|
||||||
|
//end#fragment Tail
|
||||||
102
graph/Dijkstra.java
Normal file
102
graph/Dijkstra.java
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package graph;
|
||||||
|
|
||||||
|
import priorityqueue.AdaptablePriorityQueue;
|
||||||
|
import priorityqueue.Entry;
|
||||||
|
import priorityqueue.heap.HeapAdaptablePriorityQueue;
|
||||||
|
import utility.DefaultComparator;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dijkstra's algorithm for the single-source shortest path problem in
|
||||||
|
* an undirected graph whose edges have integer weights.
|
||||||
|
*
|
||||||
|
* <p>To execute the algorithm, use the {@link
|
||||||
|
* #execute(Graph,Vertex,Object) execute} method, and then make
|
||||||
|
* subsequent calls to the {@link #getDist(Vertex) getDist} method to
|
||||||
|
* obtain the shortest distance from the start to any given vertex.
|
||||||
|
*
|
||||||
|
* @author Roberto Tamassia, Michael Goodrich, Eric Zamore
|
||||||
|
*/
|
||||||
|
|
||||||
|
//begin#fragment execute
|
||||||
|
/* Dijkstra's algorithm for the single-source shortest path problem
|
||||||
|
* in an undirected graph whose edges have non-negative integer weights. */
|
||||||
|
public class Dijkstra<V, E> {
|
||||||
|
/** Infinity value. */
|
||||||
|
protected static final Integer INFINITE = Integer.MAX_VALUE;
|
||||||
|
/** Input graph. */
|
||||||
|
protected Graph<V, E> graph;
|
||||||
|
/** Decoration key for edge weights */
|
||||||
|
protected Object WEIGHT;
|
||||||
|
/** Decoration key for vertex distances */
|
||||||
|
protected Object DIST = new Object();
|
||||||
|
/** Decoration key for entries in the priority queue */
|
||||||
|
protected Object ENTRY = new Object();
|
||||||
|
/** Auxiliary priority queue. */
|
||||||
|
protected AdaptablePriorityQueue<Integer, Vertex<V>> Q;
|
||||||
|
/** Executes Dijkstra's algorithm.
|
||||||
|
* @param g Input graph
|
||||||
|
* @param s Source vertex
|
||||||
|
* @param w Weight decoration object */
|
||||||
|
public void execute(Graph<V, E> g, Vertex<V> s, Object w) throws InvalidKeyException{
|
||||||
|
graph = g;
|
||||||
|
WEIGHT = w;
|
||||||
|
DefaultComparator dc = new DefaultComparator();
|
||||||
|
Q = new HeapAdaptablePriorityQueue<Integer, Vertex<V>>(dc);
|
||||||
|
dijkstraVisit(s);
|
||||||
|
}
|
||||||
|
/** Get the distance of a vertex from the source vertex.
|
||||||
|
//end#fragment execute
|
||||||
|
* This method returns the length of a shortest path from the source
|
||||||
|
* to <tt>u</tt> after {@link #execute(Graph,Vertex,Object) execute}
|
||||||
|
* has been called.
|
||||||
|
//begin#fragment execute
|
||||||
|
* @param u Start vertex for the shortest path tree */
|
||||||
|
public int getDist(Vertex<V> u) throws InvalidKeyException{
|
||||||
|
return (Integer) u.get(DIST);
|
||||||
|
}
|
||||||
|
//end#fragment execute
|
||||||
|
|
||||||
|
//begin#fragment dijkstraVisit
|
||||||
|
/** The actual execution of Dijkstra's algorithm.
|
||||||
|
* @param v source vertex.
|
||||||
|
*/
|
||||||
|
protected void dijkstraVisit (Vertex<V> v) throws InvalidKeyException{
|
||||||
|
// store all the vertices in priority queue Q
|
||||||
|
for (Vertex<V> u: graph.vertices()) {
|
||||||
|
int u_dist;
|
||||||
|
if (u==v)
|
||||||
|
u_dist = 0;
|
||||||
|
else
|
||||||
|
u_dist = INFINITE;
|
||||||
|
Entry<Integer, Vertex<V>> u_entry = Q.insert(u_dist, u); // autoboxing
|
||||||
|
u.put(ENTRY, u_entry);
|
||||||
|
}
|
||||||
|
// grow the cloud, one vertex at a time
|
||||||
|
while (!Q.isEmpty()) {
|
||||||
|
// remove from Q and insert into cloud a vertex with minimum distance
|
||||||
|
Entry<Integer, Vertex<V>> u_entry = Q.min();
|
||||||
|
Vertex<V> u = u_entry.getValue();
|
||||||
|
int u_dist = u_entry.getKey();
|
||||||
|
Q.remove(u_entry); // remove u from the priority queue
|
||||||
|
u.put(DIST,u_dist); // the distance of u is final
|
||||||
|
u.remove(ENTRY); // remove the entry decoration of u
|
||||||
|
if (u_dist == INFINITE)
|
||||||
|
continue; // unreachable vertices are not processed
|
||||||
|
// examine all the neighbors of u and update their distances
|
||||||
|
for (Edge<E> e: graph.incidentEdges(u)) {
|
||||||
|
Vertex<V> z = graph.opposite(u,e);
|
||||||
|
Entry<Integer, Vertex<V>> z_entry
|
||||||
|
= (Entry<Integer, Vertex<V>>) z.get(ENTRY);
|
||||||
|
if (z_entry != null) { // check that z is in Q, i.e., not in the cloud
|
||||||
|
int e_weight = (Integer) e.get(WEIGHT);
|
||||||
|
int z_dist = z_entry.getKey();
|
||||||
|
if ( u_dist + e_weight < z_dist ) // relaxation of edge e = (u,z)
|
||||||
|
Q.replaceKey(z_entry, u_dist + e_weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end#fragment dijkstraVisit
|
||||||
|
} // end of Dijkstra class
|
||||||
58
graph/FindCycleDFS.java
Normal file
58
graph/FindCycleDFS.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package graph;
|
||||||
|
//begin#fragment FindCycleDFS
|
||||||
|
|
||||||
|
import position.NodePositionList;
|
||||||
|
import position.Position;
|
||||||
|
import position.PositionList;
|
||||||
|
|
||||||
|
/** This class specializes DFS to find a cycle. */
|
||||||
|
//end#fragment FindCycleDFS
|
||||||
|
/* @author Roberto Tamassia, Michael Goodrich, Eric Zamore
|
||||||
|
*/
|
||||||
|
//begin#fragment FindCycleDFS
|
||||||
|
public class FindCycleDFS<V, E>
|
||||||
|
extends DFS<V, E, Object, Iterable<Position>> {
|
||||||
|
protected PositionList<Position> cycle; // sequence of edges of the cycle
|
||||||
|
protected boolean done;
|
||||||
|
protected Vertex<V> cycleStart;
|
||||||
|
//end#fragment FindCycleDFS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the DFS algorithm.
|
||||||
|
* @return collection containing the vertices and
|
||||||
|
* edges of a cycle.
|
||||||
|
*/
|
||||||
|
//begin#fragment FindCycleDFS
|
||||||
|
public void setup() {
|
||||||
|
cycle = new NodePositionList<Position>();
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
|
protected void startVisit(Vertex<V> v) { cycle.addLast(v); }
|
||||||
|
protected void finishVisit(Vertex<V> v) {
|
||||||
|
cycle.remove(cycle.last()); // remove v from cycle
|
||||||
|
if (!cycle.isEmpty()) cycle.remove(cycle.last()); // remove edge into v from cycle
|
||||||
|
}
|
||||||
|
protected void traverseDiscovery(Edge<E> e, Vertex<V> from) {
|
||||||
|
cycle.addLast(e);
|
||||||
|
}
|
||||||
|
protected void traverseBack(Edge<E> e, Vertex<V> from) {
|
||||||
|
cycle.addLast(e); // back edge e creates a cycle
|
||||||
|
cycleStart = graph.opposite(from, e);
|
||||||
|
cycle.addLast(cycleStart); // first vertex completes the cycle
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
protected boolean isDone() { return done; }
|
||||||
|
public Iterable<Position> finalResult(Iterable<Position> r) {
|
||||||
|
// remove the vertices and edges from start to cycleStart
|
||||||
|
if (!cycle.isEmpty()) {
|
||||||
|
for (Position<Position> p: cycle.positions()) {
|
||||||
|
if (p.element() == cycleStart)
|
||||||
|
break;
|
||||||
|
cycle.remove(p); // remove vertex from cycle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cycle; // list of the vertices and edges of the cycle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end#fragment FindCycleDFS
|
||||||
|
|
||||||
43
graph/FindPathDFS.java
Normal file
43
graph/FindPathDFS.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package graph;
|
||||||
|
|
||||||
|
//begin#fragment FindPathDFS
|
||||||
|
|
||||||
|
import position.NodePositionList;
|
||||||
|
import position.Position;
|
||||||
|
import position.PositionList;
|
||||||
|
|
||||||
|
/** Class specializing DFS to find a path between a start vertex and a target
|
||||||
|
* vertex. It assumes the target vertex is passed as the info object to the
|
||||||
|
* execute method. It returns an iterable list of the vertices and edges
|
||||||
|
* comprising the path from start to info. The returned path is empty if
|
||||||
|
* info is unreachable from start. */
|
||||||
|
public class FindPathDFS<V, E>
|
||||||
|
extends DFS<V, E, Vertex<V>, Iterable<Position>> {
|
||||||
|
protected PositionList<Position> path;
|
||||||
|
protected boolean done;
|
||||||
|
/** Setup method to initialize the path. */
|
||||||
|
public void setup() {
|
||||||
|
path = new NodePositionList<Position>();
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
|
protected void startVisit(Vertex<V> v) {
|
||||||
|
path.addLast(v); // add vertex v to path
|
||||||
|
if (v == info)
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
protected void finishVisit(Vertex<V> v) {
|
||||||
|
path.remove(path.last()); // remove v from path
|
||||||
|
if(!path.isEmpty()) // if v is not the start vertex
|
||||||
|
path.remove(path.last()); // remove discovery edge into v from path
|
||||||
|
}
|
||||||
|
protected void traverseDiscovery(Edge<E> e, Vertex<V> from) {
|
||||||
|
path.addLast(e); // add edge e to the path
|
||||||
|
}
|
||||||
|
protected boolean isDone() {
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
public Iterable<Position> finalResult(Iterable<Position> r) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end#fragment FindPathDFS
|
||||||
52
graph/Kruskal.java
Normal file
52
graph/Kruskal.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package graph;
|
||||||
|
|
||||||
|
|
||||||
|
import partition.ListPartition;
|
||||||
|
import partition.Partition;
|
||||||
|
import position.NodePositionList;
|
||||||
|
import position.PositionList;
|
||||||
|
import priorityqueue.Entry;
|
||||||
|
import priorityqueue.PriorityQueue;
|
||||||
|
import priorityqueue.heap.HeapPriorityQueue;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
|
public class Kruskal<V, E> {
|
||||||
|
protected Graph<V, E> graph;
|
||||||
|
protected Object WEIGHT;
|
||||||
|
protected PositionList<Edge<E>> EList;
|
||||||
|
|
||||||
|
protected PriorityQueue<Double, Edge<E>> Q;
|
||||||
|
|
||||||
|
public Iterable<Edge<E>> execute(Graph<V, E> g, Object w) throws InvalidKeyException{
|
||||||
|
graph = g;
|
||||||
|
WEIGHT = w;
|
||||||
|
Q = new HeapPriorityQueue<Double, Edge<E>>();
|
||||||
|
EList = new NodePositionList<Edge<E>>();
|
||||||
|
KruskalAlg();
|
||||||
|
return EList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void KruskalAlg() throws InvalidKeyException{
|
||||||
|
Partition<Vertex<V>> P = new ListPartition<Vertex<V>>();
|
||||||
|
|
||||||
|
for (Vertex<V> w : graph.vertices())
|
||||||
|
P.makeSet(w);
|
||||||
|
|
||||||
|
for (Edge<E> e : graph.edges())
|
||||||
|
Q.insert((Double) e.get(WEIGHT), e);
|
||||||
|
|
||||||
|
while (EList.size() < graph.numVertices() - 1) {
|
||||||
|
Entry<Double, Edge<E>> e_entry = Q.removeMin();
|
||||||
|
Edge<E> e = e_entry.getValue();
|
||||||
|
Vertex<V> endV[] = graph.endVertices(e);
|
||||||
|
Vertex<V> u = endV[0];
|
||||||
|
Vertex<V> v = endV[1];
|
||||||
|
|
||||||
|
if (P.find(u) != P.find(v)) {
|
||||||
|
P.union(P.find(u), P.find(v));
|
||||||
|
EList.addLast(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
graph/gioel.rar
Normal file
BIN
graph/gioel.rar
Normal file
Binary file not shown.
Reference in New Issue
Block a user