public static Dna Cross(Dna a, Dna b) { Dna res = new Dna(); Int32 aCount = a.Genom.Count; Int32 bCount = a.Genom.Count; res.Genom = new List <Int32>(aCount); if (aCount <= bCount) { for (int i = 0; i < aCount; i++) { res.Genom.Add((i << 1 & 1) == 0 ? a.Genom[i] : b.Genom[i]); } } else { Int32 point = bCount; for (int i = 0; i < aCount; i++) { if (i < point) { res.Genom.Add((i << 1 & 1) == 0 ? a.Genom[i] : b.Genom[i]); } else { res.Genom.Add(a.Genom[i]); } } } return(res); }
public static Dna New(Node[] nodes, Int32 start, Random rand, object randLock) { Dna res = new Dna(); Int32 pathLen; lock (randLock) pathLen = rand.Next(nodes.Length - 1, nodes.Length + (nodes.Length >> 1)); Int32 nodeIndex = start; Int32 lastNode; res.Genom = new List <Int32>(pathLen); for (int i = 0; i < pathLen; i++) { lastNode = nodeIndex; res.Genom.Add(nodeIndex); lock (randLock) nodeIndex = nodes[nodeIndex].NodesId[rand.Next(0, nodes[nodeIndex].NodesId.Length)]; } return(res); }
public bool Start(Int32 population, Int32 generations, Int32 startNode, Int32 ver) { Edge[] srcEdge = edges.ToArray(); Node[] srcNode = nodes.ToArray(); individuals = new List <Dna>(population); List <Dna> nexIndividuals = new List <Dna>(population); Int32 populationLen; Parallel.For(0, population, x => { var tmp = Dna.New(srcNode, startNode, rand, randLock); lock (individualsLock) individuals.Add(tmp); }); population /= 2; for (int i = 0; i < generations; i++) { individuals = individuals.AsParallel().Where(x => x.Validate(srcEdge, srcNode)).OrderBy(x => x.Length(srcEdge)).ToList(); if (i % callbackStep == 0) { if (individuals.Count != 0) { UpdateGenerationStep?.Invoke(i.ToString(), individuals.First().Length(srcEdge).ToString(), individuals.AsParallel().Average(x => x.Length(srcEdge)).ToString()); } else { UpdateGenerationStep?.Invoke(i.ToString(), "NaN", "NaN"); } } if (individuals.Count == 0) { individuals.Clear(); Parallel.For(0, population, x => { var tmp = Dna.New(srcNode, startNode, rand, randLock); lock (individualsLock) individuals.Add(tmp); }); } populationLen = individuals.Count; nexIndividuals = new List <Dna>(individuals.Take(populationLen >> 1)); Parallel.For(0, population >> 1, x => { Int32 ia, ib; lock (randLock) { ia = rand.Next(0, populationLen >> 1); ib = rand.Next(0, populationLen >> 1); } if (ia == ib) { ib = (ib + 1) % populationLen; } var tmp = Dna.Cross(individuals[ia], individuals[ib]); lock (individualsLock) nexIndividuals.Add(tmp); tmp = Dna.Cross(individuals[ib], individuals[ia]); lock (individualsLock) nexIndividuals.Add(tmp); tmp = Dna.New(srcNode, startNode, rand, randLock); lock (individualsLock) nexIndividuals.Add(tmp); tmp = Dna.New(srcNode, startNode, rand, randLock); lock (individualsLock) nexIndividuals.Add(tmp); }); individuals = new List <Dna>(nexIndividuals); Parallel.For(0, individuals.Count, x => individuals[x].Mutate(ver, rand, randLock, srcNode)); } individuals = individuals.AsParallel().Where(x => x.Validate(srcEdge, srcNode)).OrderBy(x => x.Length(srcEdge)).ToList(); if (individuals.Count == 0) { return(false); } return(true); }