2
2
// XXX see README_graph_search
3
3
import GraphTracer from '../../components/DataStructures/Graph/GraphTracer' ;
4
4
import Array2DTracer from '../../components/DataStructures/Array/Array2DTracer' ;
5
-
6
- // Colors for array, graph nodes, graph edges
7
- // OMG, colors for array and graph require different types and are
8
- // inconsistent!
9
- // XXX not sure how this interracts with color perception options -
10
- // doesnt seem to work like this
11
- // XXX should do similar for edge colors?
12
- const FRONTIER_COLOR_A = '0' ; // Blue
13
- const FRONTIER_COLOR_N = 4 ; // Blue
14
- const FRONTIER_COLOR_E = 4 ; // Blue
15
- const N_M_COLOR_E = 2 ; // Orange - edge between n and m
16
- const FINALISED_COLOR_A = '1' ; // Green
17
- const FINALISED_COLOR_N = 1 ; // Green
18
- const FINALISED_COLOR_E = 3 ; // Red
19
- // if we find a path to end node:
20
- const SUCCESS_COLOR_A = '1' ; // Green
21
- const SUCCESS_COLOR_E = 1 ; // Green
5
+ import { colors } from './graphSearchColours' ;
22
6
23
7
export default {
24
8
initVisualisers ( ) {
@@ -31,8 +15,6 @@ export default {
31
15
instance : new Array2DTracer ( 'array' , null , 'Parent array, Seen array & Queue' ) ,
32
16
order : 1 ,
33
17
} ,
34
-
35
-
36
18
} ;
37
19
} ,
38
20
@@ -145,7 +127,7 @@ export default {
145
127
146
128
// select start node in blue
147
129
vis . array . select ( 0 , b + 1 ) ;
148
- vis . graph . colorNode ( b , FRONTIER_COLOR_N ) ;
130
+ vis . graph . colorNode ( b , colors . FRONTIER_N ) ;
149
131
} ,
150
132
[ [ displayedNodes , displayedParent , displayedVisited ] , displayedQueue , explored , visited , s , Nodes ]
151
133
) ;
@@ -166,23 +148,28 @@ export default {
166
148
) ;
167
149
168
150
// while Nodes not empty B2
169
- while ( Nodes . length > 0 ) {
151
+ // XXX ?nice to have while true and break out of the
152
+ // loop after the chunk (conditionally) so when the loop exits
153
+ // we have an extra chunk at the start of the loop
154
+ // while (Nodes.length > 0) {
155
+ /* eslint-disable no-constant-condition */
156
+ while ( true ) {
170
157
chunker . add (
171
158
2 ,
172
159
( vis , c_n , c_lastNei , c_parent , c_visited , c_Nodes ) => {
173
160
// removes m if it exists; need to redo node selection etc
174
- // for green nodes:(
161
+ // for green nodes:
175
162
vis . array . assignVariable ( 'm' , 2 , undefined ) ; // removes m if there
176
163
// highlight all nodes explored in green in the array
177
164
// and all other seen nodes in blue in the array
178
165
for ( let i = 0 ; i < c_visited . length ; i ++ )
179
166
{
180
167
if ( c_visited [ i ] == true )
181
168
if ( ! c_Nodes . includes ( i ) ) {
182
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FINALISED_COLOR_A ) ;
169
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FINALISED_A ) ;
183
170
} else {
184
171
// vis.array.deselect(0, i + 1);
185
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FRONTIER_COLOR_A ) ;
172
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FRONTIER_A ) ;
186
173
}
187
174
}
188
175
@@ -193,24 +180,17 @@ export default {
193
180
vis . graph . removeEdgeColor ( c_n , c_lastNei ) ;
194
181
let prevColor ;
195
182
if ( c_Nodes . includes ( c_lastNei ) )
196
- prevColor = FRONTIER_COLOR_E ;
183
+ prevColor = colors . FRONTIER_E ;
197
184
else
198
- prevColor = FINALISED_COLOR_E ;
185
+ prevColor = colors . FINALISED_E ;
199
186
vis . graph . removeEdgeColor ( c_n , c_lastNei ) ;
200
187
vis . graph . colorEdge ( c_n , c_lastNei , prevColor ) ;
201
188
}
202
-
203
- // // recolor in red if it has a child
204
- // for(let i = 0; i < c_parent.length; i ++){
205
- // if (c_parent[i] == c_lastNei){
206
- // vis.graph.removeEdgeColor(i, c_lastNei);
207
- // vis.graph.colorEdge(i, c_lastNei, FRONTIER_COLOR_E);
208
- // }
209
- // }
210
189
} ,
211
190
[ n , lastNeighbor , parent , visited , Nodes ]
212
-
213
191
) ;
192
+ if ( ! ( Nodes . length > 0 ) )
193
+ break ;
214
194
215
195
// n <- dequeue(Nodes) B10
216
196
n = Nodes . shift ( ) ;
@@ -226,7 +206,7 @@ export default {
226
206
// highlight all frontier nodes
227
207
for ( let i = 0 ; i < a . length ; i ++ ) {
228
208
if ( a [ i ] == true && Nodes . includes ( i ) ) {
229
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FRONTIER_COLOR_A ) ;
209
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FRONTIER_A ) ;
230
210
// vis.array.select(0,i + 1, 0, i + 1, '1');
231
211
232
212
}
@@ -237,23 +217,23 @@ export default {
237
217
{
238
218
if ( b [ i ] == true && ! Nodes . includes ( i ) )
239
219
{
240
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FINALISED_COLOR_A ) ;
220
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FINALISED_A ) ;
241
221
vis . graph . removeNodeColor ( i ) ;
242
- vis . graph . colorNode ( i , FINALISED_COLOR_N ) ;
222
+ vis . graph . colorNode ( i , colors . FINALISED_N ) ;
243
223
}
244
224
}
245
225
246
226
// finalise edge color to n from parent
247
227
if ( c_parent [ c_n ] !== null ) {
248
228
vis . graph . removeEdgeColor ( c_n , c_parent [ c_n ] ) ;
249
- vis . graph . colorEdge ( c_n , c_parent [ c_n ] , FINALISED_COLOR_E ) ;
229
+ vis . graph . colorEdge ( c_n , c_parent [ c_n ] , colors . FINALISED_E ) ;
250
230
}
251
231
252
232
//redisplay queue
253
233
vis . array . setList ( z ) ;
254
234
} ,
255
235
[ [ displayedNodes , displayedParent , displayedVisited ] , n ,
256
- displayedQueue , explored , visited , parent , Nodes ]
236
+ displayedQueue , explored , visited , parent , Nodes ]
257
237
) ;
258
238
259
239
// If is_end_node(n) B11
@@ -276,14 +256,14 @@ displayedQueue, explored, visited, parent, Nodes]
276
256
if ( c_parent [ y ] != null )
277
257
{
278
258
vis . graph . removeEdgeColor ( c_parent [ y ] , y ) ;
279
- vis . graph . colorEdge ( c_parent [ y ] , y , FRONTIER_COLOR_E ) ;
259
+ vis . graph . colorEdge ( c_parent [ y ] , y , colors . FRONTIER_E ) ;
280
260
}
281
261
282
262
// recolor in red if it has a child
283
263
for ( let i = 0 ; i < c_parent . length ; i ++ ) {
284
264
if ( c_parent [ i ] == y ) {
285
265
vis . graph . removeEdgeColor ( i , y ) ;
286
- vis . graph . colorEdge ( i , y , FRONTIER_COLOR_E ) ;
266
+ vis . graph . colorEdge ( i , y , colors . FRONTIER_E ) ;
287
267
}
288
268
}
289
269
}
@@ -301,9 +281,9 @@ displayedQueue, explored, visited, parent, Nodes]
301
281
// + color parent array
302
282
while ( ( current != a ) && ( c_parent [ current ] != null ) )
303
283
{
304
- vis . array . select ( 1 , current + 1 , 1 , current + 1 , SUCCESS_COLOR_A ) ;
284
+ vis . array . select ( 1 , current + 1 , 1 , current + 1 , colors . SUCCESS_A ) ;
305
285
vis . graph . removeEdgeColor ( current , c_parent [ current ] ) ;
306
- vis . graph . colorEdge ( current , c_parent [ current ] , SUCCESS_COLOR_E ) ;
286
+ vis . graph . colorEdge ( current , c_parent [ current ] , colors . SUCCESS_E ) ;
307
287
current = c_parent [ current ] ;
308
288
}
309
289
} ,
@@ -334,27 +314,17 @@ displayedQueue, explored, visited, parent, Nodes]
334
314
// recolor if node has a parent or is start
335
315
if ( c_parent [ c_lastNei ] != null || c_lastNei == start ) {
336
316
vis . graph . removeEdgeColor ( c_n , c_lastNei ) ;
337
- // XXX if not just added or previously FINALISED_COLOR_E
338
317
if ( c_parent [ c_n ] === c_lastNei )
339
- vis . graph . colorEdge ( c_n , c_lastNei , FINALISED_COLOR_E ) ;
318
+ vis . graph . colorEdge ( c_n , c_lastNei , colors . FINALISED_E ) ;
340
319
else if ( c_parent [ c_lastNei ] === c_n )
341
- vis . graph . colorEdge ( c_n , c_lastNei , FRONTIER_COLOR_E ) ;
320
+ vis . graph . colorEdge ( c_n , c_lastNei , colors . FRONTIER_E ) ;
342
321
}
343
-
344
- // recolor in red if it has a child
345
- // for(let i = 0; i < c_parent.length; i ++){
346
- // if (c_parent[i] == c_lastNei){
347
- // vis.graph.removeEdgeColor(i, c_lastNei);
348
- // vis.graph.colorEdge(i, c_lastNei, FRONTIER_COLOR_E);
349
- // }
350
- // }
351
-
352
322
}
353
323
354
324
//highlight the edge connecting the neighbor
355
325
vis . graph . removeEdgeColor ( c_n , c_m ) ;
356
326
// color 2 = orange doesn't show up well - 4 = green better?
357
- vis . graph . colorEdge ( c_n , c_m , N_M_COLOR_E ) ;
327
+ vis . graph . colorEdge ( c_n , c_m , colors . N_M_E ) ;
358
328
359
329
// add var m; need to color elements again
360
330
vis . array . assignVariable ( 'm' , 2 , c_m + 1 ) ;
@@ -364,10 +334,10 @@ displayedQueue, explored, visited, parent, Nodes]
364
334
{
365
335
if ( c_visited [ i ] == true )
366
336
if ( ! c_Nodes . includes ( i ) ) {
367
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FINALISED_COLOR_A ) ;
337
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FINALISED_A ) ;
368
338
} else {
369
339
// vis.array.deselect(0, i + 1);
370
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FRONTIER_COLOR_A ) ;
340
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FRONTIER_A ) ;
371
341
}
372
342
}
373
343
} ,
@@ -404,17 +374,17 @@ displayedQueue, explored, visited, parent, Nodes]
404
374
{
405
375
if ( c_visited [ i ] == true )
406
376
if ( ! ( c_Nodes . includes ( i ) || i === c_m ) ) {
407
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FINALISED_COLOR_A ) ;
377
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FINALISED_A ) ;
408
378
} else {
409
379
// vis.array.deselect(0, i + 1);
410
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FRONTIER_COLOR_A ) ;
380
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FRONTIER_A ) ;
411
381
}
412
382
}
413
383
vis . array . setList ( y ) ;
414
384
415
385
// color the graph node in blue as seen
416
386
vis . graph . removeNodeColor ( c_m ) ;
417
- vis . graph . colorNode ( c_m , FRONTIER_COLOR_N ) ;
387
+ vis . graph . colorNode ( c_m , colors . FRONTIER_N ) ;
418
388
} ,
419
389
420
390
[ [ displayedNodes , displayedParent , displayedVisited ] , displayedQueue , explored , visited , n , m , Nodes ]
@@ -440,10 +410,10 @@ displayedQueue, explored, visited, parent, Nodes]
440
410
{
441
411
if ( z [ i ] == true || i === c )
442
412
if ( i !== c && ! Nodes . includes ( i ) ) {
443
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FINALISED_COLOR_A ) ;
413
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FINALISED_A ) ;
444
414
} else {
445
415
// vis.array.deselect(0, i + 1);
446
- vis . array . select ( 0 , i + 1 , 0 , i + 1 , FRONTIER_COLOR_A ) ;
416
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FRONTIER_A ) ;
447
417
}
448
418
}
449
419
vis . array . setList ( y ) ;
@@ -453,7 +423,7 @@ displayedQueue, explored, visited, parent, Nodes]
453
423
454
424
//highlight the edge from n to this neighbor in red
455
425
vis . graph . removeEdgeColor ( b , c ) ;
456
- vis . graph . colorEdge ( b , c , FRONTIER_COLOR_E ) ;
426
+ vis . graph . colorEdge ( b , c , colors . FRONTIER_E ) ;
457
427
458
428
459
429
// vis.array.set(x, 'BFS');
@@ -476,7 +446,7 @@ displayedQueue, explored, visited, parent, Nodes]
476
446
// if it has not been seen
477
447
if ( y [ z ] == false && Nodes . includes ( z ) ) {
478
448
vis . array . deselect ( 0 , z + 1 ) ;
479
- vis . array . select ( 0 , z + 1 , 0 , z + 1 , FINALISED_COLOR_A ) ;
449
+ vis . array . select ( 0 , z + 1 , 0 , z + 1 , colors . FINALISED_A ) ;
480
450
//vis.graph.removeNodeColor(z);
481
451
//vis.graph.colorNode(z, 4);
482
452
}
@@ -490,50 +460,48 @@ displayedQueue, explored, visited, parent, Nodes]
490
460
}
491
461
// no path found
492
462
//return B5
493
- chunker . add (
494
- 5 ,
495
- ( vis , x , y , z , a , b ) => {
496
- //remove the orange highlight from the last neighbour
497
- // XXX not needed?
498
- if ( y != null )
499
- {
500
- vis . graph . removeEdgeColor ( y , x ) ;
501
-
502
- // recolor in red if it has a parent
503
- if ( z [ y ] != null )
463
+ chunker . add (
464
+ 5 ,
465
+ ( vis , c_n , c_lastNei , c_parent , c_visited , c_Nodes ) => {
466
+ // We don't actually need to do anything here if we have a
467
+ // chunk before breaking out of the outer while loop, but
468
+ // it does no harm and we need to fix one edge color at
469
+ // least if we don't use the break coding.
470
+ //
471
+ // removes m if it exists; need to redo node selection etc
472
+ // for green nodes:
473
+ vis . array . assignVariable ( 'm' , 2 , undefined ) ; // removes m if there
474
+ // highlight all nodes explored in green in the array
475
+ // and all other seen nodes in blue in the array
476
+ for ( let i = 0 ; i < c_visited . length ; i ++ )
504
477
{
505
- vis . graph . removeEdgeColor ( z [ y ] , y ) ;
506
- vis . graph . colorEdge ( z [ y ] , y , FRONTIER_COLOR_E ) ;
507
- }
508
-
509
- // recolor in red if it has a child
510
- for ( let i = 0 ; i < z . length ; i ++ ) {
511
- if ( z [ i ] == y ) {
512
- vis . graph . removeEdgeColor ( i , y ) ;
513
- vis . graph . colorEdge ( i , y , FRONTIER_COLOR_E ) ;
514
- }
478
+ if ( c_visited [ i ] == true )
479
+ if ( ! c_Nodes . includes ( i ) ) {
480
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FINALISED_A ) ;
481
+ } else {
482
+ // vis.array.deselect(0, i + 1);
483
+ vis . array . select ( 0 , i + 1 , 0 , i + 1 , colors . FRONTIER_A ) ;
484
+ }
515
485
}
516
- }
517
- } ,
518
- [ n , lastNeighbor , parent , start , end ]
519
486
520
- ) ;
521
- } ; // End of bfs
487
+ // remove the highlight between n
488
+ // and the last visited neighbor
489
+ if ( ( c_n != null ) && ( c_lastNei != null ) ) {
522
490
491
+ vis . graph . removeEdgeColor ( c_n , c_lastNei ) ;
492
+ let prevColor ;
493
+ if ( c_Nodes . includes ( c_lastNei ) )
494
+ prevColor = colors . FRONTIER_E ;
495
+ else
496
+ prevColor = colors . FINALISED_E ;
497
+ vis . graph . removeEdgeColor ( c_n , c_lastNei ) ;
498
+ vis . graph . colorEdge ( c_n , c_lastNei , prevColor ) ;
499
+ }
500
+ } ,
501
+ [ n , lastNeighbor , parent , visited , Nodes ]
502
+ ) ;
503
+ } ; // End of bfs
523
504
524
505
bfs ( start ) ;
525
-
526
506
}
527
-
528
507
} ;
529
-
530
- // green vis.array.select(0, i + 1, 0, i + 1, '1');
531
- // blue vis.array.select(0,i + 1);
532
- // red vis.array.select(0, i + 1, 0, i + 1, '4');
533
- // for (let i = 0; i < numVertices; i++) { // For each vertex v
534
- // if (!visited[i]) { // If v is not Seen
535
- // bfs(i); // Call BFS starting from v
536
- // }
537
- // }
538
- // }
539
- // };
0 commit comments