package opt.example; import dist.Distribution; import opt.ga.CrossoverFunction; import shared.Instance; /** * A cross over function for a traveling * salesman problem, based on * @author Andrew Guillory gtg008g@mail.gatech.edu * @version 1.0 */ public class TravelingSalesmanCrossOver implements CrossoverFunction { /** * The evaluation function */ private TravelingSalesmanEvaluationFunction eval; /** * Make a new traveling salesman cross over * @param eval the evaluation function to use */ public TravelingSalesmanCrossOver(TravelingSalesmanEvaluationFunction eval) { this.eval = eval; } /** * @see opt.ga.CrossOverFunction#mate(opt.OptimizationData, opt.OptimizationData) */ public Instance mate(Instance a, Instance b) { int[] nexta = new int[a.size()]; int[] nextb = new int[b.size()]; for (int i = 0; i < a.size() - 1; i++) { nexta[a.getDiscrete(i)] = a.getDiscrete(i+1); nextb[b.getDiscrete(i)] = b.getDiscrete(i+1); } nexta[a.getDiscrete(a.size() - 1)] = a.getDiscrete(0); nexta[b.getDiscrete(b.size() - 1)] = b.getDiscrete(0); boolean[] visited = new boolean[a.size()]; int[] child = new int[a.size()]; child[0] = Distribution.random.nextInt(a.size()); visited[child[0]] = true; for (int i = 0; i < child.length - 1; i++) { int cur = child[i]; int na = nexta[cur]; int nb = nextb[cur]; int next = -1; if (visited[na] && !visited[nb]) { next = nb; } else if (visited[nb] && !visited[na]) { next = na; } else if (!visited[na] && !visited[nb]) { if (eval.getDistance(cur, na) < eval.getDistance(cur, nb)) { next = na; } else { next = nb; } } else { do { next = Distribution.random.nextInt(a.size()); } while (visited[next]); } child[i+1] = next; visited[next] = true; } double[] data = new double[child.length]; for (int i = 0; i < child.length; i++) { data[i] = child[i]; } return new Instance(data); } }