java programming - university of wisconsin–la...
TRANSCRIPT
JavaProgrammingGraphs
Graphs
• Agraphisamathematicalabstractionthatincludes– Vertices
• anobjectinthegraph– Edges
• aconnectionbetweentwovertices.Writtenas(V1,V2)meaningthereisaconnectionbetweenV1andV2
• Edgesmaybedirected,inwhichcasetheedgesareknownasarcs.(V1,V2)thenmeansFROMV1TOV2.
• Agraphisaset ofverticesandaset ofarcs– G=(V,E)
• Visasetofvertices• Eisasetofedges
Example
• DirectedGraphExample:– V={A,B,C,D,E}– E={(A,E),(A,B),(B,A),(B,D),(C,E),(D,C),(E,B),(E,C),(E,D)}– G=(V,E)
Graphs:Definitions
• Adjacency:– AssumethatUandVareverticesinsomegraph.VertexUisadjacenttovertexVif thereisanarc(U,V)in
thegraph.• Loop:
– anyarcsuchthatthefirstandsecondnodesofthearcarethesame.• In-degreeofV.
– ThenumberofarcsinthegraphhavingVasthesecondvertex.• Out-degreeofV.
– ThenumberofarcsinthegraphhavingVasthefirstvertex.• OrderofG:
– thenumberofvertices.• SizeofG:
– thenumberofarcs.• Path:
– Asequenceofverticessuchthatforeverypairofadjacentverticesinthesequence thereisacorrespondingarcinthegraph.Asequencecontainingasinglevertexisaalsoapath.
– Asequencewithoutrepeatedverticesisasimplepath.• PathLength:
– thenumberofarcsinthepath.• Cycle:
– Acycleisapathwherethelengthisgreaterthanzeroandthefirstandlastvertexarethesame.Agraphwithoutanycyclesisknownasanacyclicgraph.
Graphs
• Theorder?• Thesize?• IsAadjacenttoE?• IsEadjacenttoA?• Out-degreeofA?• In-degreeofA?• Istherealoop?• Is[A,E,C,E]apath?• Is[A,B,A]apath?• Isthegraphacyclic?
DirectedGraph Interface
• Javadoesn’thaveagraphAPI.WedefineourownGraphinterface.
DirectedGraph Interface
• TheGraphinterface– Theinterfaceisgenericandallowsforverticesandedgesofanytype– Themethodsallowustocontrolthegraphstructureandinquireabout
relevantpropertiesofthegraph.
public interface Graph<V,E> {public boolean containsEdge(E e);public boolean containsVertex(V v);public E addEdge(E e, V v1, V v2);public V addVertex(V v);public Collection<V> vertices();public Collection<E> edges();public Collection<V> getPredecessors(V v);public Collection<V> getSuccessors(V v);public int inDegree(V v);public int outDegree(V v);public V getV1(E e);public V getV2(E e);public E getEdge(V v1, V v2);public E removeEdge(E e);public V removeVertex(V v); public int order();public int size(); public String toString(Collection<E> edges);
}
public abstract class AbstractGraph<V,E> implements Graph<V,E> {
@Overridepublic int size() {
return edges().size();}
@Overridepublic int order() {
return vertices().size();}
@Overridepublic boolean containsEdge(E e) {
return edges().contains(e);}
@Overridepublic boolean containsVertex(V v) {
return vertices().contains(v);}
@Overridepublic int inDegree(V v) {
return getPredecessors(v).size();}
@Overridepublic int outDegree(V v) {
return getSuccessors(v).size();}
}
public abstract class AbstractMapGraph<V, E> extends AbstractGraph<V,E> {protected Set<V> vertices;protected HashMap<E, Pair<V>> edges;
protected class Pair<V> {V source, destination;
Pair(V src, V dest) {this.source = src;this.destination = dest;
}}
public AbstractMapGraph() {vertices = new HashSet<>();edges = new HashMap<>();
}
public AbstractMapGraph(Graph<V, E> other) {this();for (V v : other.vertices()) {
addVertex(v);}
for (E edge : other.edges()) {V v1 = other.getV1(edge);V v2 = other.getV2(edge);addEdge(edge, v1, v2);
}}
// other methods on following slides }
@Overridepublic E addEdge(E e, V source, V destination) {
if (getEdge(source, destination) != null) {throw new IllegalArgumentException();
}
edges.put(e, new Pair(addVertex(source), addVertex(destination)));return e;
}
@Overridepublic V addVertex(V v) {
if (!containsVertex(v)) {vertices.add(v);
}return v;
}
@Overridepublic Collection<V> vertices() {
return new java.util.LinkedList<>(vertices);}
@Overridepublic Collection<E> edges() {
return new java.util.LinkedList<>(edges.keySet());}
@Overridepublic Collection<V> getPredecessors(V v) {
List<V> predecessors = new LinkedList<>();for (Pair<V> p : edges.values()) {
if (v.equals(p.destination)) {predecessors.add(p.source);
}}return predecessors;
}
@Overridepublic Collection<V> getSuccessors(V v) {
List<V> successors = new LinkedList<>();for (Pair<V> p : edges.values()) {
if (v.equals(p.source)) {successors.add(p.destination);
}}return successors;
}
Topologicalsort
• Topologicalsort:alinearorderingofverticesinadirectedgraphsuchthatforeveryarc(u,v)inthegrahp,ucomesbeforevintheordering– Anyorderinginwhichallthearrowsgo“right”isavalidsolution.– Anydirectedgraphwithacyclecannotbetopologicallysorted
Algorithm
algorithm topologicalSort(G) {L ← An empty listS ← A list of all nodes in G with in-degree 0while S is not empty do
M ← S.removeFirst()L.append(M)foreach node N with an edge E from M to N do
remove edge E from Gif N has in-degree 0 then
S.append(N)endif
endforeachendwhile
if the size of G is greater than 0 then return error (G is not acyclic)
else return L
public class GraphUtilities {public static <V,E> List<V> topologicalSort(DirectedGraph<V,E> graph) {
DirectedGraph<V, E> copy = new DirectedMapGraph<>(graph);List<V> nodeSet = new LinkedList<>();for (V v : copy.vertices()) {
if (copy.inDegree(v) == 0) {nodeSet.add(v);
}}List<V> sorted = new ArrayList<>();while (!nodeSet.isEmpty()) {
V fromNode = nodeSet.remove(0);sorted.add(fromNode);for (V toNode : copy.getSuccessors(fromNode)) {
E edge = copy.getEdge(fromNode, toNode);copy.removeEdge(edge);if (copy.inDegree(toNode) == 0) {
nodeSet.add(toNode);}
}}
if (copy.size() > 0) {throw new IllegalStateException("Graph cannot be sorted");
} else {return sorted;
}
} }
(Minimum)SpanningTrees
• SpanningTree:Givenaconnected,undirected,weightedgraph,aspanningtreeis– asub-graph– atree(undirectedgraphwhereanytwoverticesareconnectedbyexactlyonesimplepath)– atreethatcontainsallvertices– Onegraphmayhavemanyspanningtrees
• Minimum spanningtree:– Aspanningtreesuchthatthesumoftheedgeweightsofthetreeislessthanorequaltothesumof
edgeweightsofeveryotherspanningtree.
PrimsAlgorithm
• Agreedyalgorithmthatfindstheminimumspanningtreeofaconnected,weightedundirectedgraph.
algorithm prim(G) {MST ← An empty graphif(G.order() == 0) return MST;
MST.addVertex(randomly selected vertex of G)while MST.order() < G.order() do
EDGE ← an edge of G(the smallest weighted edge where exactly one of the vertices is in MST)
MST.addVertex(the vertex of EDGE that is not in MST)MST.addEdge(EDGE, vertex 1 of EDGE, vertex 2 of EDGE)
endwhile
return MST
PrimExample
C C
F
2
C
F
D 24
A
C
F
D
1
24
PrimExample
A
C
F
D
1
24
A
B C
F
D
15
24
A
B C
FE
D
15
3 24
MinimumSpanningTree
WeightedInterface
• Wecandefineaninterfacethatdescribesanobjecthavinga‘weight’.
public interface Weighted<E extends Number> { public E weight();public double doubleValue();
}
public static <V, E extends Number> Weighted<E> chooseMinWeightEdge(Graph<V, Weighted<E>> graph, Graph<V, Weighted<E>> mst) {
double minWeight = Double.POSITIVE_INFINITY;Weighted<E> selectedEdge = null;for(Weighted<E> edge : graph.edges()) {
if(mst.containsVertex(graph.getV1(edge)) && !mst.containsVertex(graph.getV2(edge)) ||mst.containsVertex(graph.getV2(edge)) && !mst.containsVertex(graph.getV1(edge))) {if(edge.weight().doubleValue() < minWeight) {
selectedEdge = edge;minWeight = edge.weight().doubleValue();
}}
}return selectedEdge;
}
public static <V, E extends Number> UndirectedGraph<V, Weighted<E>> minimumSpanningTreePrim(UndirectedGraph<V, Weighted<E>> graph) {UndirectedGraph<V, Weighted<E>> mst = new UndirectedMapGraph();mst.addVertex(graph.vertices().iterator().next());
while(mst.order() < graph.order()) {Weighted<E> edge = chooseMinWeightEdge(graph, mst);V newVertex = mst.containsVertex(graph.getV1(edge)) ? graph.getV2(edge) : graph.getV1(edge);mst.addVertex(newVertex);mst.addEdge(edge, graph.getV1(edge), graph.getV2(edge));
}
return mst; }