github.com/yaricom/goNEAT@v0.0.0-20210507221059-e2110b885482/experiments/generation_test.go (about)

     1  package experiments
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/gob"
     6  	"testing"
     7  	"time"
     8  	"reflect"
     9  
    10  	"github.com/yaricom/goNEAT/neat"
    11  	"github.com/yaricom/goNEAT/neat/utils"
    12  	"github.com/yaricom/goNEAT/neat/genetics"
    13  	"github.com/yaricom/goNEAT/neat/network"
    14  )
    15  
    16  // Tests encoding/decoding of generation
    17  func TestGeneration_Encode_Decode(t *testing.T) {
    18  	genome_id, fitness := 10, 23.0
    19  	gen := buildTestGeneration(genome_id, fitness)
    20  
    21  	var buff bytes.Buffer
    22  	enc := gob.NewEncoder(&buff)
    23  
    24  	// encode generation
    25  	err := gen.Encode(enc)
    26  	if err != nil {
    27  		t.Error("failed to encode generation", err)
    28  		return
    29  	}
    30  
    31  	// decode generation
    32  	data := buff.Bytes()
    33  	dec := gob.NewDecoder(bytes.NewBuffer(data))
    34  	dgen := &Generation{}
    35  	err = dgen.Decode(dec)
    36  	if err != nil {
    37  		t.Error("failed to dencode generation", err)
    38  		return
    39  	}
    40  
    41  	//  and test fields
    42  	deepCompareGenerations(gen, dgen, t)
    43  }
    44  
    45  func deepCompareGenerations(first, second *Generation, t *testing.T) {
    46  	if first.Id != second.Id {
    47  		t.Error("first.Id != second.Id")
    48  	}
    49  	if first.Executed != second.Executed {
    50  		t.Errorf("first.Executed != second.Executed, %s != %s\n", first.Executed, second.Executed)
    51  	}
    52  	if first.Solved != second.Solved {
    53  		t.Error("first.Solved != second.Solved")
    54  	}
    55  
    56  	if !reflect.DeepEqual(first.Fitness, second.Fitness) {
    57  		t.Error("Fitness values mismatch")
    58  	}
    59  	if !reflect.DeepEqual(first.Age, second.Age) {
    60  		t.Error("Age values mismatch")
    61  	}
    62  	if !reflect.DeepEqual(first.Compexity, second.Compexity) {
    63  		t.Error("Compexity values mismatch")
    64  	}
    65  
    66  	if first.Diversity != second.Diversity {
    67  		t.Error("first.Diversity != second.Diversity")
    68  	}
    69  	if first.WinnerEvals != second.WinnerEvals {
    70  		t.Error("first.WinnerEvals != second.WinnerEvals")
    71  	}
    72  	if first.WinnerNodes != second.WinnerNodes {
    73  		t.Error("first.WinnerNodes != second.WinnerNodes ")
    74  	}
    75  	if first.WinnerGenes != second.WinnerGenes {
    76  		t.Error("first.WinnerGenes != second.WinnerGenes")
    77  	}
    78  
    79  	if first.Best.Fitness != second.Best.Fitness {
    80  		t.Error("first.Best.Fitness != second.Best.Fitness")
    81  	}
    82  	if first.Best.Genotype.Id != second.Best.Genotype.Id {
    83  		t.Error("first.Best.Genotype.Id != second.Best.Genotype.Id")
    84  	}
    85  
    86  	for i, tr := range second.Best.Genotype.Traits {
    87  		if !reflect.DeepEqual(tr, first.Best.Genotype.Traits[i]) {
    88  			t.Error("Wrong trait found in new genome")
    89  		}
    90  	}
    91  	for i, nd := range second.Best.Genotype.Nodes {
    92  		if !reflect.DeepEqual(nd, first.Best.Genotype.Nodes[i]) {
    93  			t.Error("Wrong node found", nd, first.Best.Genotype.Nodes[i])
    94  		}
    95  	}
    96  
    97  	for i, g := range second.Best.Genotype.Genes {
    98  		if !reflect.DeepEqual(g, first.Best.Genotype.Genes[i]) {
    99  			t.Error("Wrong gene found", g, first.Best.Genotype.Genes[i])
   100  		}
   101  	}
   102  }
   103  
   104  func buildTestGeneration(gen_id int, fitness float64) *Generation {
   105  	epoch := Generation{}
   106  	epoch.Id = gen_id
   107  	epoch.Executed = time.Now().Round(time.Second)
   108  	epoch.Solved = true
   109  	epoch.Fitness = Floats{10.0, 30.0, 40.0, fitness}
   110  	epoch.Age = Floats{1.0, 3.0, 4.0, 10.0}
   111  	epoch.Compexity = Floats{34.0, 21.0, 56.0, 15.0}
   112  	epoch.Diversity = 32
   113  	epoch.WinnerEvals = 12423
   114  	epoch.WinnerNodes = 7
   115  	epoch.WinnerGenes = 5
   116  
   117  	genome := buildTestGenome(gen_id)
   118  	org := genetics.Organism{Fitness:fitness, Genotype:genome, Generation:gen_id}
   119  	epoch.Best = &org
   120  
   121  	return &epoch
   122  }
   123  
   124  func buildTestGenome(id int) *genetics.Genome {
   125  	traits := []*neat.Trait{
   126  		{Id:1, Params:[]float64{0.1, 0, 0, 0, 0, 0, 0, 0}},
   127  		{Id:3, Params:[]float64{0.3, 0, 0, 0, 0, 0, 0, 0}},
   128  		{Id:2, Params:[]float64{0.2, 0, 0, 0, 0, 0, 0, 0}},
   129  	}
   130  
   131  	nodes := []*network.NNode{
   132  		{Id:1, NeuronType: network.InputNeuron, ActivationType: utils.NullActivation, Incoming:make([]*network.Link, 0), Outgoing:make([]*network.Link, 0)},
   133  		{Id:2, NeuronType: network.InputNeuron, ActivationType: utils.NullActivation, Incoming:make([]*network.Link, 0), Outgoing:make([]*network.Link, 0)},
   134  		{Id:3, NeuronType: network.BiasNeuron, ActivationType: utils.SigmoidSteepenedActivation, Incoming:make([]*network.Link, 0), Outgoing:make([]*network.Link, 0)},
   135  		{Id:4, NeuronType: network.OutputNeuron, ActivationType: utils.SigmoidSteepenedActivation, Incoming:make([]*network.Link, 0), Outgoing:make([]*network.Link, 0)},
   136  	}
   137  
   138  	genes := []*genetics.Gene{
   139  		genetics.NewGeneWithTrait(traits[0], 1.5, nodes[0], nodes[3], false, 1, 0),
   140  		genetics.NewGeneWithTrait(traits[2], 2.5, nodes[1], nodes[3], false, 2, 0),
   141  		genetics.NewGeneWithTrait(traits[1], 3.5, nodes[2], nodes[3], false, 3, 0),
   142  	}
   143  
   144  	return genetics.NewGenome(id, traits, nodes, genes)
   145  }