tags:

views:

503

answers:

4

I am trying to convert these small math calls to Java from C# and just wanted to make sure that they operate the same way. I added one additional call as it is not supported in Java.

Here is code in C#

public override int CompareTo(object a)
{
EquationGenome Gene1 = this;
EquationGenome Gene2 = (EquationGenome)a;
return Math.Sign(Gene2.CurrentFitness  -  Gene1.CurrentFitness);
}


Java:

Notice the Math.Sign is not being called.

/**
* Compare to.
*/
public int compareTo(final Object a) {

    final EquationGenome gene1 = this;
    final EquationGenome gene2 = (EquationGenome) a;
    return (int) ((-1.0) * (gene2.currentFitness - gene1.currentFitness));
}

And here is one to replicate C#'s 'next' with two int parameters in Java:

public static final int nextInt(final Random r, final int min, final int max) {

    final int diff = max - min;
    final int n = r.nextInt(diff);
    return n + min;

}

Are these methods equivalent from C# to Java?

+1  A: 

No, because Math.Sign in C# returns one of three values: -1 if the value is < 0, 0 if the value is equal to 0, and 1 if the value is greater than 0. It doesn't flip the sign by multiplying by -1 as you're doing in the Java code.

In C# the CompareTo function expects -1 to mean that the object on which it is called is less than the object being passed in. Since you're returning the sign of subtracting value 1 from value 2, this will be switched. I doubt this is what you want for your algorithm, given your Java code. Traditionally you would subtract value 2 from value 1 and use that sign.

Adam Robinson
+2  A: 

Why not just use Java's compareTo? This is assuming currentFitness is of type Integer and not the primitive type int. Otherwise you can just wrap it in Integer. This is not the most efficient method but it's more clear to me.

/**
* Compare to.
*/
public int compareTo(final Object a) {

    final EquationGenome gene1 = this;
    final EquationGenome gene2 = (EquationGenome) a;
    return gene1.currentFitness.compareTo(gene2.currentFitness);
}
CookieOfFortune
OK, I didn't think about it at the time.
Berlin Brown
I'm a little confused...isn't the point of this question to convert Java code to C#?
Adam Robinson
"to Java from C#"
CookieOfFortune
my last line works in C# code too without any changes I believe.
CookieOfFortune
DOH! I guess I'm the one that can't read.
Adam Robinson
A: 

If your Java version of EquationGenome implements the Comparable interface, you'll be able to take advantage of many Java APIs. This would alter your class to look like this:

final class EquationGenome
  implements Comparable<EquationGenome>
{
  ...
  public int compareTo(final EquationGenome gene2) ...

Then, what you are doing with the multiplication isn't clear. I assume the "natural order" is from most fit to least fit. Then I'd implement the comparison like this:

public int compareTo(final EquationGenome that) {
  if (currentFitness == that.currentFitness) {
    /* TODO: Add more tests if there are other properties that distinguish
     * one EquationGenome from another (secondary sort keys). */
    return 0;
  } else 
    return (currentFitness > that.currentFitness) ? -1 : +1;
}

By convention, you should either implement the equals method to be "consistent" with your compareTo method, or clearly document your class to note the inconsistency. If you implement equals, you should also implement hashCode for consistency too.

public boolean equals(Object o) {
  return o instanceof EquationGenome && compareTo((EquationGenome) o) == 0;
}

public int hashCode() {
  return currentFitness;
}


The method for producing random numbers is alright, as long as you understand that max is excluded; the method generates random numbers from the half-open interval (min, max]. If you want to include max in the range, add one to diff.

erickson
A: 

I would write something like.

Note: You have be very careful using Comparator with mutable fields as this can have undesirable side effects.

public class EquationGenome implenents Comparable<EquationGenome> {
    private final double currentFitness;
    public EquationGenome(double currentFitness) {
        this.currentFitness = currentFitness;
    }

    public int compareTo(EquationGenome eg) {
        return Double.compareTo(currentFitness, eg.currentFitness);
    }
}
Peter Lawrey