gonum.org/v1/gonum@v0.14.0/graph/topo/clique_graph_test.go (about) 1 // Copyright ©2017 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package topo 6 7 import ( 8 "fmt" 9 "testing" 10 11 "gonum.org/v1/gonum/graph/encoding" 12 "gonum.org/v1/gonum/graph/encoding/dot" 13 "gonum.org/v1/gonum/graph/simple" 14 ) 15 16 var cliqueGraphTests = []struct { 17 name string 18 g []intset 19 want string 20 }{ 21 { 22 name: "simple", 23 g: []intset{ 24 0: linksTo(1, 2, 4, 6), 25 1: linksTo(2, 4, 6), 26 2: linksTo(3, 6), 27 3: linksTo(4, 5), 28 4: linksTo(6), 29 5: nil, 30 6: nil, 31 }, 32 want: `strict graph { 33 // Node definitions. 34 0 [nodes="[0 1 2 6]"]; 35 1 [nodes="[0 1 4 6]"]; 36 2 [nodes="[2 3]"]; 37 3 [nodes="[3 4]"]; 38 4 [nodes="[3 5]"]; 39 40 // Edge definitions. 41 0 -- 1 [nodes="[0 1 6]"]; 42 0 -- 2 [nodes="[2]"]; 43 1 -- 3 [nodes="[4]"]; 44 2 -- 3 [nodes="[3]"]; 45 2 -- 4 [nodes="[3]"]; 46 3 -- 4 [nodes="[3]"]; 47 }`, 48 }, 49 { 50 name: "Batagelj-Zaversnik Graph", 51 g: batageljZaversnikGraph, 52 want: `strict graph { 53 // Node definitions. 54 0 [nodes="[0]"]; 55 1 [nodes="[1 2]"]; 56 2 [nodes="[1 3]"]; 57 3 [nodes="[2 4]"]; 58 4 [nodes="[3 4]"]; 59 5 [nodes="[4 5]"]; 60 6 [nodes="[6 7 8 14]"]; 61 7 [nodes="[7 11 12]"]; 62 8 [nodes="[9 11]"]; 63 9 [nodes="[10 11]"]; 64 10 [nodes="[12 18]"]; 65 11 [nodes="[13 14 15]"]; 66 12 [nodes="[14 15 17]"]; 67 13 [nodes="[15 16]"]; 68 14 [nodes="[17 18 19 20]"]; 69 70 // Edge definitions. 71 1 -- 2 [nodes="[1]"]; 72 1 -- 3 [nodes="[2]"]; 73 2 -- 4 [nodes="[3]"]; 74 3 -- 4 [nodes="[4]"]; 75 3 -- 5 [nodes="[4]"]; 76 4 -- 5 [nodes="[4]"]; 77 6 -- 7 [nodes="[7]"]; 78 6 -- 11 [nodes="[14]"]; 79 6 -- 12 [nodes="[14]"]; 80 7 -- 8 [nodes="[11]"]; 81 7 -- 9 [nodes="[11]"]; 82 7 -- 10 [nodes="[12]"]; 83 8 -- 9 [nodes="[11]"]; 84 10 -- 14 [nodes="[18]"]; 85 11 -- 12 [nodes="[14 15]"]; 86 11 -- 13 [nodes="[15]"]; 87 12 -- 13 [nodes="[15]"]; 88 12 -- 14 [nodes="[17]"]; 89 }`, 90 }, 91 } 92 93 func TestCliqueGraph(t *testing.T) { 94 for _, test := range cliqueGraphTests { 95 g := simple.NewUndirectedGraph() 96 for u, e := range test.g { 97 // Add nodes that are not defined by an edge. 98 if g.Node(int64(u)) == nil { 99 g.AddNode(simple.Node(u)) 100 } 101 for v := range e { 102 g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) 103 } 104 } 105 dst := simple.NewUndirectedGraph() 106 CliqueGraph(dst, g) 107 108 b, _ := dot.Marshal(dst, "", "", " ") 109 got := string(b) 110 111 if got != test.want { 112 t.Errorf("unexpected clique graph result for %q: got:\n%s\nwant:\n%s", test.name, got, test.want) 113 } 114 } 115 } 116 117 func (n Clique) Attributes() []encoding.Attribute { 118 return []encoding.Attribute{{Key: "nodes", Value: fmt.Sprintf(`"%v"`, n.Nodes())}} 119 } 120 121 func (e CliqueGraphEdge) Attributes() []encoding.Attribute { 122 return []encoding.Attribute{{Key: "nodes", Value: fmt.Sprintf(`"%v"`, e.Nodes())}} 123 } 124 125 func BenchmarkCliqueGraph(b *testing.B) { 126 for _, test := range cliqueGraphTests { 127 g := simple.NewUndirectedGraph() 128 for u, e := range test.g { 129 // Add nodes that are not defined by an edge. 130 if g.Node(int64(u)) == nil { 131 g.AddNode(simple.Node(u)) 132 } 133 for v := range e { 134 g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) 135 } 136 } 137 138 b.Run(test.name, func(b *testing.B) { 139 var dst *simple.UndirectedGraph 140 for i := 0; i < b.N; i++ { 141 b.StopTimer() 142 dst = simple.NewUndirectedGraph() 143 b.StartTimer() 144 CliqueGraph(dst, g) 145 } 146 }) 147 } 148 }