-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalgorithm.go
136 lines (118 loc) · 2.11 KB
/
algorithm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package rgraph
import (
"math/rand"
"time"
)
const MaxPairIteration = 100000
const MaxGraphIteration = 100
var u []int
var groups [][]int
type pair struct {
x int
y int
}
var pairs []pair
// RandomRegularGraph is a practical algorithm for generating random regular graphs with n vertices of degree d.
func RandomRegularGraph(n, d int) graph {
newGroups(n, d)
for i := 0; i < MaxGraphIteration; i++ {
g := iteration()
if g.isDRegular(d) {
return g
}
}
return nil
}
// should be ordered
func newU(n, d int) {
for i := 1; i < n*d+1; i++ {
u = append(u, i)
}
}
// should be ordered
func newGroups(n, d int) {
newU(n, d)
for i := 0; i < n; i++ {
var group []int
for _, v := range u[i*d : i*d+d] {
group = append(group, v)
}
groups = append(groups, group)
}
}
// x < y
func suitable(x, y int) bool {
// check that they lie in different group
indexOfX := indexInGroups(x)
indexOfY := indexInGroups(y)
if indexOfX == indexOfY {
return false
}
// check that no currently existing pair contains points
// in the same two group
if pairExist(indexOfX, indexOfY) {
return false
}
return true
}
func indexInGroups(x int) int {
for i := range groups {
for j := range groups[i] {
if x == groups[i][j] {
return i
}
}
}
return -1
}
func indexInU(x int) int {
for i := range u {
if u[i] == x {
return i
}
}
return -1
}
func pairExist(x, y int) bool {
for i := range pairs {
if pairs[i].x == x && pairs[i].y == y {
return true
}
}
return false
}
// order tuple
func twoRandomPoints() (int, int) {
rand.Seed(time.Now().Unix())
x := rand.Intn(len(u))
for {
y := rand.Intn(len(u))
if x != y {
if x < y {
return u[x], u[y]
} else {
return u[y], u[x]
}
}
}
}
func pairNewPoints() {
if len(u) > 0 {
x, y := twoRandomPoints()
if suitable(x, y) {
pairs = append(pairs, pair{x: indexInGroups(x), y: indexInGroups(y)})
deleteIndex(y)
deleteIndex(x)
}
}
}
func deleteIndex(x int) {
i := indexInU(x)
u = append(u[:i], u[i+1:]...)
}
func iteration() graph {
for i := 0; i < MaxPairIteration; i++ {
pairNewPoints()
}
return buildGraph()
}