protected override void PerformMutation(IGraphChromosome graph, float probability) { if (RandomizationProvider.Current.GetDouble() >= probability) { return; } // No edges to add if (graph.EdgeCount == graph.VertexCount * graph.VertexCount) { return; } // Shuffle var allIDs = graph.Vertices.Select(v => v.ID); uint[] fromVerts = MutationService.Shuffle(allIDs, RandomizationProvider.Current).ToArray(); uint[] toVerts = MutationService.Shuffle(allIDs, RandomizationProvider.Current).ToArray(); // Find the first that does not exist foreach (var v1 in fromVerts) { foreach (var v2 in toVerts) { if (!graph.ContainsEdge(v1, v2)) { graph.AddEdge(v1, v2, graph.CreateNewEdge()); return; } } } }
/// <summary> /// Calculates the total distance between two graphs, only /// accounting for edges. /// </summary> /// <param name="g1"></param> /// <param name="g2"></param> /// <returns></returns> protected double TotalEdgeDistance(IGraphChromosome g1, IGraphChromosome g2) { double totalDist = 0; double nMismatch = 0; double nMatch = 0; foreach (var edge in g1.Edges) { if (g2.ContainsEdge(edge.IDFrom, edge.IDTo)) { totalDist += EdgeDistance(g2[edge.IDFrom, edge.IDTo], edge.Value); nMatch++; } else { nMismatch++; } } foreach (var edge in g2.Edges) { if (!g1.ContainsEdge(edge.IDFrom, edge.IDTo)) { nMismatch++; } } int N = Math.Max(g1.EdgeCount, g2.EdgeCount); return((EdgeMismatchWeight * nMismatch / N) + (EdgeMatchWeight * totalDist / nMatch)); }
protected override IGraphChromosome PerformCrossover(IGraphChromosome p1, IGraphChromosome p2) { IList <IChromosome> parents = new IChromosome[2]; // "Disjoint genes are inherited from the more fit parent." var child = p1.Clone() as IGraphChromosome; foreach (var vert in p1.Vertices) { if (p2.ContainsVertex(vert.ID)) { parents[0] = vert.Value; parents[1] = p2[vert.ID]; child[vert.ID] = VertexCrossover.Cross(parents)[0]; } } foreach (var edge in p1.Edges) { if (p2.ContainsEdge(edge.IDFrom, edge.IDTo)) { parents[0] = edge.Value; parents[1] = p2[edge.IDFrom, edge.IDTo]; child[edge.IDFrom, edge.IDTo] = EdgeCrossover.Cross(parents)[0]; } } return(child); }