func TestNavigableSmallWorldUndirected(t *testing.T) { for p := 1; p < 5; p++ { for q := 0; q < 10; q++ { for r := 0.5; r < 10; r++ { for _, dims := range smallWorldDimensionParameters { g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph(0, math.Inf(1))} err := NavigableSmallWorld(g, dims, p, q, r, nil) n := 1 for _, d := range dims { n *= d } if err != nil { t.Fatalf("unexpected error: dims=%v n=%d, p=%d, q=%d, r=%v: %v", dims, n, p, q, r, err) } if g.addBackwards { t.Errorf("edge added with From.ID > To.ID: dims=%v n=%d, p=%d, q=%d, r=%v", dims, n, p, q, r) } if g.addSelfLoop { t.Errorf("unexpected self edge: dims=%v n=%d, p=%d, q=%d, r=%v", dims, n, p, q, r) } if g.addMultipleEdge { t.Errorf("unexpected multiple edge: dims=%v n=%d, p=%d, q=%d, r=%v", dims, n, p, q, r) } } } } } }
func TestWalkAll(t *testing.T) { for i, test := range walkAllTests { g := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range test.g { if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { if !g.Has(simple.Node(v)) { g.AddNode(simple.Node(v)) } g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) } } type walker interface { WalkAll(g graph.Undirected, before, after func(), during func(graph.Node)) } for _, w := range []walker{ &BreadthFirst{}, &DepthFirst{}, } { var ( c []graph.Node cc [][]graph.Node ) switch w := w.(type) { case *BreadthFirst: w.EdgeFilter = test.edge case *DepthFirst: w.EdgeFilter = test.edge default: panic(fmt.Sprintf("bad walker type: %T", w)) } during := func(n graph.Node) { c = append(c, n) } after := func() { cc = append(cc, []graph.Node(nil)) cc[len(cc)-1] = append(cc[len(cc)-1], c...) c = c[:0] } w.WalkAll(g, nil, after, during) got := make([][]int, len(cc)) for j, c := range cc { ids := make([]int, len(c)) for k, n := range c { ids[k] = n.ID() } sort.Ints(ids) got[j] = ids } sort.Sort(ordered.BySliceValues(got)) if !reflect.DeepEqual(got, test.want) { t.Errorf("unexpected connected components for test %d using %T:\ngot: %v\nwant:%v", i, w, got, test.want) } } } }
func TestDepthFirst(t *testing.T) { for i, test := range depthFirstTests { g := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) } } w := DepthFirst{ EdgeFilter: test.edge, } var got []int final := w.Walk(g, test.from, func(n graph.Node) bool { if test.until != nil && test.until(n) { return true } got = append(got, n.ID()) return false }) if !test.final[final] { t.Errorf("unexepected final node for test %d:\ngot: %v\nwant: %v", i, final, test.final) } sort.Ints(got) if test.want != nil && !reflect.DeepEqual(got, test.want) { t.Errorf("unexepected DFS traversed nodes for test %d:\ngot: %v\nwant: %v", i, got, test.want) } } }
func TestCommunityQ(t *testing.T) { for _, test := range communityQTests { g := simple.NewUndirectedGraph(0, 0) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v), W: 1}) } } for _, structure := range test.structures { communities := make([][]graph.Node, len(structure.memberships)) for i, c := range structure.memberships { for n := range c { communities[i] = append(communities[i], simple.Node(n)) } } got := Q(g, communities, structure.resolution) if !floats.EqualWithinAbsOrRel(got, structure.want, structure.tol, structure.tol) && math.IsNaN(got) != math.IsNaN(structure.want) { for _, c := range communities { sort.Sort(ordered.ByID(c)) } t.Errorf("unexpected Q value for %q %v: got: %v want: %v", test.name, communities, got, structure.want) } } } }
func TestBronKerbosch(t *testing.T) { for i, test := range bronKerboschTests { g := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) } } cliques := BronKerbosch(g) got := make([][]int, len(cliques)) for j, c := range cliques { ids := make([]int, len(c)) for k, n := range c { ids[k] = n.ID() } sort.Ints(ids) got[j] = ids } sort.Sort(ordered.BySliceValues(got)) if !reflect.DeepEqual(got, test.want) { t.Errorf("unexpected cliques for test %d:\ngot: %v\nwant:%v", i, got, test.want) } } }
func TestConnectedComponents(t *testing.T) { for i, test := range connectedComponentTests { g := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range test.g { if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { if !g.Has(simple.Node(v)) { g.AddNode(simple.Node(v)) } g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) } } cc := ConnectedComponents(g) got := make([][]int, len(cc)) for j, c := range cc { ids := make([]int, len(c)) for k, n := range c { ids[k] = n.ID() } sort.Ints(ids) got[j] = ids } sort.Sort(ordered.BySliceValues(got)) if !reflect.DeepEqual(got, test.want) { t.Errorf("unexpected connected components for test %d %T:\ngot: %v\nwant:%v", i, g, got, test.want) } } }
func TestEdgeBetweenness(t *testing.T) { for i, test := range betweennessTests { g := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { // Weight omitted to show weight-independence. g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v), W: 0}) } } got := EdgeBetweenness(g) prec := 1 - int(math.Log10(test.wantTol)) outer: for u := range test.g { for v := range test.g { wantQ, gotOK := got[[2]int{u, v}] gotQ, wantOK := test.wantEdges[[2]int{u, v}] if gotOK != wantOK { t.Errorf("unexpected betweenness result for test %d, edge (%c,%c)", i, u+'A', v+'A') } if !floats.EqualWithinAbsOrRel(gotQ, wantQ, test.wantTol, test.wantTol) { t.Errorf("unexpected betweenness result for test %d:\ngot: %v\nwant:%v", i, orderedPairFloats(got, prec), orderedPairFloats(test.wantEdges, prec)) break outer } } } } }
func TestBetweennessWeighted(t *testing.T) { for i, test := range betweennessTests { g := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v), W: 1}) } } p, ok := path.FloydWarshall(g) if !ok { t.Errorf("unexpected negative cycle in test %d", i) continue } got := BetweennessWeighted(g, p) prec := 1 - int(math.Log10(test.wantTol)) for n := range test.g { gotN, gotOK := got[n] wantN, wantOK := test.want[n] if gotOK != wantOK { t.Errorf("unexpected betweenness existence for test %d, node %c", i, n+'A') } if !floats.EqualWithinAbsOrRel(gotN, wantN, test.wantTol, test.wantTol) { t.Errorf("unexpected betweenness result for test %d:\ngot: %v\nwant:%v", i, orderedFloats(got, prec), orderedFloats(test.want, prec)) break } } } }
func undirectedEdgeAttrGraphFrom(g []set, attr map[edge][]Attribute) graph.Graph { dg := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range g { for v := range e { dg.SetEdge(attrEdge{from: simple.Node(u), to: simple.Node(v), attr: attr[edge{from: u, to: v}]}) } } return dg }
func undirectedGraphFrom(g []set) graph.Graph { dg := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range g { for v := range e { dg.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) } } return dg }
func TestExhaustiveAStar(t *testing.T) { g := simple.NewUndirectedGraph(0, math.Inf(1)) nodes := []locatedNode{ {id: 1, x: 0, y: 6}, {id: 2, x: 1, y: 0}, {id: 3, x: 8, y: 7}, {id: 4, x: 16, y: 0}, {id: 5, x: 17, y: 6}, {id: 6, x: 9, y: 8}, } for _, n := range nodes { g.AddNode(n) } edges := []weightedEdge{ {from: g.Node(1), to: g.Node(2), cost: 7}, {from: g.Node(1), to: g.Node(3), cost: 9}, {from: g.Node(1), to: g.Node(6), cost: 14}, {from: g.Node(2), to: g.Node(3), cost: 10}, {from: g.Node(2), to: g.Node(4), cost: 15}, {from: g.Node(3), to: g.Node(4), cost: 11}, {from: g.Node(3), to: g.Node(6), cost: 2}, {from: g.Node(4), to: g.Node(5), cost: 7}, {from: g.Node(5), to: g.Node(6), cost: 9}, } for _, e := range edges { g.SetEdge(e) } heuristic := func(u, v graph.Node) float64 { lu := u.(locatedNode) lv := v.(locatedNode) return math.Hypot(lu.x-lv.x, lu.y-lv.y) } if ok, edge, goal := isMonotonic(g, heuristic); !ok { t.Fatalf("non-monotonic heuristic at edge:%v for goal:%v", edge, goal) } ps := DijkstraAllPaths(g) for _, start := range g.Nodes() { for _, goal := range g.Nodes() { pt, _ := AStar(start, goal, g, heuristic) gotPath, gotWeight := pt.To(goal) wantPath, wantWeight, _ := ps.Between(start, goal) if gotWeight != wantWeight { t.Errorf("unexpected path weight from %v to %v result: got:%s want:%s", start, goal, gotWeight, wantWeight) } if !reflect.DeepEqual(gotPath, wantPath) { t.Errorf("unexpected path from %v to %v result:\ngot: %v\nwant:%v", start, goal, gotPath, wantPath) } } } }
func undirectedStructuredGraphFrom(c []edge, g ...[]set) graph.Graph { s := &structuredGraph{UndirectedGraph: simple.NewUndirectedGraph(0, math.Inf(1))} var base int for i, sg := range g { sub := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range sg { for v := range e { ce := simple.Edge{F: simple.Node(u + base), T: simple.Node(v + base)} sub.SetEdge(ce) } } s.sub = append(s.sub, namedGraph{id: i, Graph: sub}) base += len(sg) } for _, e := range c { s.SetEdge(simple.Edge{F: simple.Node(e.from), T: simple.Node(e.to)}) } return s }
func undirectedNamedIDGraphFrom(g []set) graph.Graph { dg := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range g { nu := namedNode{id: u, name: alpha[u : u+1]} for v := range e { nv := namedNode{id: v, name: alpha[v : v+1]} dg.SetEdge(simple.Edge{F: nu, T: nv}) } } return dg }
func undirectedSubGraphFrom(g []set, s map[int][]set) graph.Graph { var base int subs := make(map[int]subGraph) for i, sg := range s { sub := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range sg { for v := range e { ce := simple.Edge{F: simple.Node(u + base), T: simple.Node(v + base)} sub.SetEdge(ce) } } subs[i] = subGraph{id: i, Graph: sub} base += len(sg) } dg := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range g { var nu graph.Node if sg, ok := subs[u]; ok { sg.id += base nu = sg } else { nu = simple.Node(u + base) } for v := range e { var nv graph.Node if sg, ok := subs[v]; ok { sg.id += base nv = sg } else { nv = simple.Node(v + base) } dg.SetEdge(simple.Edge{F: nu, T: nv}) } } return dg }
func TestReduceQConsistency(t *testing.T) { tests: for _, test := range communityQTests { g := simple.NewUndirectedGraph(0, 0) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v), W: 1}) } } for _, structure := range test.structures { if math.IsNaN(structure.want) { continue tests } communities := make([][]graph.Node, len(structure.memberships)) for i, c := range structure.memberships { for n := range c { communities[i] = append(communities[i], simple.Node(n)) } sort.Sort(ordered.ByID(communities[i])) } gQ := Q(g, communities, structure.resolution) gQnull := Q(g, nil, 1) cg0 := reduce(g, nil) cg0Qnull := Q(cg0, cg0.Structure(), 1) if !floats.EqualWithinAbsOrRel(gQnull, cg0Qnull, structure.tol, structure.tol) { t.Errorf("disgagreement between null Q from method: %v and function: %v", cg0Qnull, gQnull) } cg0Q := Q(cg0, communities, structure.resolution) if !floats.EqualWithinAbsOrRel(gQ, cg0Q, structure.tol, structure.tol) { t.Errorf("unexpected Q result after initial conversion: got: %v want :%v", gQ, cg0Q) } cg1 := reduce(cg0, communities) cg1Q := Q(cg1, cg1.Structure(), structure.resolution) if !floats.EqualWithinAbsOrRel(gQ, cg1Q, structure.tol, structure.tol) { t.Errorf("unexpected Q result after initial condensation: got: %v want :%v", gQ, cg1Q) } } } }
func undirectedNamedIDNodeAttrGraphFrom(g []set, attr [][]Attribute) graph.Graph { dg := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range g { var at []Attribute if u < len(attr) { at = attr[u] } nu := namedAttrNode{id: u, name: alpha[u : u+1], attr: at} for v := range e { if v < len(attr) { at = attr[v] } nv := namedAttrNode{id: v, name: alpha[v : v+1], attr: at} dg.SetEdge(simple.Edge{F: nu, T: nv}) } } return dg }
func TestNonContiguous(t *testing.T) { g := simple.NewUndirectedGraph(0, 0) for _, e := range []simple.Edge{ {F: simple.Node(0), T: simple.Node(1), W: 1}, {F: simple.Node(4), T: simple.Node(5), W: 1}, } { g.SetEdge(e) } func() { defer func() { r := recover() if r != nil { t.Error("unexpected panic with non-contiguous ID range") } }() Louvain(g, 1, nil) }() }
func TestGnpUndirected(t *testing.T) { for n := 2; n <= 20; n++ { for p := 0.; p <= 1; p += 0.1 { g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph(0, math.Inf(1))} err := Gnp(g, n, p, nil) if err != nil { t.Fatalf("unexpected error: n=%d, p=%v: %v", n, p, err) } if g.addBackwards { t.Errorf("edge added with From.ID > To.ID: n=%d, p=%v", n, p) } if g.addSelfLoop { t.Errorf("unexpected self edge: n=%d, p=%v", n, p) } if g.addMultipleEdge { t.Errorf("unexpected multiple edge: n=%d, p=%v", n, p) } } } }
func TestPreferentialAttachment(t *testing.T) { for n := 2; n <= 20; n++ { for m := 0; m < n; m++ { g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph(0, math.Inf(1))} err := PreferentialAttachment(g, n, m, nil) if err != nil { t.Fatalf("unexpected error: n=%d, m=%d: %v", n, m, err) } if g.addBackwards { t.Errorf("edge added with From.ID > To.ID: n=%d, m=%d", n, m) } if g.addSelfLoop { t.Errorf("unexpected self edge: n=%d, m=%d", n, m) } if g.addMultipleEdge { t.Errorf("unexpected multiple edge: n=%d, m=%d", n, m) } } } }
func undirectedPortedAttrGraphFrom(g []set, attr [][]Attribute, ports map[edge]portedEdge) graph.Graph { dg := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range g { var at []Attribute if u < len(attr) { at = attr[u] } nu := attrNode{id: u, attr: at} for v := range e { if v < len(attr) { at = attr[v] } pe := ports[edge{from: u, to: v}] pe.from = nu pe.to = attrNode{id: v, attr: at} dg.SetEdge(pe) } } return dg }
func TestGnmUndirected(t *testing.T) { for n := 2; n <= 20; n++ { nChoose2 := (n - 1) * n / 2 for m := 0; m <= nChoose2; m++ { g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph(0, math.Inf(1))} err := Gnm(g, n, m, nil) if err != nil { t.Fatalf("unexpected error: n=%d, m=%d: %v", n, m, err) } if g.addBackwards { t.Errorf("edge added with From.ID > To.ID: n=%d, m=%d", n, m) } if g.addSelfLoop { t.Errorf("unexpected self edge: n=%d, m=%d", n, m) } if g.addMultipleEdge { t.Errorf("unexpected multiple edge: n=%d, m=%d", n, m) } } } }
func TestMoveLocal(t *testing.T) { for _, test := range localMoveTests { g := simple.NewUndirectedGraph(0, 0) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v), W: 1}) } } for _, structure := range test.structures { communities := make([][]graph.Node, len(structure.memberships)) for i, c := range structure.memberships { for n := range c { communities[i] = append(communities[i], simple.Node(n)) } sort.Sort(ordered.ByID(communities[i])) } r := reduce(reduce(g, nil), communities) l := newLocalMover(r, r.communities, structure.resolution) for _, n := range structure.targetNodes { dQ, dst, src := l.deltaQ(n) if dQ > 0 { before := Q(r, l.communities, structure.resolution) l.move(dst, src) after := Q(r, l.communities, structure.resolution) want := after - before if !floats.EqualWithinAbsOrRel(dQ, want, structure.tol, structure.tol) { t.Errorf("unexpected deltaQ: got: %v want: %v", dQ, want) } } } } } }
func testMinumumSpanning(mst func(dst graph.UndirectedBuilder, g spanningGraph) float64, t *testing.T) { for _, test := range spanningTreeTests { g := test.graph() for _, e := range test.edges { g.SetEdge(e) } dst := simple.NewUndirectedGraph(0, math.Inf(1)) w := mst(dst, g) if w != test.want { t.Errorf("unexpected minimum spanning tree weight for %q: got: %f want: %f", test.name, w, test.want) } var got float64 for _, e := range dst.Edges() { got += e.Weight() } if got != test.want { t.Errorf("unexpected minimum spanning tree edge weight sum for %q: got: %f want: %f", test.name, got, test.want) } gotEdges := dst.Edges() if len(gotEdges) != len(test.treeEdges) { t.Errorf("unexpected number of spanning tree edges for %q: got: %d want: %d", test.name, len(gotEdges), len(test.treeEdges)) } for _, e := range test.treeEdges { w, ok := dst.Weight(e.From(), e.To()) if !ok { t.Errorf("spanning tree edge not found in graph for %q: %+v", test.name, e) } if w != e.Weight() { t.Errorf("unexpected spanning tree edge weight for %q: got: %f want: %f", test.name, w, e.Weight()) } } } }
func TestVertexOrdering(t *testing.T) { for i, test := range vOrderTests { g := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) } } order, core := VertexOrdering(g) if len(core)-1 != test.wantK { t.Errorf("unexpected value of k for test %d: got: %d want: %d", i, len(core)-1, test.wantK) } var offset int for k, want := range test.wantCore { sort.Ints(want) got := make([]int, len(want)) for j, n := range order[len(order)-len(want)-offset : len(order)-offset] { got[j] = n.ID() } sort.Ints(got) if !reflect.DeepEqual(got, want) { t.Errorf("unexpected %d-core for test %d:\ngot: %v\nwant:%v", got, test.wantCore) } for j, n := range core[k] { got[j] = n.ID() } sort.Ints(got) if !reflect.DeepEqual(got, want) { t.Errorf("unexpected %d-core for test %d:\ngot: %v\nwant:%v", got, test.wantCore) } offset += len(want) } } }
func TestIsPath(t *testing.T) { dg := simple.NewDirectedGraph(0, math.Inf(1)) if !IsPathIn(dg, nil) { t.Error("IsPath returns false on nil path") } p := []graph.Node{simple.Node(0)} if IsPathIn(dg, p) { t.Error("IsPath returns true on nonexistant node") } dg.AddNode(p[0]) if !IsPathIn(dg, p) { t.Error("IsPath returns false on single-length path with existing node") } p = append(p, simple.Node(1)) dg.AddNode(p[1]) if IsPathIn(dg, p) { t.Error("IsPath returns true on bad path of length 2") } dg.SetEdge(simple.Edge{F: p[0], T: p[1], W: 1}) if !IsPathIn(dg, p) { t.Error("IsPath returns false on correct path of length 2") } p[0], p[1] = p[1], p[0] if IsPathIn(dg, p) { t.Error("IsPath erroneously returns true for a reverse path") } p = []graph.Node{p[1], p[0], simple.Node(2)} dg.SetEdge(simple.Edge{F: p[1], T: p[2], W: 1}) if !IsPathIn(dg, p) { t.Error("IsPath does not find a correct path for path > 2 nodes") } ug := simple.NewUndirectedGraph(0, math.Inf(1)) ug.SetEdge(simple.Edge{F: p[1], T: p[0], W: 1}) ug.SetEdge(simple.Edge{F: p[1], T: p[2], W: 1}) if !IsPathIn(dg, p) { t.Error("IsPath does not correctly account for undirected behavior") } }
func rend_node(w http.ResponseWriter, r *http.Request) { g, n, db, err1 := get_graph(w, r) if err1 != nil { return // Already rendered } parts := strings.Split(r.URL.Path, "/") srcid, err3 := strconv.Atoi(parts[4]) if err3 != nil { t_error.Execute(w, err3) return } labels, err4 := db.GetLabels() if err4 != nil { t_error.Execute(w, err4) } ng := dbNodeGraph{UndirectedGraph: simple.NewUndirectedGraph(0, math.Inf(1)), dbName: n, labels: labels} ng.AddNode(dbNodeNode{Node: simple.Node(srcid), dbName: n, label: labels[srcid]}) for _, dst := range g.From(simple.Node(srcid)) { ng.AddNode(dbNodeNode{Node: simple.Node(dst.ID()), dbName: n, label: labels[dst.ID()]}) ng.SetEdge(dbNodeEdge{simple.Edge{F: simple.Node(srcid), T: simple.Node(dst.ID()), W: g.Edge(simple.Node(srcid), dst).Weight()}}) } data, err2 := dot.Marshal(ng, "", "", "", false) if err2 != nil { t_error.Execute(w, err2) return } //fmt.Println(string(data)) buf := bytes.NewBuffer(data) dotter := exec.Command("dot", "-Tsvg") dotin, _ := dotter.StdinPipe() dotout, _ := dotter.StdoutPipe() w.Header().Set("Content-type", "image/svg+xml") dotter.Start() io.Copy(dotin, buf) dotin.Close() io.Copy(w, dotout) }
func TestBreadthFirst(t *testing.T) { for i, test := range breadthFirstTests { g := simple.NewUndirectedGraph(0, math.Inf(1)) for u, e := range test.g { // Add nodes that are not defined by an edge. if !g.Has(simple.Node(u)) { g.AddNode(simple.Node(u)) } for v := range e { g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) } } w := BreadthFirst{ EdgeFilter: test.edge, } var got [][]int final := w.Walk(g, test.from, func(n graph.Node, d int) bool { if test.until != nil && test.until(n, d) { return true } if d >= len(got) { got = append(got, []int(nil)) } got[d] = append(got[d], n.ID()) return false }) if !test.final[final] { t.Errorf("unexepected final node for test %d:\ngot: %v\nwant: %v", i, final, test.final) } for _, l := range got { sort.Ints(l) } if !reflect.DeepEqual(got, test.want) { t.Errorf("unexepected BFS level structure for test %d:\ngot: %v\nwant: %v", i, got, test.want) } } }
func TestDuplication(t *testing.T) { for n := 2; n <= 50; n++ { for alpha := 0.1; alpha <= 1; alpha += 0.1 { for delta := 0.; delta <= 1; delta += 0.2 { for sigma := 0.; sigma <= 1; sigma += 0.2 { g := &duplication{UndirectedMutator: simple.NewUndirectedGraph(0, math.Inf(1))} err := Duplication(g, n, delta, alpha, sigma, nil) if err != nil { t.Fatalf("unexpected error: n=%d, alpha=%v, delta=%v sigma=%v: %v", n, alpha, delta, sigma, err) } if g.addBackwards { t.Errorf("edge added with From.ID > To.ID: n=%d, alpha=%v, delta=%v sigma=%v", n, alpha, delta, sigma) } if g.addSelfLoop { t.Errorf("unexpected self edge: n=%d, alpha=%v, delta=%v sigma=%v", n, alpha, delta, sigma) } if g.addMultipleEdge { t.Errorf("unexpected multiple edge: n=%d, alpha=%v, delta=%v sigma=%v", n, alpha, delta, sigma) } } } } } }
func navigableSmallWorldUndirected(n, p, q int, r float64) graph.Undirected { g := simple.NewUndirectedGraph(0, math.Inf(1)) gen.NavigableSmallWorld(g, []int{n, n}, p, q, r, nil) return g }
func gnpUndirected(n int, p float64) graph.Undirected { g := simple.NewUndirectedGraph(0, math.Inf(1)) gen.Gnp(g, n, p, nil) return g }