/// <summary> /// Generate two child RoadNetworks by recombining halves of two parent RoadNetworks. /// </summary> /// <param name="parent1">The first parent RoadNetwork</param> /// <param name="parent2">The second parent RoadNetwork</param> /// <param name="child1">The first child RoadNetwork</param> /// <param name="child2">The second child RoadNetwork</param> public static void Conjugate(RoadNetwork parent1, RoadNetwork parent2, out RoadNetwork child1, out RoadNetwork child2) { Cut(parent1); Cut(parent2); List<Vertex> startVertexPartition1 = new List<Vertex>(); List<Vertex> endVertexPartition1 = new List<Vertex>(); List<Vertex> startVertexPartition2 = new List<Vertex>(); List<Vertex> endVertexPartition2 = new List<Vertex>(); List<Edge> startEdgePartition1 = new List<Edge>(); List<Edge> endEdgePartition1 = new List<Edge>(); List<Edge> startEdgePartition2 = new List<Edge>(); List<Edge> endEdgePartition2 = new List<Edge>(); List<Edge> brokenEdgePartition1 = new List<Edge>(); List<Edge> brokenEdgePartition2 = new List<Edge>(); parent1.PartitionVertices(startVertexPartition1, endVertexPartition1); parent2.PartitionVertices(startVertexPartition2, endVertexPartition2); parent1.PartitionEdges(startEdgePartition1, endEdgePartition1, brokenEdgePartition1); parent2.PartitionEdges(startEdgePartition2, endEdgePartition2, brokenEdgePartition2); child1 = new RoadNetwork(parent1.Map); child2 = new RoadNetwork(parent2.Map); child1.CopyVertices(startVertexPartition1); child1.CopyEdges(startEdgePartition1); child1.CopyVertices(endVertexPartition2); child1.CopyEdges(endEdgePartition2); child2.CopyVertices(startVertexPartition2); child2.CopyEdges(startEdgePartition2); child2.CopyVertices(endVertexPartition1); child2.CopyEdges(endEdgePartition1); ShuffleEdges(brokenEdgePartition1); ShuffleEdges(brokenEdgePartition2); int nEdges = Math.Max(brokenEdgePartition1.Count, brokenEdgePartition2.Count); for (int i = 0; i < nEdges; i++) { Vertex start1; Vertex end1; Vertex start2; Vertex end2; GetStartAndEnd(brokenEdgePartition1, i, endVertexPartition1, startVertexPartition1, out start1, out end1); GetStartAndEnd(brokenEdgePartition2, i, endVertexPartition2, startVertexPartition2, out start2, out end2); if (start1 != null && start2 != null) { child2.AddEdge(start1.Copy, end2.Copy); child1.AddEdge(start2.Copy, end1.Copy); } } }