github.com/yaricom/goNEAT@v0.0.0-20210507221059-e2110b885482/neat/genetics/population_test.go (about)

     1  package genetics
     2  
     3  import (
     4  	"testing"
     5  	"github.com/yaricom/goNEAT/neat"
     6  	"math/rand"
     7  	"strings"
     8  	"bytes"
     9  	"bufio"
    10  )
    11  
    12  func TestNewPopulationRandom(t *testing.T) {
    13  	rand.Seed(42)
    14  	in, out, nmax := 3, 2, 5
    15  	recurrent := false
    16  	link_prob := 0.5
    17  	conf := neat.NeatContext{
    18  		CompatThreshold:0.5,
    19  		PopSize:10,
    20  	}
    21  	pop, err := NewPopulationRandom(in, out, nmax, recurrent, link_prob, &conf)
    22  	if err != nil {
    23  		t.Error(err)
    24  	}
    25  	if pop == nil {
    26  		t.Error("pop == nil")
    27  	}
    28  	if len(pop.Organisms) != conf.PopSize {
    29  		t.Error("len(pop.Organisms) != size")
    30  	}
    31  	if pop.nextNodeId != 11 {
    32  		t.Error("pop.currNodeId != 11")
    33  	}
    34  	if pop.nextInnovNum != int64(101) {
    35  		t.Error("pop.currInnovNum != 101")
    36  	}
    37  	if len(pop.Species) == 0 {
    38  		t.Error("len(pop.Species) == 0")
    39  	}
    40  
    41  	for _, org := range pop.Organisms {
    42  		if len(org.Genotype.Genes) == 0 {
    43  			t.Error("len(org.GNome.Genes) == 0")
    44  		}
    45  		if len(org.Genotype.Nodes) == 0 {
    46  			t.Error("len(org.GNome.Nodes) == 0")
    47  		}
    48  		if len(org.Genotype.Traits) == 0 {
    49  			t.Error("len(org.GNome.Traits) == 0")
    50  		}
    51  		if org.Genotype.Phenotype == nil {
    52  			t.Error("org.GNome.Phenotype == nil")
    53  		}
    54  	}
    55  
    56  }
    57  
    58  func TestNewPopulation(t *testing.T) {
    59  	rand.Seed(42)
    60  	in, out, nmax, n := 3, 2, 5, 3
    61  	recurrent := false
    62  	link_prob := 0.5
    63  	conf := neat.NeatContext{
    64  		CompatThreshold:0.5,
    65  		PopSize:10,
    66  	}
    67  	gen := newGenomeRand(1, in, out, n, nmax, recurrent, link_prob)
    68  
    69  	pop, err := NewPopulation(gen, &conf)
    70  	if err != nil {
    71  		t.Error(err)
    72  	}
    73  	if pop == nil {
    74  		t.Error("pop == nil")
    75  	}
    76  	if len(pop.Organisms) != conf.PopSize {
    77  		t.Error("len(pop.Organisms) != conf.PopSize")
    78  	}
    79  	last_node_id, _ := gen.getLastNodeId()
    80  	if pop.nextNodeId != int32(last_node_id + 1) {
    81  		t.Error("pop.currNodeId != last_node_id")
    82  	}
    83  	last_gene_innov_num, _ := gen.getNextGeneInnovNum()
    84  	if pop.nextInnovNum != last_gene_innov_num {
    85  		t.Error("pop.currInnovNum != last_gene_innov_num")
    86  	}
    87  
    88  	for _, org := range pop.Organisms {
    89  		if len(org.Genotype.Genes) == 0 {
    90  			t.Error("len(org.GNome.Genes) == 0")
    91  		}
    92  		if len(org.Genotype.Nodes) == 0 {
    93  			t.Error("len(org.GNome.Nodes) == 0")
    94  		}
    95  		if len(org.Genotype.Traits) == 0 {
    96  			t.Error("len(org.GNome.Traits) == 0")
    97  		}
    98  		if org.Genotype.Phenotype == nil {
    99  			t.Error("org.GNome.Phenotype == nil")
   100  		}
   101  	}
   102  }
   103  
   104  func TestReadPopulation(t *testing.T) {
   105  	pop_str := "genomestart 1\n" +
   106  		"trait 1 0.1 0 0 0 0 0 0 0\n" +
   107  		"trait 2 0.2 0 0 0 0 0 0 0\n" +
   108  		"trait 3 0.3 0 0 0 0 0 0 0\n" +
   109  		"node 1 0 1 1\n" +
   110  		"node 2 0 1 1\n" +
   111  		"node 3 0 1 3\n" +
   112  		"node 4 0 0 2\n" +
   113  		"gene 1 1 4 1.5 false 1 0 true\n" +
   114  		"gene 2 2 4 2.5 false 2 0 true\n" +
   115  		"gene 3 3 4 3.5 false 3 0 true\n" +
   116  		"genomeend 1\n" +
   117  		"genomestart 2\n" +
   118  		"trait 1 0.1 0 0 0 0 0 0 0\n" +
   119  		"trait 2 0.2 0 0 0 0 0 0 0\n" +
   120  		"trait 3 0.3 0 0 0 0 0 0 0\n" +
   121  		"node 1 0 1 1\n" +
   122  		"node 2 0 1 1\n" +
   123  		"node 3 0 1 3\n" +
   124  		"node 4 0 0 2\n" +
   125  		"gene 1 1 4 1.5 false 1 0 true\n" +
   126  		"gene 2 2 4 2.5 false 2 0 true\n" +
   127  		"gene 3 3 4 3.5 false 3 0 true\n" +
   128  		"genomeend 2\n"
   129  	conf := neat.NeatContext{
   130  		CompatThreshold:0.5,
   131  	}
   132  	pop, err := ReadPopulation(strings.NewReader(pop_str), &conf)
   133  	if err != nil {
   134  		t.Error(err)
   135  		return
   136  	}
   137  	if pop == nil {
   138  		t.Error("pop == nil")
   139  	}
   140  	if len(pop.Organisms) != 2 {
   141  		t.Error("len(pop.Organisms) != size")
   142  	}
   143  	if len(pop.Species) != 1 {
   144  		// because genomes are identical
   145  		t.Error("len(pop.Species) != 1", len(pop.Species))
   146  	}
   147  }
   148  
   149  func TestPopulation_verify(t *testing.T) {
   150  	// first create population
   151  	pop_str := "genomestart 1\n" +
   152  		"trait 1 0.1 0 0 0 0 0 0 0\n" +
   153  		"trait 2 0.2 0 0 0 0 0 0 0\n" +
   154  		"trait 3 0.3 0 0 0 0 0 0 0\n" +
   155  		"node 1 0 1 1\n" +
   156  		"node 2 0 1 1\n" +
   157  		"node 3 0 1 3\n" +
   158  		"node 4 0 0 2\n" +
   159  		"gene 1 1 4 1.5 false 1 0 true\n" +
   160  		"gene 2 2 4 2.5 false 2 0 true\n" +
   161  		"gene 3 3 4 3.5 false 3 0 true\n" +
   162  		"genomeend 1\n" +
   163  		"genomestart 2\n" +
   164  		"trait 1 0.1 0 0 0 0 0 0 0\n" +
   165  		"trait 2 0.2 0 0 0 0 0 0 0\n" +
   166  		"trait 3 0.3 0 0 0 0 0 0 0\n" +
   167  		"node 1 0 1 1\n" +
   168  		"node 2 0 1 1\n" +
   169  		"node 3 0 1 3\n" +
   170  		"node 4 0 0 2\n" +
   171  		"gene 1 1 4 1.5 false 1 0 true\n" +
   172  		"gene 2 2 4 2.5 false 2 0 true\n" +
   173  		"gene 3 3 4 3.5 false 3 0 true\n" +
   174  		"genomeend 2\n"
   175  	conf := neat.NeatContext{
   176  		CompatThreshold:0.5,
   177  	}
   178  	pop, err := ReadPopulation(strings.NewReader(pop_str), &conf)
   179  	if err != nil {
   180  		t.Error(err)
   181  		return
   182  	}
   183  	if pop == nil {
   184  		t.Error("pop == nil")
   185  	}
   186  
   187  	// then verify created
   188  	res, err := pop.Verify()
   189  	if err != nil {
   190  		t.Error(err)
   191  	}
   192  	if !res {
   193  		t.Error("Population verification failed, but must not")
   194  	}
   195  }
   196  
   197  func TestPopulation_Write(t *testing.T) {
   198  	// first create population
   199  	pop_str := "genomestart 1\n" +
   200  		"trait 1 0.1 0 0 0 0 0 0 0\n" +
   201  		"trait 2 0.2 0 0 0 0 0 0 0\n" +
   202  		"trait 3 0.3 0 0 0 0 0 0 0\n" +
   203  		"node 1 0 1 1\n" +
   204  		"node 2 0 1 1\n" +
   205  		"node 3 0 1 3\n" +
   206  		"node 4 0 0 2\n" +
   207  		"gene 1 1 4 1.5 false 1 0 true\n" +
   208  		"gene 2 2 4 2.5 false 2 0 true\n" +
   209  		"gene 3 3 4 3.5 false 3 0 true\n" +
   210  		"genomeend 1\n" +
   211  		"genomestart 2\n" +
   212  		"trait 1 0.1 0 0 0 0 0 0 0\n" +
   213  		"trait 2 0.2 0 0 0 0 0 0 0\n" +
   214  		"trait 3 0.3 0 0 0 0 0 0 0\n" +
   215  		"node 1 0 1 1\n" +
   216  		"node 2 0 1 1\n" +
   217  		"node 3 0 1 3\n" +
   218  		"node 4 0 0 2\n" +
   219  		"gene 1 1 4 1.5 false 1 0 true\n" +
   220  		"gene 2 2 4 2.5 false 2 0 true\n" +
   221  		"gene 3 3 4 3.5 false 3 0 true\n" +
   222  		"genomeend 2\n"
   223  	conf := neat.NeatContext{
   224  		CompatThreshold:0.5,
   225  	}
   226  	pop, err := ReadPopulation(strings.NewReader(pop_str), &conf)
   227  	if err != nil {
   228  		t.Error(err)
   229  		return
   230  	}
   231  	if pop == nil {
   232  		t.Error("pop == nil")
   233  		return
   234  	}
   235  
   236  	// write it again and test
   237  	out_buf := bytes.NewBufferString("")
   238  	pop.Write(out_buf)
   239  
   240  	_, p_str_r, err_p := bufio.ScanLines([]byte(pop_str), true)
   241  	_, o_str_r, err_o := bufio.ScanLines(out_buf.Bytes(), true)
   242  	if err_p != nil || err_o != nil {
   243  		t.Error("Failed to parse strings", err_o, err_p)
   244  	}
   245  	for i, gsr := range p_str_r {
   246  		if gsr != o_str_r[i] {
   247  			t.Error("Lines mismatch", gsr, o_str_r[i])
   248  		}
   249  	}
   250  }