/*
 * BinaryString.java
 *
 * Created on November 2, 2005, 5:20 PM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package cz.pcland.ga;
import cz.pcland.ga.fitness.TSPFitness;
/**
 *
 * @author petr
 */


import java.util.*;

public class TSPIntegerIndividual extends BaseIndividual {
    protected int[] string;
    
    public String toString(){
        String s="";
        for(int i=0;i<this.strLen;i++){
            s+=String.valueOf(string[i]);
        }
        return s;
    }
    
    public BaseIndividual copy() {
        return new TSPIntegerIndividual(this);
    }
    
    public TSPIntegerIndividual(int[] str){
        super(str.length);
        this.string = str;
    }
    
    /* create random binary coded individual */
    public TSPIntegerIndividual(int len) {
        super(len);
        
        boolean taken[] = new boolean[len];
        
        int[] city_list = new int[len];
        
        double cost = 0.0;
        
        for(int i=0;i<len;i++) taken[i] = false;
        
        for(int i=0;i<len-1;i++) {
            int icandidate;
            do {
                icandidate = (int) (Math.random() * (double) len );
            } while(taken[icandidate]);
            
            city_list[i] = icandidate;
            taken[icandidate] = true;
            
            if(i == len-2) {
                icandidate = 0;
                while(taken[icandidate]) icandidate++;
                city_list[i+1] = icandidate;
            }
        }
        
        this.string = city_list;
    }
    
    public void setString(int[] str){
        this.string = str;
    }
    
    /* Copy Constructor for reproduction*/
    TSPIntegerIndividual(TSPIntegerIndividual i) {
        super(i.strLen);
        
        fitness = i.fitness;
        //strLen = i.strLen;
        string = new int[i.strLen];
        for(int iter=0;iter<i.strLen;iter++) {
            string[iter] = i.string[iter];
        }
    }
    
    public void swap(int[] a, int i1, int i2) {
        int tmp = a[i1];
        a[i1] = a[i2];
        a[i2] = tmp;
    }
    
    
    public void mutation(double mutationProb) {
        if(Math.random() < mutationProb) {
            int r1 = Math.abs(MyRand.getInt()%strLen);
            int r2 = Math.abs(MyRand.getInt()%(strLen-1));
            if(r2 >= r1) r2++;
            
            if(r2 < r1) {int temp=r1;r1=r2;r2=temp;}
            
            int c = 0;
            for(int i=r1;i<=r1+(r2-r1)/2;i++){
                swap(string, i, r2 - c); 
                c++;
            }
        }
    }
    
    public int[] getString() {
        return string;
    }
    
    
    
    
    
    
    
}

