Pergunta

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?

The fitness function is as follows:

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<n;++i)
    {
        char si = s.charAt(i);
        if (si != '0' && 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 < 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<Double> weights)
{
    int n = scasol.length();
    double lhs = 0.0, rhs = 0.0;
    if (n > weights.size()) return(-1);

    for(int i = 0; i < 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();
}}

Main method (in separate class):

import java.util.ArrayList;
public class Lab8 {

public static void main(String args[])
{
    for(int i = 0; i < 10; i++){
        ScalesSolution s = new ScalesSolution("10101x");
        s.println();
    }


    ArrayList<Double> weights = new ArrayList<Double>();
    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);

}}

CS2004 class:

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<Double> ReadNumberFile(String filename)
{
    ArrayList<Double> res = new ArrayList<Double>();
    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);
}}

Once run, the random binary strings work perfectly well, yet the fitness function fails to change from 0. Here is a sample output:

011100
111010
001110
111011
001000
010101
001010
100011
110100
011001

[1.0, 2.0, 3.0, 4.0, 10.0]
Fitness: 0.0

Thank you all so much for your time. Stefanos.

Foi útil?

Solução

scasol appears to be empty when ScalesFitness is called. In the RandomBinaryString method, you never actually construct s, but rather, just print it out. Instead of System.out.print(s+'0') and the other line, you should have s += '0';.

Since this appears to be an exercise, I'll leave the rest to you, but here is a tip for next time: don't have a function do more than it's supposed to (such as printing out its results), otherwise, it might look like the set of functions is actually working, when in reality it isn't.

In this case, it looked like everything was working fine since it appeared like the s.println() function what actually printing out scasol, but in reality, scasol was empty and the RandomBinaryString method was actually doing the printing.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top