Browse Source

Update genetic algorythm

Alexey Edelev 5 năm trước cách đây
mục cha
commit
0d4f0781c7

+ 7 - 4
neuralnetwork/genetic/mutagen/dummymutagen.go

@@ -1,6 +1,7 @@
 package mutagen
 
 import (
+	"fmt"
 	"math/rand"
 	"time"
 
@@ -24,10 +25,12 @@ func (rm *DummyMutagen) Mutate(network *neuralnetwork.NeuralNetwork) {
 		randomized := rand.Float64()
 		if randomized < (float64(rm.chance) / 100.0) {
 			r, c := network.Weights[l].Dims()
-			mutationRow := int(rand.Uint32()) % r
-			mutationColumn := int(rand.Uint32()) % c
-			weight := rand.Float64()
-			network.Weights[l].Set(mutationRow, mutationColumn, weight)
+			for o := 0; o < 10; o++ {
+				mutationRow := int(rand.Uint32()) % r
+				mutationColumn := int(rand.Uint32()) % c
+				weight := rand.Float64()
+				network.Weights[l].Set(mutationRow, mutationColumn, weight)
+			}
 		}
 	}
 }

+ 8 - 3
neuralnetwork/main.go

@@ -3,15 +3,21 @@ package main
 import (
 	genetic "./genetic"
 	mutagen "./genetic/mutagen"
+	remotecontrol "./remotecontrol"
 	snakesimulator "./snakesimulator"
 )
 
 func main() {
+	rc := &remotecontrol.RemoteControl{}
+	go rc.Run()
 	s := snakesimulator.NewSnakeSimulator()
 	s.StartServer()
-	p := genetic.NewPopulation(s, mutagen.NewDummyMutagen(50), 40, []int{16, 12, 12, 4})
+	p := genetic.NewPopulation(s, mutagen.NewDummyMutagen(50), 400, []int{16, 18, 18, 4})
+	for _, net := range p.Networks {
+		net.SetStateWatcher(rc)
+	}
 	p.NaturalSelection(200)
-	// s.Run()
+	s.Run()
 
 	// sizes := []int{13, 8, 12, 3}
 	// nn, _ := neuralnetwork.NewNeuralNetwork(sizes, neuralnetwork.NewRPropInitializer(neuralnetwork.RPropConfig{
@@ -21,7 +27,6 @@ func main() {
 	// 	DeltaMin: 0.000001,
 	// }))
 
-	// rc := &remotecontrol.RemoteControl{}
 	// nn.SetStateWatcher(rc)
 	// rc.Run()
 

+ 38 - 10
neuralnetwork/snakesimulator/snakesimulator.go

@@ -54,12 +54,40 @@ func (s *SnakeSimulator) Verify(population *genetic.Population) (results []*gene
 		s.statsUpdateQueue <- true
 
 		s.field.GenerateNextFood()
-		s.snake = &Snake{
-			Points: []*Point{
-				&Point{X: 20, Y: 20},
-				&Point{X: 21, Y: 20},
-				&Point{X: 22, Y: 20},
-			},
+		rand.Seed(time.Now().UnixNano())
+		switch rand.Uint32() % 4 {
+		case 1:
+			s.snake = &Snake{
+				Points: []*Point{
+					&Point{X: 20, Y: 20},
+					&Point{X: 21, Y: 20},
+					&Point{X: 22, Y: 20},
+				},
+			}
+		case 2:
+			s.snake = &Snake{
+				Points: []*Point{
+					&Point{X: 22, Y: 20},
+					&Point{X: 21, Y: 20},
+					&Point{X: 20, Y: 20},
+				},
+			}
+		case 3:
+			s.snake = &Snake{
+				Points: []*Point{
+					&Point{X: 20, Y: 20},
+					&Point{X: 20, Y: 21},
+					&Point{X: 20, Y: 22},
+				},
+			}
+		default:
+			s.snake = &Snake{
+				Points: []*Point{
+					&Point{X: 20, Y: 22},
+					&Point{X: 20, Y: 21},
+					&Point{X: 20, Y: 20},
+				},
+			}
 		}
 
 		i := 0
@@ -190,10 +218,10 @@ func (s *SnakeSimulator) GetHeadState() []float64 {
 		float64(rWall) / float64(width),
 		float64(tWall) / float64(height),
 		float64(bWall) / float64(height),
-		float64(lFood) / float64(width),
-		float64(rFood) / float64(width),
-		float64(tFood) / float64(height),
-		float64(bFood) / float64(height),
+		float64(lFood) / float64(lWall),
+		float64(rFood) / float64(rWall),
+		float64(tFood) / float64(tWall),
+		float64(bFood) / float64(bWall),
 		float64(tlFood) / diag,
 		float64(trFood) / diag,
 		float64(blFood) / diag,