1 /** 2 * Copyright: © 2012-2014 Anton Gushcha 3 * License: Subject to the terms of the MIT license, as written in the included LICENSE file. 4 * Authors: NCrashed <ncrashed@gmail.com>, 5 * LeMarwin <lemarwin42@gmail.com>, 6 * Nazgull09 <nazgull90@gmail.com> 7 */ 8 module devol.population; 9 10 import std.stdio; 11 12 import std.random; 13 import std.string; 14 import std.array; 15 import std.algorithm; 16 import std.conv; 17 import std.file; 18 19 public 20 { 21 import devol.individ; 22 } 23 24 interface PopAbstract 25 { 26 void genName(int size); 27 @property string name(); 28 @property void name(string val); 29 @property uint generation(); 30 @property void generation(uint val); 31 @property ulong length(); 32 IndAbstract opIndex( uint i ); 33 IndAbstract[] opSlice( uint a, uint b ); 34 uint opDollar(); 35 int opApply(int delegate(ref IndAbstract) dg); 36 } 37 38 static string getDefChars() 39 { 40 string ret = "qwertyuiopasdfghjklzxcvbnm"; 41 return ret ~ toUpper(ret); 42 } 43 44 alias Population!(getDefChars, Individ) StdPop; 45 46 class Population(alias nameChecker, IndType) 47 if ( is(typeof(nameChecker()) == string) ) 48 : PopAbstract 49 { 50 public: 51 static int DefNameLength = 10; 52 static string DefNameChars = getDefChars(); 53 54 alias IndType IndividType; 55 56 @property uint generation() 57 { 58 return iGeneration; 59 } 60 61 @property void generation(uint val) 62 { 63 //if (val < iGeneration) return; 64 iGeneration = val; 65 } 66 67 this() 68 { 69 inds = new IndType[0]; 70 } 71 72 this(uint size) 73 { 74 inds = new IndType[size]; 75 foreach( ref ind; inds) 76 { 77 ind = new IndType; 78 } 79 } 80 81 void genName(int size = DefNameLength) 82 { 83 auto buff = new char[size]; 84 string chars = nameChecker(); 85 foreach(ref c; buff) 86 { 87 c = chars[uniform(0,chars.length)]; 88 } 89 mName = buff.idup; 90 } 91 92 @property string name() 93 { 94 return mName; 95 } 96 97 @property void name(string val) 98 { 99 string chars = nameChecker(); 100 foreach(i,c; val) 101 { 102 if ( chars.find(c).empty ) 103 { 104 val = val[0..i] ~ chars[uniform(0,chars.length)] ~ val[i+1..$]; 105 } 106 } 107 mName = val; 108 } 109 110 @property ulong length() 111 { 112 return inds.length; 113 } 114 115 IndType opIndex( uint i ) 116 { 117 return inds[i]; 118 } 119 120 IndAbstract[] opSlice( uint a, uint b ) 121 { 122 return cast(IndAbstract[])(inds[a..b]); 123 } 124 125 uint opDollar() 126 { 127 return cast(uint)(inds.length); 128 } 129 130 int opApply(int delegate(ref IndAbstract) dg) 131 { 132 int result = 0; 133 134 foreach( i,ref ind; inds) 135 { 136 IndAbstract inda = (ind); 137 result = dg(inda); 138 if (result) break; 139 } 140 return result; 141 } 142 143 auto opBinary(string m)(IndType val) 144 if (m == "~") 145 { 146 inds ~= val; 147 return this; 148 } 149 150 void addIndivid(IndType val) 151 { 152 if (val is null) return; 153 inds ~= val; 154 } 155 156 void saveBests(string filename) 157 { 158 if (inds.length == 0) return; 159 160 auto sortedInds = inds.sort!"a.fitness > b.fitness"; 161 162 IndType best; 163 int k = 0; 164 165 File* f; 166 try 167 { 168 mkdirRecurse(filename); 169 f = new File(filename~mName~"_g"~to!string(iGeneration), "w"); 170 171 do 172 { 173 best = sortedInds[k++]; 174 f.writeln("Individ №", k,":"); 175 f.writeln(best.programString()); 176 f.writeln("=================================="); 177 } while( k < sortedInds.length && sortedInds[k].fitness >= best.fitness); 178 } catch(Exception e) 179 { 180 writeln("FAILED TO CREATE FILE TO WRITE RESULTED INDIVIDS!!"); 181 } 182 } 183 184 void saveAll(string filename) 185 { 186 File* f; 187 try 188 { 189 mkdirRecurse(filename); 190 f = new File(filename~mName~"_g"~to!string(iGeneration), "w"); 191 192 foreach(i,ind;inds) 193 { 194 f.writeln("Individ №", i,":"); 195 f.writeln(ind.programString()); 196 f.writeln("=================================="); 197 } 198 } catch(Exception e) 199 { 200 writeln("FAILED TO CREATE FILE TO WRITE RESULTED INDIVIDS!!"); 201 } 202 } 203 204 @property auto dup() 205 { 206 auto ret = new Population!(nameChecker, IndType); 207 ret.iGeneration = iGeneration; 208 foreach(ind;inds) 209 ret.inds ~= ind.dup; 210 ret.mName = mName; 211 return ret; 212 } 213 214 void clear() 215 { 216 inds.clear(); 217 } 218 219 protected 220 { 221 uint iGeneration; 222 IndType[] inds; 223 string mName = ""; 224 } 225 }