1
1
package chapter4 ;
2
2
3
3
import java .util .ArrayList ;
4
+ import java .util .Arrays ;
4
5
import java .util .List ;
6
+ import java .util .stream .Collectors ;
7
+
8
+ import chapter2 .GenericSearch ;
9
+ import chapter2 .GenericSearch .Node ;
5
10
6
11
// V is the type of the vertices in the Graph
7
12
public class Graph <V > {
@@ -17,14 +22,135 @@ public Graph() {
17
22
public Graph (List <V > vertices ) {
18
23
this .vertices = new ArrayList <>(vertices );
19
24
edges = new ArrayList <>();
20
- for (int i = 0 ; i < this .vertices . size (); i ++ ) {
25
+ for (V element : this .vertices ) {
21
26
edges .add (new ArrayList <Edge >());
22
27
}
23
28
}
24
29
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
25
110
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 ());
27
143
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
+ }
28
154
}
29
155
30
156
}
0 commit comments