2323// to turn on caching for any component. This gives constant time
2424// performance for all basic operations on that component.
2525//
26- // Example usage
26+ // Tutorial
2727//
28- // The package examples show how to build graphs from standard components
29- // using composition and filtering. They also demonstrate how to apply
30- // a cost function to a virtual graph.
28+ // The Euclid and Maxflow examples show how to build graphs from
29+ // standard components using composition and filtering. They also
30+ // demonstrate how to apply a cost function to a virtual graph.
3131//
3232package build
3333
@@ -41,21 +41,25 @@ import (
4141// by composing and filtering a set of standard graphs, or by writing
4242// functions that describe the edges of a graph.
4343type Virtual struct {
44+ // The `order` field is, in fact, a constant function.
45+ // It returns the number of vertices in the graph.
4446 order int
45- // The edge and cost functions define a weighted graph without self-loops.
47+
48+ // The `edge` and `cost` functions define a weighted graph without self-loops.
4649 //
4750 // • edge(v, w) returns true whenever (v, w) belongs to the graph;
4851 // the value is disregarded when v == w.
4952 //
50- // • cost(v, w) returns the cost of (v, w); the value is disregarded
51- // when edge(v, w) is false.
53+ // • cost(v, w) returns the cost of (v, w);
54+ // the value is disregarded when edge(v, w) is false.
55+ //
5256 edge func (v , w int ) bool
5357 cost func (v , w int ) int64
5458
55- // These functions can be used to improve performance.
56- // They MUST BE CONSISTENT with edge and cost.
57- // The generic() factory method contains a basic implementation .
58- // The Consistent test function should be used to check compliance.
59+ // The `degree` and `visit` functions can be used to improve performance.
60+ // They MUST BE CONSISTENT with edge and cost. If not implemented,
61+ // the ` generic` or `generic0` implementation is used instead .
62+ // The ` Consistent` test function should be used to check compliance.
5963 //
6064 // • degree(v) returns the outdegree of vertex v.
6165 //
@@ -64,12 +68,13 @@ type Virtual struct {
6468 // If a call to do returns true, visit MUST ABORT the iteration
6569 // and return true; if successful it should return false.
6670 // Precondition: a ≥ 0.
71+ //
6772 degree func (v int ) int
6873 visit func (v int , a int , do func (w int , c int64 ) (skip bool )) (aborted bool )
6974}
7075
7176// FilterFunc is a function that tells if there is a directed edge from v to w.
72- // The nil value represents an edge functions that always returns true.
77+ // The nil value represents an edge function that always returns true.
7378type FilterFunc func (v , w int ) bool
7479
7580// CostFunc is a function that computes the cost of an edge from v to w.
@@ -107,7 +112,7 @@ func max(m, n int) int {
107112 return m
108113}
109114
110- // null is the null graph; a graph of order 0 .
115+ // null is the null graph; a graph with no vertices .
111116var null = new (Virtual )
112117
113118// singleton returns a graph with one vertex.
@@ -126,7 +131,7 @@ func edge() *Virtual {
126131 g := & Virtual {
127132 order : 2 ,
128133 cost : zero ,
129- edge : func ( v , w int ) bool { return v != w } ,
134+ edge : alwaysEdge ,
130135 degree : degreeOne ,
131136 }
132137 g .visit = func (v int , a int , do func (w int , c int64 ) bool ) (aborted bool ) {
@@ -260,17 +265,16 @@ func Generic(n int, edge FilterFunc) *Virtual {
260265 return generic0 (n , edge )
261266}
262267
263- // Specific returns a cached copy of g with constant time performance
264- // for all basic operations. It uses space proportional to
265- // the size of the graph.
268+ // Specific returns a cached copy of g with constant time performance for
269+ // all basic operations. It uses space proportional to the size of the graph.
266270//
267271// This function does not accept multigraphs and graphs with self-loops.
268272func Specific (g graph.Iterator ) * Virtual {
269- stats := graph .Check (g )
273+ h := graph .Sort (g )
274+ stats := graph .Check (h )
270275 if stats .Multi != 0 || stats .Loops != 0 {
271276 panic ("Virtual doesn't support multiple edges or self-loops" )
272277 }
273- h := graph .Sort (g )
274278 res := & Virtual {
275279 order : h .Order (),
276280 edge : h .Edge ,
@@ -282,7 +286,7 @@ func Specific(g graph.Iterator) *Virtual {
282286 return res
283287 }
284288 res .cost = func (v , w int ) (cost int64 ) {
285- if ! res . edge (v , w ) {
289+ if ! h . Edge (v , w ) {
286290 return 0
287291 }
288292 h .VisitFrom (v , w , func (w int , c int64 ) (skip bool ) {
@@ -353,10 +357,7 @@ func (g *Virtual) Complement() *Virtual {
353357 return singleton ()
354358 }
355359 res := generic0 (n , func (v , w int ) (edge bool ) {
356- if v != w {
357- return ! g .edge (v , w )
358- }
359- return
360+ return v != w && ! g .edge (v , w )
360361 })
361362 res .degree = func (v int ) int { return n - 1 - g .degree (v ) }
362363 res .visit = func (v int , a int , do func (w int , c int64 ) bool ) (aborted bool ) {
0 commit comments