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 }