title: Java Fitness Function - Scales
body: <p>I have a fitness function as part of a lab and wish to apply it to a set of 'weights' (ArrayList weights). I have created the array and stored some values in it. I have created random binary strings (which have an 'x' at the end in order to generate random values) which I wish to also apply the fitness function to; however, the problem I am having is that the fitness function always returns a value of 0. Am I missing something here?</p>
  
  <p>The fitness function is as follows:</p>
  
  <pre><code>import java.util.*;
  public class ScalesSolution{
  private static String scasol;
  //Creates a new scales solution based on a string parameter
  //The string parameter is checked to see if it contains all zeros and ones
  //Otherwise the random binary string generator is used (n = length of parameter)
  
  public ScalesSolution(String s)
  {
      boolean ok = true;
      int n = s.length();
      for(int i=0;i&lt;n;++i)
      {
          char si = s.charAt(i);
          if (si != '0' &amp;&amp; si != '1') ok = false;
      }
      if (ok)
      {
          scasol = s;
      }
      else
      {
          scasol = RandomBinaryString(n);
      }
  }
  
  private static String RandomBinaryString(int n)
  {
      String s = new String();
      //Code goes here
      //Create a random binary string of just ones and zeros of length n
      for(int i = 0; i &lt; n; i++){
          int x = CS2004.UI(0,1);
              if(x == 0){
                  System.out.print(s + '0');
              }
              else if(x == 1){
                  System.out.print(s + '1');
              }
      }
      return(s);
  }
  
  public ScalesSolution(int n) 
  {
      scasol = RandomBinaryString(n); 
  }
  
  //This is the fitness function for the Scales problem
  //This function returns -1 if the number of weights is less than
  //the size of the current solution
  //EXERCISE 3
  public static double ScalesFitness(ArrayList&lt;Double&gt; weights)
  {
      int n = scasol.length();
      double lhs = 0.0, rhs = 0.0;
      if (n &gt; weights.size()) return(-1);
  
      for(int i = 0; i &lt; n; i++){
          if(scasol.charAt(i) == 0){
              lhs += weights.get(i);
          }
          else{
              rhs += weights.get(i);
          }
      }       
      //Code goes here
      //Check each element of scasol for a 0 (lhs) and 1 (rhs) add the weight wi
      //to variables lhs and rhs as appropriate
      return(Math.abs(lhs-rhs));
  }
  
  //Display the string without a new line
  public void print()
  {
      System.out.print(scasol);
  }
  //Display the string with a new line
  public void println()
  {
      print();
      System.out.println();
  }}
  </code></pre>
  
  <p>Main method (in separate class):</p>
  
  <pre><code>import java.util.ArrayList;
  public class Lab8 {
  
  public static void main(String args[])
  {
      for(int i = 0; i &lt; 10; i++){
          ScalesSolution s = new ScalesSolution("10101x");
          s.println();
      }
  
  
      ArrayList&lt;Double&gt; weights = new ArrayList&lt;Double&gt;();
      weights.add(1.0);
      weights.add(2.0);
      weights.add(3.0);
      weights.add(4.0);
      weights.add(10.0);
      System.out.println();
      System.out.println(weights);
      System.out.print("Fitness: ");
  
      double fitness = ScalesSolution.ScalesFitness(weights);
      System.out.println(fitness);
  
  }}
  </code></pre>
  
  <p>CS2004 class:</p>
  
  <pre><code>import java.util.*;
  import java.io.*;
  
  //Some useful code that we will probably reuse in later laboratories...
  public class CS2004 
  {
  //Shared random object
  static private Random rand;
  //Create a uniformly distributed random integer between aa and bb inclusive
  static public int UI(int aa,int bb)
  {
      int a = Math.min(aa,bb);
      int b = Math.max(aa,bb);
      if (rand == null) 
      {
          rand = new Random();
          rand.setSeed(System.nanoTime());
      }
      int d = b - a + 1;
      int x = rand.nextInt(d) + a;
      return(x);
  }
  //Create a uniformly distributed random double between a and b inclusive
  static public double UR(double a,double b)
  {
      if (rand == null) 
      {
          rand = new Random();
          rand.setSeed(System.nanoTime());
      }
      return((b-a)*rand.nextDouble()+a);
  }
  //This method reads in a text file and parses all of the numbers in it
  //This code is not very good and can be improved!
  //But it should work!!!
  //It takes in as input a string filename and returns an array list of Doubles
  static public ArrayList&lt;Double&gt; ReadNumberFile(String filename)
  {
      ArrayList&lt;Double&gt; res = new ArrayList&lt;Double&gt;();
      Reader r;
      try
      {
          r = new BufferedReader(new FileReader(filename));
          StreamTokenizer stok = new StreamTokenizer(r);
          stok.parseNumbers();
          stok.nextToken();
          while (stok.ttype != StreamTokenizer.TT_EOF) 
          {
              if (stok.ttype == StreamTokenizer.TT_NUMBER)
              {
                  res.add(stok.nval);
              }
              stok.nextToken();
          }
      }
      catch(Exception E)
      {
          System.out.println("+++ReadFile: "+E.getMessage());
      }
      return(res);
  }}
  </code></pre>
  
  <p>Once run, the random binary strings work perfectly well, yet the fitness function fails to change from 0. Here is a sample output:</p>
  
  <pre><code>011100
  111010
  001110
  111011
  001000
  010101
  001010
  100011
  110100
  011001
  
  [1.0, 2.0, 3.0, 4.0, 10.0]
  Fitness: 0.0
  </code></pre>
  
  <p>Thank you all so much for your time.
  Stefanos.</p>