11package chapter4 ;
22
33import java .util .ArrayList ;
4+ import java .util .Arrays ;
45import java .util .List ;
6+ import java .util .stream .Collectors ;
7+ 8+ import chapter2 .GenericSearch ;
9+ import chapter2 .GenericSearch .Node ;
510
611// V is the type of the vertices in the Graph
712public class Graph <V > {
@@ -17,14 +22,135 @@ public Graph() {
1722 public Graph (List <V > vertices ) {
1823 this .vertices = new ArrayList <>(vertices );
1924 edges = new ArrayList <>();
20- for (int i = 0 ; i < this .vertices . size (); i ++ ) {
25+ for (V element : this .vertices ) {
2126 edges .add (new ArrayList <Edge >());
2227 }
2328 }
2429
30+ // Number of vertices
31+ public int getVertexCount () {
32+ return vertices .size ();
33+ }
34+ 35+ // Number of edges
36+ public int getEdgeCount () {
37+ return edges .stream ().mapToInt (al -> al .size ()).sum ();
38+ }
39+ 40+ // Add a vertex to the graph and return its index
41+ public int addVertex (V vertex ) {
42+ vertices .add (vertex );
43+ edges .add (new ArrayList <>());
44+ return getVertexCount () - 1 ;
45+ }
46+ 47+ // This is an undirected graph, so we always add
48+ // edges in both directions
49+ public void addEdge (Edge edge ) {
50+ edges .get (edge .u ).add (edge );
51+ edges .get (edge .v ).add (edge .reversed ());
52+ }
53+ 54+ // Add an edge using vertex indices (convenience method)
55+ public void addEdge (int u , int v ) {
56+ addEdge (new Edge (u , v ));
57+ }
58+ 59+ // Add an edge by looking up vertex indices (convenience method)
60+ public void addEdge (V first , V second ) {
61+ addEdge (new Edge (indexOf (first ), indexOf (second )));
62+ }
63+ 64+ // Find the vertex at a specific index
65+ public V vertexAt (int index ) {
66+ return vertices .get (index );
67+ }
68+ 69+ // Find the index of a vertex in the graph
70+ public int indexOf (V vertex ) {
71+ return vertices .indexOf (vertex );
72+ }
73+ 74+ // Find the vertices that a vertex at some index is connected to
75+ public List <V > neighborsOf (int index ) {
76+ return edges .get (index ).stream ()
77+ .map (edge -> vertexAt (edge .v ))
78+ .collect (Collectors .toList ());
79+ }
80+ 81+ // Look up a vertice's index and find its neighbors (convenience method)
82+ public List <V > neighborsOf (V vertex ) {
83+ return neighborsOf (indexOf (vertex ));
84+ }
85+ 86+ // Return all of the edges associated with a vertex at some index
87+ public List <Edge > edgesOf (int index ) {
88+ return edges .get (index );
89+ }
90+ 91+ // Look up the index of a vertex and return its edges (convenience method)
92+ public List <Edge > edgesOf (V vertex ) {
93+ return edgesOf (indexOf (vertex ));
94+ }
95+ 96+ // Make it easy to pretty-print a Graph
97+ @ Override
98+ public String toString () {
99+ StringBuilder sb = new StringBuilder ();
100+ for (int i = 0 ; i < vertices .size (); i ++) {
101+ sb .append (vertexAt (i ).toString ());
102+ sb .append (" -> " );
103+ sb .append (Arrays .toString (neighborsOf (i ).toArray ()));
104+ sb .append (System .lineSeparator ());
105+ }
106+ return sb .toString ();
107+ }
108+ 109+ // Test basic Graph construction
25110 public static void main (String [] args ) {
26- // TODO Auto-generated method stub
111+ // Represents the 15 largest MSAs in the United States
112+ Graph <String > cityGraph = new Graph <>(
113+ List .of ("Seattle" , "San Francisco" , "Los Angeles" , "Riverside" , "Phoenix" , "Chicago" , "Boston" ,
114+ "New York" , "Atlanta" , "Miami" , "Dallas" , "Houston" , "Detroit" , "Philadelphia" , "Washington" ));
115+ 116+ cityGraph .addEdge ("Seattle" , "Chicago" );
117+ cityGraph .addEdge ("Seattle" , "San Francisco" );
118+ cityGraph .addEdge ("San Francisco" , "Riverside" );
119+ cityGraph .addEdge ("San Francisco" , "Los Angeles" );
120+ cityGraph .addEdge ("Los Angeles" , "Riverside" );
121+ cityGraph .addEdge ("Los Angeles" , "Phoenix" );
122+ cityGraph .addEdge ("Riverside" , "Phoenix" );
123+ cityGraph .addEdge ("Riverside" , "Chicago" );
124+ cityGraph .addEdge ("Phoenix" , "Dallas" );
125+ cityGraph .addEdge ("Phoenix" , "Houston" );
126+ cityGraph .addEdge ("Dallas" , "Chicago" );
127+ cityGraph .addEdge ("Dallas" , "Atlanta" );
128+ cityGraph .addEdge ("Dallas" , "Houston" );
129+ cityGraph .addEdge ("Houston" , "Atlanta" );
130+ cityGraph .addEdge ("Houston" , "Miami" );
131+ cityGraph .addEdge ("Atlanta" , "Chicago" );
132+ cityGraph .addEdge ("Atlanta" , "Washington" );
133+ cityGraph .addEdge ("Atlanta" , "Miami" );
134+ cityGraph .addEdge ("Miami" , "Washington" );
135+ cityGraph .addEdge ("Chicago" , "Detroit" );
136+ cityGraph .addEdge ("Detroit" , "Boston" );
137+ cityGraph .addEdge ("Detroit" , "Washington" );
138+ cityGraph .addEdge ("Detroit" , "New York" );
139+ cityGraph .addEdge ("Boston" , "New York" );
140+ cityGraph .addEdge ("New York" , "Philadelphia" );
141+ cityGraph .addEdge ("Philadelphia" , "Washington" );
142+ System .out .println (cityGraph .toString ());
27143
144+ Node <String > bfsResult = GenericSearch .bfs ("Boston" ,
145+ v -> v .equals ("Miami" ),
146+ cityGraph ::neighborsOf );
147+ if (bfsResult == null ) {
148+ System .out .println ("No solution found using breadth-first search!" );
149+ } else {
150+ List <String > path = GenericSearch .nodeToPath (bfsResult );
151+ System .out .println ("Path from Boston to Miami:" );
152+ System .out .println (path );
153+ }
28154 }
29155
30156}
0 commit comments