/*
 * OnePointTSPCrossover.java
 *
 * Created on March 30, 2006, 1:32 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package cz.pcland.ga.crossover;
import cz.pcland.ga.BaseIndividual;
import cz.pcland.ga.MyRand;
import cz.pcland.ga.TSPIntegerIndividual;
import java.util.*;
/**
 *
 * @author petr
 */
public class OnePointTSPCrossover implements CrossoverOpearator {
    
    public  String toString() {
        return "TSP 1 point";
    }
    
    protected void swap(int[] str1, int[] str2, int i){
        int tmp = str1[i];
        str1[i] = str2[i];
        str2[i] = tmp;
    }
    
    public BaseIndividual[] crossOver(BaseIndividual i1, BaseIndividual i2, int strLen) {
        TSPIntegerIndividual integer1 = (TSPIntegerIndividual)i1;
        TSPIntegerIndividual integer2 = (TSPIntegerIndividual)i2;
        int position = Math.abs(MyRand.getInt())%strLen; //position = 0..strLen-1
        
        boolean taken1 [] = new boolean[strLen];
        boolean taken2 [] = new boolean[strLen];
        int off1 [] = new int[strLen];
        int off2 [] = new int[strLen];
        
         for(int i=0;i<strLen;i++) {
            if(i<=position) {
                off1[i] = -1;
                off2[i] = -1;
            } else {
                int imother = integer1.getString()[i];
                int ifather = integer2.getString()[i];
                off1[i] = ifather;
                off2[i] = imother;
                taken1[ifather] = true;
                taken2[imother] = true;
            }
        }
        
       for(int i=0;i<=position;i++) {
            if(off1[i] == -1) {
                for(int j=0;j<strLen;j++) {
                    int imother = integer1.getString()[j];
                    if(!taken1[imother]) {
                        off1[i] = imother;
                        taken1[imother] = true;
                        break;
                    }
                }
            }
            if(off2[i] == -1) {
                for(int j=0;j<strLen;j++) {
                    int ifather = integer2.getString()[j];
                    if(!taken2[ifather]) {
                        off2[i] = ifather;
                        taken2[ifather] = true;
                        break;
                    }
                }
            }
        }
        
        
        TSPIntegerIndividual[] ret = {new TSPIntegerIndividual(strLen), new TSPIntegerIndividual(strLen)};
        ret[0].setString(off1);
        ret[1].setString(off2);
        
        return ret;
    }
    /**
     * Creates a new instance of OnePointTSPCrossover
     */
    public OnePointTSPCrossover() {
    }
    
}
