| -- Profile_simple.Play -- |
| package main |
| |
| import ( |
| "fmt" |
| "log" |
| "sort" |
| |
| "golang.org/x/exp/rand" |
| "gonum.org/v1/gonum/graph/community" |
| "gonum.org/v1/gonum/graph/internal/ordered" |
| "gonum.org/v1/gonum/graph/simple" |
| ) |
| |
| func main() { |
| // Profile calls Modularize which implements the Louvain modularization algorithm. |
| // Since this is a randomized algorithm we use a defined random source to ensure |
| // consistency between test runs. In practice, results will not differ greatly |
| // between runs with different PRNG seeds. |
| src := rand.NewSource(1) |
| |
| // Create dumbell graph: |
| // |
| // 0 4 |
| // |\ /| |
| // | 2 - 3 | |
| // |/ \| |
| // 1 5 |
| // |
| g := simple.NewUndirectedGraph() |
| for u, e := range smallDumbell { |
| for v := range e { |
| g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) |
| } |
| } |
| |
| // Get the profile of internal node weight for resolutions |
| // between 0.1 and 10 using logarithmic bisection. |
| p, err := community.Profile( |
| community.ModularScore(g, community.Weight, 10, src), |
| true, 1e-3, 0.1, 10, |
| ) |
| if err != nil { |
| log.Fatal(err) |
| } |
| |
| // Print out each step with communities ordered. |
| for _, d := range p { |
| comm := d.Communities() |
| for _, c := range comm { |
| sort.Sort(ordered.ByID(c)) |
| } |
| sort.Sort(ordered.BySliceIDs(comm)) |
| fmt.Printf("Low:%.2v High:%.2v Score:%v Communities:%v Q=%.3v\n", |
| d.Low, d.High, d.Score, comm, community.Q(g, comm, d.Low)) |
| } |
| |
| } |
| |
| // intset is an integer set. |
| type intset map[int]struct{} |
| |
| func linksTo(i ...int) intset { |
| if len(i) == 0 { |
| return nil |
| } |
| s := make(intset) |
| for _, v := range i { |
| s[v] = struct{}{} |
| } |
| return s |
| } |
| |
| var smallDumbell = []intset{ |
| 0: linksTo(1, 2), |
| 1: linksTo(2), |
| 2: linksTo(3), |
| 3: linksTo(4, 5), |
| 4: linksTo(5), |
| 5: nil, |
| } |
| |
| -- Profile_multiplex.Play -- |
| |
| package main |
| |
| import ( |
| "fmt" |
| "log" |
| "sort" |
| |
| "golang.org/x/exp/rand" |
| "gonum.org/v1/gonum/graph/community" |
| "gonum.org/v1/gonum/graph/internal/ordered" |
| "gonum.org/v1/gonum/graph/simple" |
| ) |
| |
| var friends, enemies *simple.WeightedUndirectedGraph |
| |
| func main() { |
| // Profile calls ModularizeMultiplex which implements the Louvain modularization |
| // algorithm. Since this is a randomized algorithm we use a defined random source |
| // to ensure consistency between test runs. In practice, results will not differ |
| // greatly between runs with different PRNG seeds. |
| src := rand.NewSource(1) |
| |
| // The undirected graphs, friends and enemies, are the political relationships |
| // in the Middle East as described in the Slate article: |
| // http://www.slate.com/blogs/the_world_/2014/07/17/the_middle_east_friendship_chart.html |
| g, err := community.NewUndirectedLayers(friends, enemies) |
| if err != nil { |
| log.Fatal(err) |
| } |
| weights := []float64{1, -1} |
| |
| // Get the profile of internal node weight for resolutions |
| // between 0.1 and 10 using logarithmic bisection. |
| p, err := community.Profile( |
| community.ModularMultiplexScore(g, weights, true, community.WeightMultiplex, 10, src), |
| true, 1e-3, 0.1, 10, |
| ) |
| if err != nil { |
| log.Fatal(err) |
| } |
| |
| // Print out each step with communities ordered. |
| for _, d := range p { |
| comm := d.Communities() |
| for _, c := range comm { |
| sort.Sort(ordered.ByID(c)) |
| } |
| sort.Sort(ordered.BySliceIDs(comm)) |
| fmt.Printf("Low:%.2v High:%.2v Score:%v Communities:%v Q=%.3v\n", |
| d.Low, d.High, d.Score, comm, community.QMultiplex(g, comm, weights, []float64{d.Low})) |
| } |
| |
| } |