1
2
3
4
5
6
7
8
9
10
11 package edu.uci.ics.jung.algorithms.generators;
12
13 import java.util.ArrayList;
14 import java.util.List;
15
16 import com.google.common.base.Supplier;
17
18 import edu.uci.ics.jung.graph.Graph;
19 import edu.uci.ics.jung.graph.util.EdgeType;
20
21
22
23
24
25
26
27
28
29
30
31
32 public class Lattice2DGenerator<V,E> implements GraphGenerator<V,E>
33 {
34 protected int row_count;
35 protected int col_count;
36 protected boolean is_toroidal;
37 protected boolean is_directed;
38 protected Supplier<? extends Graph<V, E>> graph_factory;
39 protected Supplier<V> vertex_factory;
40 protected Supplier<E> edge_factory;
41 private List<V> v_array;
42
43
44
45
46
47
48
49
50
51
52
53 public Lattice2DGenerator(Supplier<? extends Graph<V,E>> graph_factory, Supplier<V> vertex_factory,
54 Supplier<E> edge_factory, int latticeSize, boolean isToroidal)
55 {
56 this(graph_factory, vertex_factory, edge_factory, latticeSize, latticeSize, isToroidal);
57 }
58
59
60
61
62
63
64
65
66
67
68
69
70 public Lattice2DGenerator(Supplier<? extends Graph<V,E>> graph_factory, Supplier<V> vertex_factory,
71 Supplier<E> edge_factory, int row_count, int col_count, boolean isToroidal)
72 {
73 if (row_count < 2 || col_count < 2)
74 {
75 throw new IllegalArgumentException("Row and column counts must each be at least 2.");
76 }
77
78 this.row_count = row_count;
79 this.col_count = col_count;
80 this.is_toroidal = isToroidal;
81 this.graph_factory = graph_factory;
82 this.vertex_factory = vertex_factory;
83 this.edge_factory = edge_factory;
84 this.is_directed = (graph_factory.get().getDefaultEdgeType() == EdgeType.DIRECTED);
85 }
86
87
88
89
90
91
92 public Graph<V,E> get()
93 {
94 int vertex_count = row_count * col_count;
95 Graph<V,E> graph = graph_factory.get();
96 v_array = new ArrayList<V>(vertex_count);
97 for (int i = 0; i < vertex_count; i++)
98 {
99 V v = vertex_factory.get();
100 graph.addVertex(v);
101 v_array.add(i, v);
102 }
103
104 int start = is_toroidal ? 0 : 1;
105 int end_row = is_toroidal ? row_count : row_count - 1;
106 int end_col = is_toroidal ? col_count : col_count - 1;
107
108
109
110 for (int i = 0; i < end_row; i++)
111 for (int j = 0; j < col_count; j++)
112 graph.addEdge(edge_factory.get(), getVertex(i,j), getVertex(i+1, j));
113
114 for (int i = 0; i < row_count; i++)
115 for (int j = 0; j < end_col; j++)
116 graph.addEdge(edge_factory.get(), getVertex(i,j), getVertex(i, j+1));
117
118
119 if (graph.getDefaultEdgeType() == EdgeType.DIRECTED)
120 {
121
122 for (int i = start; i < row_count; i++)
123 for (int j = 0; j < col_count; j++)
124 graph.addEdge(edge_factory.get(), getVertex(i,j), getVertex(i-1, j));
125
126 for (int i = 0; i < row_count; i++)
127 for (int j = start; j < col_count; j++)
128 graph.addEdge(edge_factory.get(), getVertex(i,j), getVertex(i, j-1));
129 }
130
131 return graph;
132 }
133
134
135
136
137
138
139
140 public int getGridEdgeCount()
141 {
142 int boundary_adjustment = (is_toroidal ? 0 : 1);
143 int vertical_edge_count = col_count * (row_count - boundary_adjustment);
144 int horizontal_edge_count = row_count * (col_count - boundary_adjustment);
145
146 return (vertical_edge_count + horizontal_edge_count) * (is_directed ? 2 : 1);
147 }
148
149 protected int getIndex(int i, int j)
150 {
151 return ((mod(i, row_count)) * col_count) + (mod(j, col_count));
152 }
153
154 protected int mod(int i, int modulus)
155 {
156 int i_mod = i % modulus;
157 return i_mod >= 0 ? i_mod : i_mod + modulus;
158 }
159
160
161
162
163
164
165 protected V getVertex(int i, int j)
166 {
167 return v_array.get(getIndex(i, j));
168 }
169
170
171
172
173
174 protected V getVertex(int i)
175 {
176 return v_array.get(i);
177 }
178
179
180
181
182
183 protected int getRow(int i)
184 {
185 return i / row_count;
186 }
187
188
189
190
191
192 protected int getCol(int i)
193 {
194 return i % col_count;
195 }
196 }