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  }