108 lines
1.9 KiB
Go
108 lines
1.9 KiB
Go
package model
|
|
|
|
import (
|
|
"math/rand"
|
|
"time"
|
|
)
|
|
|
|
type (
|
|
Node struct {
|
|
IR []int
|
|
}
|
|
ExperimentResult struct {
|
|
ViolatedCounter int
|
|
}
|
|
)
|
|
|
|
func getRandomN(n, max, seed int, r *rand.Rand) []int {
|
|
r.Seed(time.Now().UnixNano() + int64(seed))
|
|
|
|
if n > max/2 {
|
|
return r.Perm(max)[:n]
|
|
|
|
} else {
|
|
result := make([]int, 0, n)
|
|
re := make(map[int]struct{}, max)
|
|
|
|
for len(result) < n {
|
|
num := r.Intn(max)
|
|
if _, ok := re[num]; !ok {
|
|
result = append(result, num)
|
|
re[num] = struct{}{}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
func ExecuteModelA(ircount, containers, badcount, choose int) *ExperimentResult {
|
|
var (
|
|
nodes = make([]Node, containers)
|
|
badring = make(map[int]struct{})
|
|
result = new(ExperimentResult)
|
|
)
|
|
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
for len(badring) < badcount {
|
|
n := r.Intn(ircount)
|
|
if _, ok := badring[n]; !ok {
|
|
badring[n] = struct{}{}
|
|
}
|
|
}
|
|
|
|
for i := 0; i < ircount; i++ {
|
|
if _, ok := badring[i]; ok {
|
|
continue
|
|
}
|
|
rands := getRandomN(choose, containers, i+1, r)
|
|
for _, host := range rands {
|
|
nodes[host].IR = append(nodes[host].IR, i)
|
|
}
|
|
}
|
|
|
|
for _, node := range nodes {
|
|
if len(node.IR) == 0 {
|
|
result.ViolatedCounter++
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func ExecuteModelB(ircount, containers, badcount, choose int) *ExperimentResult {
|
|
var (
|
|
nodes = make([]Node, containers)
|
|
badring = make(map[int]struct{})
|
|
result = new(ExperimentResult)
|
|
)
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
|
for len(badring) < badcount {
|
|
n := r.Intn(ircount)
|
|
if _, ok := badring[n]; !ok {
|
|
badring[n] = struct{}{}
|
|
}
|
|
}
|
|
|
|
for i := 0; i < ircount; i++ {
|
|
if _, ok := badring[i]; ok {
|
|
continue
|
|
}
|
|
ind := (i * choose) % containers
|
|
for j := 0; j < choose; j++ {
|
|
nodes[ind].IR = append(nodes[ind].IR, i)
|
|
ind++
|
|
if ind == containers {
|
|
ind = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, node := range nodes {
|
|
if len(node.IR) == 0 {
|
|
result.ViolatedCounter++
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|