@@ -1440,7 +1440,7 @@ gap> D := CompleteDigraph(5);
14401440gap> VerticesReachableFrom(D, 1);
14411441[ 1, 2, 3, 4, 5 ]
14421442gap> VerticesReachableFrom(D, 3);
1443- [ 1, 2, 3 , 4, 5 ]
1443+ [ 1, 3, 2 , 4, 5 ]
14441444gap> D := EmptyDigraph(5);
14451445<immutable empty digraph with 5 vertices>
14461446gap> VerticesReachableFrom(D, 1);
@@ -2329,6 +2329,173 @@ gap> LexicographicProduct(NullDigraph(0), CompleteDigraph(10));
23292329</ManSection >
23302330<#/GAPDoc>
23312331
2332+ <#GAPDoc Label="NewDFSRecord">
2333+ <ManSection >
2334+ <Oper Name =" NewDFSRecord" Arg =" digraph" />
2335+ <Returns >A record.</Returns >
2336+ <Description >
2337+ This record contains three lists (parent, preorder and postorder) with their length
2338+ equal to the number of verticies in the <A >digraph</A >. Each index of the lists maps to the
2339+ vertex within the <A >digraph</A > equating to the vertex number. These lists store
2340+ the following:
2341+ <List >
2342+ <Mark >parent</Mark >
2343+ <Item >at each index, the parent of the vertex is stored</Item >
2344+ <Mark >preorder</Mark >
2345+ <Item >at each index, the preorder number (order in which the vertex is visited)
2346+ is stored</Item >
2347+ <Mark >postorder</Mark >
2348+ <Item >at each index, the postorder number (order in which the vertex is backtracked on)
2349+ is stored</Item >
2350+ </List >
2351+
2352+ The record also stores a further 4 attributes.
2353+ <List >
2354+ <Mark >current</Mark >
2355+ <Item >the current vertex that is being visited</Item >
2356+ <Mark >child</Mark >
2357+ <Item >the child of the current vertex</Item >
2358+ <Mark >graph</Mark >
2359+ <Item >the <A >digraph</A ></Item >
2360+ <Mark >stop</Mark >
2361+ <Item >whether to stop the depth first search</Item >
2362+ </List >
2363+
2364+ Initially, the <C >current</C > and <C >child</C > attributes will have <C >-1</C > values and the lists (<C >parent</C >,
2365+ <C >preorder</C > and <C >postorder</C >) will have <C >-1</C > values at all of their indicies as no vertex has
2366+ been visited. The <C >stop</C > attribute will initially be <C >false</C >.
2367+ <E >This record should be passed into the <C >ExecuteDFS</C > function.</E >
2368+ See <Ref Oper =" ExecuteDFS" />.
2369+ <Example ><![CDATA[
2370+ gap> record := NewDFSRecord(CompleteDigraph(2));
2371+ rec( child := -1, current := -1,
2372+ graph := <immutable complete digraph with 2 vertices>,
2373+ parent := [ -1, -1 ], postorder := [ -1, -1 ],
2374+ preorder := [ -1, -1 ], stop := false )
2375+ gap> record.preorder;
2376+ [ -1, -1 ]
2377+ gap> record.postorder;
2378+ [ -1, -1 ]
2379+ gap> record.stop;
2380+ false
2381+ gap> record.parent;
2382+ [ -1, -1 ]
2383+ gap> record.child;
2384+ -1
2385+ gap> record.current;
2386+ -1
2387+ gap> record.graph;
2388+ <immutable complete digraph with 2 vertices>
2389+ ]]> </Example >
2390+ </Description >
2391+ </ManSection >
2392+ <#/GAPDoc>
2393+
2394+ <#GAPDoc Label="DFSDefault">
2395+ <ManSection >
2396+ <Oper Name =" DFSDefault" Arg =" record, data" />
2397+ <Description >
2398+ This is a default function to be passed into the <C >ExecuteDFS</C > function.
2399+ This does nothing and can be used in place of the <C >PreOrderFunc</C >, <C >PostOrderFunc</C >,
2400+ <C >AncestorFunc</C > and/or <C >CrossFunc</C > of the <C >ExecuteDFS</C > function.
2401+ See <Ref Oper =" ExecuteDFS" />.
2402+ <Example ><![CDATA[
2403+ gap> PreOrderFunc := function(record, data)
2404+ > data.num_vertices := data.num_vertices + 1;
2405+ > end;;
2406+ gap> record := NewDFSRecord(CompleteDigraph(2));;
2407+ gap> data := rec(num_vertices := 0);;
2408+ gap> ExecuteDFS(record, data, 1, PreOrderFunc,
2409+ > DFSDefault, DFSDefault, DFSDefault);
2410+ gap> data;
2411+ rec( num_vertices := 2 )
2412+ gap> record := NewDFSRecord(CompleteDigraph(2));;
2413+ gap> ExecuteDFS(record, [], 1, DFSDefault,
2414+ > DFSDefault, DFSDefault, DFSDefault);
2415+ gap> record;
2416+ rec( child := 1, current := 1,
2417+ graph := <immutable complete digraph with 2 vertices>,
2418+ parent := [ 1, 1 ], postorder := [ 2, 1 ], preorder := [ 1, 2 ],
2419+ stop := false )
2420+ ]]> </Example >
2421+ </Description >
2422+ </ManSection >
2423+ <#/GAPDoc>
2424+
2425+ <#GAPDoc Label="ExecuteDFS">
2426+ <ManSection >
2427+ <Oper Name =" ExecuteDFS"
2428+ Arg =" record, data, start, PreOrderFunc, PostOrderFunc, AncestorFunc, CrossFunc" />
2429+ <Description >
2430+ This performs a full depth first search from the <A >start</A > vertex (where <A >start</A > is a vertex within the graph).
2431+ The depth first search can be terminated by changing the <A >record</A >.stop attribute to true in the
2432+ <A >PreOrderFunc</A >, <A >PostOrderFunc</A >, <A >AncestorFunc</A > or <A >CrossFunc</A > functions.
2433+ <C >ExecuteDFS</C > takes 7 arguments:
2434+ <List >
2435+ <Mark >record</Mark >
2436+ <Item >the depth first search record (created using NewDFSRecord)</Item >
2437+ <Mark >data</Mark >
2438+ <Item >an object that you want to manipulate in the functions passed.</Item >
2439+ <Mark >start</Mark >
2440+ <Item >the vertex where we begin the depth first search.</Item >
2441+ <Mark >PreOrderFunc</Mark >
2442+ <Item >this function is called when a vertex is first visited. This vertex
2443+ is stored in <A >record</A >.current</Item >
2444+ <Mark >PostOrderFunc</Mark >
2445+ <Item >this function is called when a vertex has no more unvisited children
2446+ causing us to backtrack. This vertex is stored in <A >record</A >.child and its parent is stored
2447+ in <A >record</A >.current</Item >
2448+ <Mark >AncestorFunc</Mark >
2449+ <Item >this function is called when (<C ><A >record</A >.current</C >,
2450+ <C ><A >record</A >.child</C >) is an edge and <C ><A >record</A >.child</C > is an ancestor of <C ><A >record</A >.current</C >. An ancestor here means that
2451+ <C ><A >record</A >.child</C > is on the same branch as <C ><A >record</A >.current</C > but was visited prior to <C ><A >record</A >.current</C ></Item >
2452+ <Mark >CrossFunc</Mark >
2453+ <Item >this function is called when (<C ><A >record</A >.current</C >,
2454+ <C ><A >record</A >.child</C >) is an edge and <C ><A >record</A >.child</C > has been visited before <C ><A >record</A >.current</C >
2455+ and it is not an ancestor of <C ><A >record</A >.current</C ></Item >
2456+ </List >
2457+ Note that this function only performs a depth first search on the vertices reachable from <A >start</A >.
2458+ It is also important to note that all functions passed need to accept arguments <A >record</A > and <A >data</A >.
2459+ Finally, for the <A >start</A > vertex, its parent is itself and the <A >PreOrderFunc</A >
2460+ will be called on it.
2461+ See <Ref Oper =" NewDFSRecord" />.
2462+ <Example ><![CDATA[
2463+ gap> record := NewDFSRecord(CycleDigraph(10));;
2464+ gap> ExecuteDFS(record, [], 1, DFSDefault,
2465+ > DFSDefault, DFSDefault, DFSDefault);
2466+ gap> record.preorder;
2467+ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
2468+ gap> record := NewDFSRecord(CompleteDigraph(10));;
2469+ gap> data := rec(cycle_vertex := 0);;
2470+ gap> AncestorFunc := function(record, data)
2471+ > record.stop := true;
2472+ > data.cycle_vertex := record.child;
2473+ > end;;
2474+ gap> ExecuteDFS(record, data, 1, DFSDefault,
2475+ > DFSDefault, AncestorFunc, DFSDefault);
2476+ gap> record.stop;
2477+ true
2478+ gap> data.cycle_vertex;
2479+ 1
2480+ gap> record.preorder;
2481+ [ 1, 2, 3, -1, -1, -1, -1, -1, -1, -1 ]
2482+ gap> record := NewDFSRecord(Digraph([[2, 3], [4], [5], [], [4]]));;
2483+ gap> CrossFunc := function(record, data)
2484+ > record.stop := true;
2485+ > Add(data, record.child);
2486+ > end;;
2487+ gap> data := [];;
2488+ gap> ExecuteDFS(record, data, 1, DFSDefault,
2489+ > DFSDefault, DFSDefault, CrossFunc);
2490+ gap> record.stop;
2491+ true
2492+ gap> data;
2493+ [ 4 ]
2494+ ]]> </Example >
2495+ </Description >
2496+ </ManSection >
2497+ <#/GAPDoc>
2498+
23322499<#GAPDoc Label="IsDigraphPath">
23332500<ManSection >
23342501 <Oper Name =" IsDigraphPath" Arg =" D, v, a" />
0 commit comments