Search code examples
javamultithreadingalgorithmclasscomparable

Can't get Comparable Interface Working


I'm developing a linear Evol.Algrm. and I'm implementing 'Comparable' for my genomes to make evaluation simpler; here's the class:

public class Chromosome extends Thread implements Comparable
{
    private String[] chromosome;
private double fitness;
private Random chromoGen;


public Chromosome(double[] candidate)
{        
    super();
    //encode candidate PER parameter; using Matrix as storage
    chromosome = encode(candidate);
}
//De-fault
public Chromosome()
{
    super();
}


public int compareTo(Chromosome c)
{
    return (fitness - c.fitness);
}

/**
 * Fitness stored in chromosome!
 */
public void setFitness()
{
    fitness = FF.fitness(this);
}

public double getFitness()
{
    return fitness;
}

/**
 * ENCODERS/DECODERS
 */
public String[] encode(double[] solution)
{
    //subtract 2^n from solution until you reach 2^-n

    /**
     * THE PRECISION IS [2^10 <-> 2^-8]!!!
     */
    double parameter = 0.00;
    String row = "";
    String[] encoded = new String[6];
    for (int j = 0; (j < 6); j++){
        parameter = solution[j];
        for (int i = 10; (i < (-8)); i--){
            if ((parameter - Math.pow(2, i)) >= 0){
                parameter = parameter - Math.pow(2, i);
                row += "1";
            }
            else{
                row += "0";
            }
        }
        encoded[j] = row;

        //refresh
        row = "";
    }

    return encoded;
}

public String encode(double sol)
{
    //subtract 2^n from solution until you reach 2^-n

    /**
     * THE PRECISION IS [2^10 <-> 2^-8]!!!
     */
    String row = "";

    for (int i = 10; (i < (-8)); i--){
        if ((sol - Math.pow(2, i)) >= 0){
            sol = sol - Math.pow(2, i);
            row += "1";
        }
        else{
            row += "0";
        }
    }

    return row;
}

public double decoded(int number)
{
    //returns UN-ENCODED solution
    double decoded = 0.00;
    String parameter = "";

    parameter = chromosome[number];
    for (int i = 10; (i < (-8)); i--){
        if (parameter.substring(i, (i+1)).equals("1")){
            decoded += Math.pow(2, i);
        }
    }

    return decoded;
}

/**
 * GETTERS
 * ---------------\/--REDUNDANT!!
 */
public double getParameter(int parameter)
{
    //decoded solution
    return decoded(parameter);
}

/**
 * Used in E-algrm.
 */
public String getRow(int row)
{
    //encoded solution
    return chromosome[row];
}

/**
 * SETTERS
 */
public void setRow(String encoded, int row)
{
    chromosome[row] = encoded;
}

public void setRow(double decoded, int row)
{
    chromosome[row] = encode(decoded);
}

/**
 * MUTATIONS IFF (mutate?)
 */
public void mutate(double mutationRate)
{
    //range of: 0-17
    int ran = 0;
    char[] temp;
    for (int m = 0; (m < 6); m++){
        temp = String.toCharArray(chromosome[m]);
        ran = chromoGen.nextDouble();
        if (ran <= mutationRate){
        }
    }
}
}

My question is, even though I clearly implemented the comparison-method; the compiler still isn't happy and says 'Must declare abstract or implement blah blah blah...'

Any help?


Solution

  • You need to make your Comparable a generic interface to be able to pass in a Chromosome type parameter into compareTo. This it should implement Comparable<Chromosome>. Otherwise the compareTo method must be of type Object.

    So if this were your class signature:

    public class Foo implements Comparable {
    

    Then the compareTo method signature must be:

    public int compareTo(Object o) {
    

    And you'd have to do some casting inside of the method. If on the other hand your class signature were

    public class Foo implements Comparable<Foo> {
    

    Then the compareTo method signature must be:

    public int compareTo(Foo o) {
    

    and no casting would be required.

    As a side recommendation, you don't want to extend Thread (especially when I don't see you implementing the public void run() method) as this will unnecessarily restrict your code. Better to implement Runnable, and pass this into a Thread object when needed.