0

So I've been tasked to work on an algorithm based on Random Mutation Hill Climbing. I have a method RMHC that takes in an ArrayList of weights and two ints, one for number of weights and another for iterations. My instructions tell me to create an initial solution, copy it and then apply a mutation method SmallChange() to the initial solution. I was also instructed on how to copy the solution with the GetSol() method in my ScalesSolution class. The mutation takes in a binary String value (i.e 11101) and changes a random substring in the binary to either 0 or 1 so I may be met with an output such as 10101 if the 2nd substring is mutated.

My issue is that when I make the SmallChange() to my solution, it makes the change to the original solution also.

I've already tried adding a copy constructor as what was suggested in another question I'd found, but it did not work.

Main Method

public class Worksheet9 {
public static void main(String[] args) {

    ArrayList<Double> myArray = new ArrayList<Double>();

    myArray.add(1.0);
    myArray.add(2.0);
    myArray.add(3.0);
    myArray.add(4.0);
    myArray.add(10.0);

    RMHC(myArray, 5, 2);
}

RMHC Method

public static ScalesSolution RMHC(ArrayList<Double> weights,int n,int iter)
{

    ScalesSolution oldsol = new ScalesSolution(n);
    ScalesSolution newsol = new ScalesSolution(oldsol.GetSol());
    //Attempting Copy Constructor
    ScalesSolution newsol = new ScalesSolution(oldsol);



    double origfitness = oldsol.ScalesFitness(weights);
    System.out.println("Original Fitness: " + origfitness);
    double origfitness1 = newsol.ScalesFitness(weights);
    System.out.println("Cloned Original Fitness: " + origfitness1);
    newsol.SmallChange();
    double origfitness2 = newsol.ScalesFitness(weights);
    System.out.println("Changed Fitness: " + origfitness2);
    double origfitness3 = oldsol.ScalesFitness(weights);
    System.out.println("Cloned Original Fitness: " + origfitness3);

    return(oldsol);
}



}

ScalesSolution Class

import java.util.ArrayList;
import java.util.Random;

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(ScalesSolution another) {
    this.scasol = another.scasol; // you can access  
  }




public void SmallChange() {

    int n = scasol.length();
    String s = scasol;



    Random rand = new Random();
    int p = (rand.nextInt(n));

    String x;
    x = scasol.substring(0, p);
    if (scasol.charAt(p) == '0') {
        x += '1';
    } else {
        x += '0';
    }
    x += scasol.substring(p + 1, n);
    scasol = x;

}





public String GetSol()
{
    return(scasol);
}


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){
            s += '0';
        } else if (x == 1) {
            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
public static double ScalesFitness(ArrayList<Double> weights)
{
    if (scasol.length() > weights.size()) return(-1);
    double lhs = 0.0,rhs = 0.0;
    int n = scasol.length();

    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();
}
}

When I call the RMHC function in the main method, I get an output like this:

Original Fitness: 16.0

Cloned Original Fitness: 16.0

Changed Fitness: 14.0

Cloned Original Fitness: 14.0

The 2nd Cloned Original Fitness should also be value 16.0 in this example. Once I figure out this initial issue, I will implement the code into a for loop to include the iterations. Thanks.

4
  • 1
    Where is your copy constructor code attempt? I don't see code like that posted within your question. What specific problems were you having with this copy constructor attempt? Commented Aug 6, 2019 at 15:49
  • 1
    Also, why is the scasol variable static? Commented Aug 6, 2019 at 15:50
  • You should follow the Java Naming Conventions: method names are written in camelCase. Commented Aug 6, 2019 at 15:52
  • Yes I think it's the static variable scasol messing you up. There's only one in your program so you "can't" make a copy of it. Commented Aug 6, 2019 at 15:52

1 Answer 1

1

Assuming this is where you try to copy your data:

ScalesSolution oldsol = new ScalesSolution(n);
ScalesSolution newsol = new ScalesSolution(oldsol.GetSol());

This doesn't work because the variable is static:

public class ScalesSolution
{
   private static String scasol;
   //...

   public String GetSol()
   {
      return(scasol);
   }

Since all you do is assign the value to the static string scasol, no actual change or copy is made.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.