mirror of
https://github.com/gonum/gonum.git
synced 2025-10-05 15:16:59 +08:00
143 lines
3.2 KiB
Go
143 lines
3.2 KiB
Go
// Copyright ©2016 The gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build ignore
|
|
|
|
// printgraphs allows us to generate a consistent directed view of
|
|
// a set of edges that follows a reasonably real-world-meaningful
|
|
// graph. The interpretation of the links in the resulting directed
|
|
// graphs are either "suggests" in the context of a Page Ranking or
|
|
// possibly "looks up to" in the Zachary graph.
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
|
|
"gonum.org/v1/gonum/graph"
|
|
"gonum.org/v1/gonum/graph/internal/ordered"
|
|
"gonum.org/v1/gonum/graph/network"
|
|
"gonum.org/v1/gonum/graph/simple"
|
|
)
|
|
|
|
// set is an integer set.
|
|
type set map[int]struct{}
|
|
|
|
func linksTo(i ...int) set {
|
|
if len(i) == 0 {
|
|
return nil
|
|
}
|
|
s := make(set)
|
|
for _, v := range i {
|
|
s[v] = struct{}{}
|
|
}
|
|
return s
|
|
}
|
|
|
|
var (
|
|
zachary = []set{
|
|
0: linksTo(1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 17, 19, 21, 31),
|
|
1: linksTo(2, 3, 7, 13, 17, 19, 21, 30),
|
|
2: linksTo(3, 7, 8, 9, 13, 27, 28, 32),
|
|
3: linksTo(7, 12, 13),
|
|
4: linksTo(6, 10),
|
|
5: linksTo(6, 10, 16),
|
|
6: linksTo(16),
|
|
8: linksTo(30, 32, 33),
|
|
9: linksTo(33),
|
|
13: linksTo(33),
|
|
14: linksTo(32, 33),
|
|
15: linksTo(32, 33),
|
|
18: linksTo(32, 33),
|
|
19: linksTo(33),
|
|
20: linksTo(32, 33),
|
|
22: linksTo(32, 33),
|
|
23: linksTo(25, 27, 29, 32, 33),
|
|
24: linksTo(25, 27, 31),
|
|
25: linksTo(31),
|
|
26: linksTo(29, 33),
|
|
27: linksTo(33),
|
|
28: linksTo(31, 33),
|
|
29: linksTo(32, 33),
|
|
30: linksTo(32, 33),
|
|
31: linksTo(32, 33),
|
|
32: linksTo(33),
|
|
33: nil,
|
|
}
|
|
|
|
blondel = []set{
|
|
0: linksTo(2, 3, 4, 5),
|
|
1: linksTo(2, 4, 7),
|
|
2: linksTo(4, 5, 6),
|
|
3: linksTo(7),
|
|
4: linksTo(10),
|
|
5: linksTo(7, 11),
|
|
6: linksTo(7, 11),
|
|
8: linksTo(9, 10, 11, 14, 15),
|
|
9: linksTo(12, 14),
|
|
10: linksTo(11, 12, 13, 14),
|
|
11: linksTo(13),
|
|
15: nil,
|
|
}
|
|
)
|
|
|
|
func main() {
|
|
for _, raw := range []struct {
|
|
name string
|
|
set []set
|
|
}{
|
|
{"zachary", zachary},
|
|
{"blondel", blondel},
|
|
} {
|
|
g := simple.NewUndirectedGraph(0, 0)
|
|
for u, e := range raw.set {
|
|
// 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})
|
|
}
|
|
}
|
|
|
|
nodes := g.Nodes()
|
|
sort.Sort(ordered.ByID(nodes))
|
|
|
|
fmt.Printf("%s = []set{\n", raw.name)
|
|
rank := network.PageRank(asDirected{g}, 0.85, 1e-8)
|
|
for _, u := range nodes {
|
|
to := g.From(nodes[u.ID()])
|
|
sort.Sort(ordered.ByID(to))
|
|
var links []int
|
|
for _, v := range to {
|
|
if rank[u.ID()] <= rank[v.ID()] {
|
|
links = append(links, v.ID())
|
|
}
|
|
}
|
|
|
|
if links == nil {
|
|
fmt.Printf("\t%d: nil, // rank=%.4v\n", u.ID(), rank[u.ID()])
|
|
continue
|
|
}
|
|
|
|
fmt.Printf("\t%d: linksTo(", u.ID())
|
|
for i, v := range links {
|
|
if i != 0 {
|
|
fmt.Print(", ")
|
|
}
|
|
fmt.Print(v)
|
|
}
|
|
fmt.Printf("), // rank=%.4v\n", rank[u.ID()])
|
|
}
|
|
fmt.Println("}")
|
|
}
|
|
}
|
|
|
|
type asDirected struct{ *simple.UndirectedGraph }
|
|
|
|
func (g asDirected) HasEdgeFromTo(u, v graph.Node) bool {
|
|
return g.UndirectedGraph.HasEdgeBetween(u, v)
|
|
}
|
|
func (g asDirected) To(v graph.Node) []graph.Node { return g.From(v) }
|