gonum.org/v1/gonum@v0.14.0/graph/community/k_communities_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 community 6 7 import ( 8 "fmt" 9 "reflect" 10 "testing" 11 12 "gonum.org/v1/gonum/graph" 13 "gonum.org/v1/gonum/graph/internal/ordered" 14 "gonum.org/v1/gonum/graph/simple" 15 ) 16 17 // batageljZaversnikGraph is the example graph from 18 // figure 1 of http://arxiv.org/abs/cs/0310049v1 19 var batageljZaversnikGraph = []intset{ 20 0: nil, 21 22 1: linksTo(2, 3), 23 2: linksTo(4), 24 3: linksTo(4), 25 4: linksTo(5), 26 5: nil, 27 28 6: linksTo(7, 8, 14), 29 7: linksTo(8, 11, 12, 14), 30 8: linksTo(14), 31 9: linksTo(11), 32 10: linksTo(11), 33 11: linksTo(12), 34 12: linksTo(18), 35 13: linksTo(14, 15), 36 14: linksTo(15, 17), 37 15: linksTo(16, 17), 38 16: nil, 39 17: linksTo(18, 19, 20), 40 18: linksTo(19, 20), 41 19: linksTo(20), 42 20: nil, 43 } 44 45 var kCliqueCommunitiesTests = []struct { 46 name string 47 g []intset 48 k int 49 want [][]graph.Node 50 }{ 51 { 52 name: "simple", 53 g: []intset{ 54 0: linksTo(1, 2, 4, 6), 55 1: linksTo(2, 4, 6), 56 2: linksTo(3, 6), 57 3: linksTo(4, 5), 58 4: linksTo(6), 59 5: nil, 60 6: nil, 61 }, 62 k: 3, 63 want: [][]graph.Node{ 64 {simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(4), simple.Node(6)}, 65 {simple.Node(3)}, 66 {simple.Node(5)}, 67 }, 68 }, 69 { 70 name: "Batagelj-Zaversnik Graph", 71 g: batageljZaversnikGraph, 72 k: 3, 73 want: [][]graph.Node{ 74 {simple.Node(0)}, 75 {simple.Node(1)}, 76 {simple.Node(2)}, 77 {simple.Node(3)}, 78 {simple.Node(4)}, 79 {simple.Node(5)}, 80 {simple.Node(6), simple.Node(7), simple.Node(8), simple.Node(14)}, 81 {simple.Node(7), simple.Node(11), simple.Node(12)}, 82 {simple.Node(9)}, 83 {simple.Node(10)}, 84 {simple.Node(13), simple.Node(14), simple.Node(15), simple.Node(17)}, 85 {simple.Node(16)}, 86 {simple.Node(17), simple.Node(18), simple.Node(19), simple.Node(20)}, 87 }, 88 }, 89 { 90 name: "Batagelj-Zaversnik Graph", 91 g: batageljZaversnikGraph, 92 k: 4, 93 want: [][]graph.Node{ 94 {simple.Node(0)}, 95 {simple.Node(1)}, 96 {simple.Node(2)}, 97 {simple.Node(3)}, 98 {simple.Node(4)}, 99 {simple.Node(5)}, 100 {simple.Node(6), simple.Node(7), simple.Node(8), simple.Node(14)}, 101 {simple.Node(9)}, 102 {simple.Node(10)}, 103 {simple.Node(11)}, 104 {simple.Node(12)}, 105 {simple.Node(13)}, 106 {simple.Node(15)}, 107 {simple.Node(16)}, 108 {simple.Node(17), simple.Node(18), simple.Node(19), simple.Node(20)}, 109 }, 110 }, 111 } 112 113 func TestKCliqueCommunities(t *testing.T) { 114 for _, test := range kCliqueCommunitiesTests { 115 g := simple.NewUndirectedGraph() 116 for u, e := range test.g { 117 // Add nodes that are not defined by an edge. 118 if g.Node(int64(u)) == nil { 119 g.AddNode(simple.Node(u)) 120 } 121 for v := range e { 122 g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) 123 } 124 } 125 got := KCliqueCommunities(test.k, g) 126 127 for _, c := range got { 128 ordered.ByID(c) 129 } 130 ordered.BySliceIDs(got) 131 132 if !reflect.DeepEqual(got, test.want) { 133 t.Errorf("unexpected k-connected components for %q k=%d:\ngot: %v\nwant:%v", test.name, test.k, got, test.want) 134 } 135 } 136 } 137 138 func BenchmarkKCliqueCommunities(b *testing.B) { 139 for _, test := range kCliqueCommunitiesTests { 140 g := simple.NewUndirectedGraph() 141 for u, e := range test.g { 142 // Add nodes that are not defined by an edge. 143 if g.Node(int64(u)) == nil { 144 g.AddNode(simple.Node(u)) 145 } 146 for v := range e { 147 g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) 148 } 149 } 150 151 b.Run(fmt.Sprintf("%s-k=%d", test.name, test.k), func(b *testing.B) { 152 var got [][]graph.Node 153 for i := 0; i < b.N; i++ { 154 got = KCliqueCommunities(test.k, g) 155 } 156 if len(got) != len(test.want) { 157 b.Errorf("unexpected k-connected components for %q k=%d:\ngot: %v\nwant:%v", test.name, test.k, got, test.want) 158 } 159 }) 160 } 161 }