forked from sarah/microworlds
More robust Snowball algorithm, paramtized & byzantine adversaries
This commit is contained in:
parent
075c0f88d6
commit
c1142dca99
|
@ -15,43 +15,81 @@ var initialSureness = flag.Int("initialSureness", 2, "how sure an honest node is
|
||||||
var byzantineTurtles = flag.Int("byzantineTurtles", 50, "in consensus simlulations, the number of turtles who will always vote 2")
|
var byzantineTurtles = flag.Int("byzantineTurtles", 50, "in consensus simlulations, the number of turtles who will always vote 2")
|
||||||
var cleverByzantineTurtles = flag.Bool("cleverByzantineTurtles", true, "byzantine turtles try to find each other")
|
var cleverByzantineTurtles = flag.Bool("cleverByzantineTurtles", true, "byzantine turtles try to find each other")
|
||||||
|
|
||||||
var alpha = flag.Float64("alpha", 0.5, "the proportion of votes in a voting round that a color must have before it is considered a vote for that colour")
|
var isolate = flag.Bool("isolate", false, "also run the isolate algorithm")
|
||||||
|
|
||||||
|
var alpha = flag.Float64("alpha", 0.8, "the proportion of votes in a voting round that a color must have before it is considered a vote for that colour")
|
||||||
|
var beta = flag.Float64("beta", 100, "acceptance threshold, the number of steps of consistent votes after which a node will no longer change its opinon")
|
||||||
|
|
||||||
|
var vote1Ahead = false
|
||||||
|
|
||||||
type Snowball struct {
|
type Snowball struct {
|
||||||
color int
|
color int
|
||||||
Probability float64
|
Probability float64
|
||||||
sureness float32
|
sureness float32
|
||||||
Byztantine bool
|
Byztantine bool
|
||||||
colourCounts []int
|
colourCounts []int
|
||||||
|
accept bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *Snowball) Setup(env *core.Environment, t *core.Turtle) {
|
func (sm *Snowball) Setup(env *core.Environment, t *core.Turtle) {
|
||||||
num := rand.Intn(100)
|
if sm.Byztantine {
|
||||||
if num >= int(sm.Probability*100.0) {
|
|
||||||
sm.color = 1
|
sm.color = 1
|
||||||
} else {
|
} else {
|
||||||
sm.color = 0
|
sm.colourCounts = make([]int, 2)
|
||||||
|
num := rand.Intn(100)
|
||||||
|
if num >= int(sm.Probability*100.0) {
|
||||||
|
sm.color = 0
|
||||||
|
sm.colourCounts[0] = 1
|
||||||
|
} else {
|
||||||
|
sm.color = 1
|
||||||
|
sm.colourCounts[1] = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sm.sureness = float32(*initialSureness)
|
sm.sureness = float32(*initialSureness)
|
||||||
sm.colourCounts = make([]int,2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *Snowball) GetColor() int {
|
func (sm *Snowball) GetColor() int {
|
||||||
return sm.color
|
return sm.color + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *Snowball) Run(env *core.Environment, t *core.Turtle) {
|
func (sm *Snowball) Run(env *core.Environment, t *core.Turtle) {
|
||||||
if sm.Byztantine {
|
if sm.Byztantine {
|
||||||
t.Wiggle()
|
t.Wiggle()
|
||||||
if *cleverByzantineTurtles {
|
am1 := t.AmountAll(env, 1, "1")
|
||||||
|
am2 := t.AmountAll(env, 1, "2")
|
||||||
|
k := float32(am1 + am2)
|
||||||
|
|
||||||
t.FollowGradient(env, 5, 2, "3")
|
if *cleverByzantineTurtles == false {
|
||||||
t.Drop(env, 1, "3")
|
if am1 > k*float32(*alpha) && am1 > am2 {
|
||||||
|
sm.color = 1
|
||||||
|
t.Drop(env, 1, "2")
|
||||||
|
} else if am2 > k*float32(*alpha) && am2 > am1 {
|
||||||
|
sm.color = 0
|
||||||
|
t.Drop(env, 1, "1")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if *isolate {
|
||||||
|
t.FollowGradient(env, 10, 0, "3")
|
||||||
|
t.Drop(env, 1, "3")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*isolate) && sm.sureness > 50 || (*isolate) == false {
|
||||||
|
if vote1Ahead {
|
||||||
|
sm.color = 1
|
||||||
|
t.Drop(env, 1, "2")
|
||||||
|
} else {
|
||||||
|
sm.color = 0
|
||||||
|
t.Drop(env, 1, "1")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sm.color = 1
|
sm.sureness++
|
||||||
|
t.Step(env)
|
||||||
|
|
||||||
t.SetColor(color.RGBA{255, 0, 0, 0})
|
t.SetColor(color.RGBA{255, 0, 0, 0})
|
||||||
t.Drop(env, 1, "2")
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if sm.color == 1 {
|
if sm.color == 1 {
|
||||||
|
@ -60,25 +98,31 @@ func (sm *Snowball) Run(env *core.Environment, t *core.Turtle) {
|
||||||
t.SetColor(color.RGBA{255, 0, 255, 0})
|
t.SetColor(color.RGBA{255, 0, 255, 0})
|
||||||
}
|
}
|
||||||
t.Wiggle()
|
t.Wiggle()
|
||||||
am1 := t.AmountAll(env, 1, "1")
|
|
||||||
am2 := t.AmountAll(env, 1, "2")
|
|
||||||
k := float32(am1 + am2)
|
|
||||||
|
|
||||||
if am1 > k*float32(*alpha) && am1 > am2 {
|
if !sm.accept {
|
||||||
|
am1 := t.AmountAll(env, 1, "1")
|
||||||
|
am2 := t.AmountAll(env, 1, "2")
|
||||||
|
k := float32(am1 + am2)
|
||||||
|
|
||||||
|
if am1 > k*float32(*alpha) && am1 > am2 {
|
||||||
sm.colourCounts[0]++
|
sm.colourCounts[0]++
|
||||||
} else if am2 > k*0.5 && am2 > am1 {
|
} else if am2 > k*float32(*alpha) && am2 > am1 {
|
||||||
sm.colourCounts[1]++
|
sm.colourCounts[1]++
|
||||||
}
|
}
|
||||||
|
|
||||||
sm.sureness++
|
sm.sureness++
|
||||||
|
|
||||||
if sm.colourCounts[sm.color] < sm.colourCounts[(sm.color+1)%2] {
|
if sm.colourCounts[sm.color] < sm.colourCounts[(sm.color+1)%2] {
|
||||||
sm.color = (sm.color+1) %2
|
sm.color = (sm.color + 1) % 2
|
||||||
sm.sureness = 0
|
sm.sureness = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if sm.sureness > float32(*beta) {
|
||||||
|
sm.accept = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a vote for our new colour if we are sure
|
// Add a vote for our new colour if we are sure
|
||||||
if sm.sureness > 1 {
|
if sm.sureness >= 1 {
|
||||||
t.Drop(env, 1, strconv.Itoa(sm.color+1))
|
t.Drop(env, 1, strconv.Itoa(sm.color+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,12 +133,6 @@ func (sm *Snowball) Run(env *core.Environment, t *core.Turtle) {
|
||||||
func main() {
|
func main() {
|
||||||
experiment := new(experiments.Experiment)
|
experiment := new(experiments.Experiment)
|
||||||
experiment.InitializeExperiment()
|
experiment.InitializeExperiment()
|
||||||
honestTurtles := experiment.GetNumTurtles() - (*byzantineTurtles)
|
|
||||||
experiment.InitNTurtles(func() core.Actor {
|
|
||||||
sm := new(Snowball)
|
|
||||||
sm.Probability = *prob
|
|
||||||
return sm
|
|
||||||
}, honestTurtles)
|
|
||||||
experiment.InitNTurtles(func() core.Actor {
|
experiment.InitNTurtles(func() core.Actor {
|
||||||
sm := new(Snowball)
|
sm := new(Snowball)
|
||||||
sm.Probability = *prob
|
sm.Probability = *prob
|
||||||
|
@ -104,25 +142,50 @@ func main() {
|
||||||
experiment.InitPheromone("1", color.RGBA{0x00, 0xFF, 0x00, 0x00})
|
experiment.InitPheromone("1", color.RGBA{0x00, 0xFF, 0x00, 0x00})
|
||||||
experiment.InitPheromone("2", color.RGBA{0xFF, 0x00, 0xFF, 0x00})
|
experiment.InitPheromone("2", color.RGBA{0xFF, 0x00, 0xFF, 0x00})
|
||||||
experiment.InitPheromone("3", color.RGBA{0xFF, 0x00, 0x00, 0x00})
|
experiment.InitPheromone("3", color.RGBA{0xFF, 0x00, 0x00, 0x00})
|
||||||
fmt.Printf("Step, Votes for 1, Votes for 2\n")
|
fmt.Printf("Step, Votes for 1, Votes for 2, Honest Votes for 1, Honest Votes for 2, Byzantine Vots for 1, Byzantine Votes for 2\n")
|
||||||
experiment.OnStep = func(env *core.Environment, turtles []*core.Turtle, step int) {
|
experiment.OnStep = func(env *core.Environment, turtles []*core.Turtle, step int) {
|
||||||
num1 := 0
|
num1 := 0
|
||||||
num2 := 0
|
num2 := 0
|
||||||
|
bnum1 := 0
|
||||||
|
bnum2 := 0
|
||||||
|
|
||||||
env.EvaporateAndDiffuse(0.99, "1")
|
env.EvaporateAndDiffuse(0.99, "1")
|
||||||
env.EvaporateAndDiffuse(0.99, "2")
|
env.EvaporateAndDiffuse(0.99, "2")
|
||||||
env.EvaporateAndDiffuse(0.99, "3")
|
env.EvaporateAndDiffuse(0.99, "3")
|
||||||
|
|
||||||
for _, turtle := range turtles {
|
if (*isolate) && step == 50 || !(*isolate) && step == 0 {
|
||||||
agent := turtle.GetActor().(*Snowball)
|
honestTurtles := experiment.GetNumTurtles() - (*byzantineTurtles)
|
||||||
if agent.GetColor() == 0 {
|
experiment.InitNTurtles(func() core.Actor {
|
||||||
num1++
|
sm := new(Snowball)
|
||||||
|
sm.Probability = *prob
|
||||||
|
return sm
|
||||||
|
}, honestTurtles)
|
||||||
|
} else {
|
||||||
|
for _, turtle := range turtles {
|
||||||
|
agent := turtle.GetActor().(*Snowball)
|
||||||
|
if agent.Byztantine == false {
|
||||||
|
if agent.GetColor() == 1 {
|
||||||
|
num1++
|
||||||
|
} else {
|
||||||
|
num2++
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if agent.GetColor() == 1 {
|
||||||
|
bnum1++
|
||||||
|
} else {
|
||||||
|
bnum2++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if num1 > num2 {
|
||||||
|
vote1Ahead = true
|
||||||
} else {
|
} else {
|
||||||
num2++
|
vote1Ahead = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if step == 0 {
|
//if step == 0 {
|
||||||
fmt.Printf("%v,%v,%v\n", step, num1, num2)
|
fmt.Printf("%v,%v,%v,%v,%v, %v,%v\n", step, num1+bnum1, num2+bnum2, num1, num2, bnum1, bnum2)
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue