@@ -1321,7 +1321,7 @@ gap> D := CompleteDigraph(5);
13211321gap> VerticesReachableFrom(D, 1);
13221322[ 2, 1, 3, 4, 5 ]
13231323gap> VerticesReachableFrom(D, 3);
1324- [ 1, 2, 3 , 4, 5 ]
1324+ [ 1, 3, 2 , 4, 5 ]
13251325gap> D := EmptyDigraph(5);
13261326<immutable empty digraph with 5 vertices>
13271327gap> VerticesReachableFrom(D, 1);
@@ -2126,6 +2126,173 @@ gap> LexicographicProduct(NullDigraph(0), CompleteDigraph(10));
21262126</ManSection >
21272127<#/GAPDoc>
21282128
2129+ <#GAPDoc Label="NewDFSRecord">
2130+ <ManSection >
2131+ <Oper Name =" NewDFSRecord" Arg =" digraph" />
2132+ <Returns >A record.</Returns >
2133+ <Description >
2134+ This record contains three lists (parent, preorder and postorder) with their length
2135+ equal to the number of verticies in the <A >digraph</A >. Each index of the lists maps to the
2136+ vertex within the <A >digraph</A > equating to the vertex number. These lists store
2137+ the following:
2138+ <List >
2139+ <Mark >parent</Mark >
2140+ <Item >at each index, the parent of the vertex is stored</Item >
2141+ <Mark >preorder</Mark >
2142+ <Item >at each index, the preorder number (order in which the vertex is visited)
2143+ is stored</Item >
2144+ <Mark >postorder</Mark >
2145+ <Item >at each index, the postorder number (order in which the vertex is backtracked on)
2146+ is stored</Item >
2147+ </List >
2148+
2149+ The record also stores a further 4 attributes.
2150+ <List >
2151+ <Mark >current</Mark >
2152+ <Item >the current vertex that is being visited</Item >
2153+ <Mark >child</Mark >
2154+ <Item >the child of the current vertex</Item >
2155+ <Mark >graph</Mark >
2156+ <Item >the <A >digraph</A ></Item >
2157+ <Mark >stop</Mark >
2158+ <Item >whether to stop the depth first search</Item >
2159+ </List >
2160+
2161+ Initially, the <C >current</C > and <C >child</C > attributes will have <C >-1</C > values and the lists (<C >parent</C >,
2162+ <C >preorder</C > and <C >postorder</C >) will have <C >-1</C > values at all of their indicies as no vertex has
2163+ been visited. The <C >stop</C > attribute will initially be <C >false</C >.
2164+ <E >This record should be passed into the <C >ExecuteDFS</C > function.</E >
2165+ See <Ref Oper =" ExecuteDFS" />.
2166+ <Example ><![CDATA[
2167+ gap> record := NewDFSRecord(CompleteDigraph(2));
2168+ rec( child := -1, current := -1,
2169+ graph := <immutable complete digraph with 2 vertices>,
2170+ parent := [ -1, -1 ], postorder := [ -1, -1 ],
2171+ preorder := [ -1, -1 ], stop := false )
2172+ gap> record.preorder;
2173+ [ -1, -1 ]
2174+ gap> record.postorder;
2175+ [ -1, -1 ]
2176+ gap> record.stop;
2177+ false
2178+ gap> record.parent;
2179+ [ -1, -1 ]
2180+ gap> record.child;
2181+ -1
2182+ gap> record.current;
2183+ -1
2184+ gap> record.graph;
2185+ <immutable complete digraph with 2 vertices>
2186+ ]]> </Example >
2187+ </Description >
2188+ </ManSection >
2189+ <#/GAPDoc>
2190+
2191+ <#GAPDoc Label="DFSDefault">
2192+ <ManSection >
2193+ <Oper Name =" DFSDefault" Arg =" record, data" />
2194+ <Description >
2195+ This is a default function to be passed into the <C >ExecuteDFS</C > function.
2196+ This does nothing and can be used in place of the <C >PreOrderFunc</C >, <C >PostOrderFunc</C >,
2197+ <C >AncestorFunc</C > and/or <C >CrossFunc</C > of the <C >ExecuteDFS</C > function.
2198+ See <Ref Oper =" ExecuteDFS" />.
2199+ <Example ><![CDATA[
2200+ gap> PreOrderFunc := function(record, data)
2201+ > data.num_vertices := data.num_vertices + 1;
2202+ > end;;
2203+ gap> record := NewDFSRecord(CompleteDigraph(2));;
2204+ gap> data := rec(num_vertices := 0);;
2205+ gap> ExecuteDFS(record, data, 1, PreOrderFunc,
2206+ > DFSDefault, DFSDefault, DFSDefault);
2207+ gap> data;
2208+ rec( num_vertices := 2 )
2209+ gap> record := NewDFSRecord(CompleteDigraph(2));;
2210+ gap> ExecuteDFS(record, [], 1, DFSDefault,
2211+ > DFSDefault, DFSDefault, DFSDefault);
2212+ gap> record;
2213+ rec( child := 1, current := 1,
2214+ graph := <immutable complete digraph with 2 vertices>,
2215+ parent := [ 1, 1 ], postorder := [ 2, 1 ], preorder := [ 1, 2 ],
2216+ stop := false )
2217+ ]]> </Example >
2218+ </Description >
2219+ </ManSection >
2220+ <#/GAPDoc>
2221+
2222+ <#GAPDoc Label="ExecuteDFS">
2223+ <ManSection >
2224+ <Oper Name =" ExecuteDFS"
2225+ Arg =" record, data, start, PreOrderFunc, PostOrderFunc, AncestorFunc, CrossFunc" />
2226+ <Description >
2227+ This performs a full depth first search from the <A >start</A > vertex (where <A >start</A > is a vertex within the graph).
2228+ The depth first search can be terminated by changing the <A >record</A >.stop attribute to true in the
2229+ <A >PreOrderFunc</A >, <A >PostOrderFunc</A >, <A >AncestorFunc</A > or <A >CrossFunc</A > functions.
2230+ <C >ExecuteDFS</C > takes 7 arguments:
2231+ <List >
2232+ <Mark >record</Mark >
2233+ <Item >the depth first search record (created using NewDFSRecord)</Item >
2234+ <Mark >data</Mark >
2235+ <Item >an object that you want to manipulate in the functions passed.</Item >
2236+ <Mark >start</Mark >
2237+ <Item >the vertex where we begin the depth first search.</Item >
2238+ <Mark >PreOrderFunc</Mark >
2239+ <Item >this function is called when a vertex is first visited. This vertex
2240+ is stored in <A >record</A >.current</Item >
2241+ <Mark >PostOrderFunc</Mark >
2242+ <Item >this function is called when a vertex has no more unvisited children
2243+ causing us to backtrack. This vertex is stored in <A >record</A >.child and its parent is stored
2244+ in <A >record</A >.current</Item >
2245+ <Mark >AncestorFunc</Mark >
2246+ <Item >this function is called when (<C ><A >record</A >.current</C >,
2247+ <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
2248+ <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 >
2249+ <Mark >CrossFunc</Mark >
2250+ <Item >this function is called when (<C ><A >record</A >.current</C >,
2251+ <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 >
2252+ and it is not an ancestor of <C ><A >record</A >.current</C ></Item >
2253+ </List >
2254+ Note that this function only performs a depth first search on the vertices reachable from <A >start</A >.
2255+ It is also important to note that all functions passed need to accept arguments <A >record</A > and <A >data</A >.
2256+ Finally, for the <A >start</A > vertex, its parent is itself and the <A >PreOrderFunc</A >
2257+ will be called on it.
2258+ See <Ref Oper =" NewDFSRecord" />.
2259+ <Example ><![CDATA[
2260+ gap> record := NewDFSRecord(CycleDigraph(10));;
2261+ gap> ExecuteDFS(record, [], 1, DFSDefault,
2262+ > DFSDefault, DFSDefault, DFSDefault);
2263+ gap> record.preorder;
2264+ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
2265+ gap> record := NewDFSRecord(CompleteDigraph(10));;
2266+ gap> data := rec(cycle_vertex := 0);;
2267+ gap> AncestorFunc := function(record, data)
2268+ > record.stop := true;
2269+ > data.cycle_vertex := record.child;
2270+ > end;;
2271+ gap> ExecuteDFS(record, data, 1, DFSDefault,
2272+ > DFSDefault, AncestorFunc, DFSDefault);
2273+ gap> record.stop;
2274+ true
2275+ gap> data.cycle_vertex;
2276+ 1
2277+ gap> record.preorder;
2278+ [ 1, 2, 3, -1, -1, -1, -1, -1, -1, -1 ]
2279+ gap> record := NewDFSRecord(Digraph([[2, 3], [4], [5], [], [4]]));;
2280+ gap> CrossFunc := function(record, data)
2281+ > record.stop := true;
2282+ > Add(data, record.child);
2283+ > end;;
2284+ gap> data := [];;
2285+ gap> ExecuteDFS(record, data, 1, DFSDefault,
2286+ > DFSDefault, DFSDefault, CrossFunc);
2287+ gap> record.stop;
2288+ true
2289+ gap> data;
2290+ [ 4 ]
2291+ ]]> </Example >
2292+ </Description >
2293+ </ManSection >
2294+ <#/GAPDoc>
2295+
21292296<#GAPDoc Label="IsDigraphPath">
21302297<ManSection >
21312298 <Oper Name =" IsDigraphPath" Arg =" D, v, a" />
0 commit comments