从一个类调用静态方法的问题

时间:2016-07-22 21:06:46

标签: java

我有一个名为Operators的类,它包含三个静态方法:crossovermutatebestOffSpring。我在另一个类中调用这些方法,例如:

List<Cell> offSpring = Operators.crossover(parent1, parent2);           
Cell bestOffSpring = Operators.bestOffSpring(offSpring);
Cell mutatedChild = Operators.mutate(bestOffSpring);

我遇到的问题是,当我拨打crossoverbestOffSpring时,他们的结果会正确生成。但是,当我调用mutate方法时,其他两个方法的结果不正确。换句话说,调用crossover方法会影响bestOffSpringmutate的结果。我检查了三种方法的逻辑,但没有发现任何错误。

我的问题是从一个类调用许多静态方法会影响它们的结果吗?

以下是三种方法的代码:

public class Operators {

    public static List<Cell> crossover(Cell parenta_,Cell parentb_)
    {

        BitSet parenta = parenta_.getChrom();
        BitSet parentb = parentb_.getChrom();

        Random rand = new Random();
        int setLength = parenta.length();
        //System.out.println("<"+setLength+">");
        BitSet child1 = new BitSet(setLength);
        BitSet child2 = new BitSet(setLength);

        //One point splicing
        int slicePoint = rand.nextInt(setLength); //rnd num between 0-70
        System.out.print("<"+slicePoint+">");
        BitSet a = (BitSet)parenta.clone();
        a.clear(slicePoint,setLength);
        BitSet b = (BitSet)parenta.clone();
        b.clear(0,slicePoint);
        BitSet c = (BitSet)parentb.clone();
        c.clear(slicePoint,setLength);
        BitSet d = (BitSet)parentb.clone();
        d.clear(0,slicePoint);

        //Combine start of p1 with end of p2
        child1.or(a);
        child1.or(d);
        //Combine start of p2 with end of p1        
        child2.or(c);
        child2.or(b);

        //Return the children
        //BitSet[] offspring = {child1, child2};

        Cell child1_ = new Cell(child1);
        Cell child2_ = new Cell(child2);

        System.out.print("C1 = " + child1_.printBit());
        System.out.print(", C2 = " + child2_.printBit() + " ");

        List<Cell> offSpring = new ArrayList<>();

        offSpring.add(child1_);
        offSpring.add(child2_);

        return offSpring;
    }

    public static Cell mutate(Cell original_){
        BitSet original = original_.getChrom();

        Double mProb = 0.4;
        Random rand = new Random();
        for(int m = 0; m < original.length(); m++)
        {
            //Small possibility a bit copied from parent to child is mutated
            if(rand.nextDouble() <= mProb)
                original.flip(m);
        }
        //Return the (possibly) strategy
        Cell mutated = new Cell(original);
        return mutated;
    }

    public static Cell bestOffSpring(List<Cell> offSpring){
        int offSpringFit1 = offSpring.get(0).getFitness();
        int offSpringFit2 = offSpring.get(1).getFitness();

        if (offSpringFit1 > offSpringFit2)
            return offSpring.get(0);
        else
            return offSpring.get(1);
    }
}

以下是一个例子,调用crossover和bestOffSpring的正确结果是:

OffSpring are 100111 <4> and 111101 <5>, best is 111101
OffSpring are 101010 <3> and 111101 <5>, best is 111101
OffSpring are 101111 <5> and 110101 <4>, best is 101111
OffSpring are 110111 <5> and 110111 <5>, best is 110111
OffSpring are 101101 <4> and 110111 <5>, best is 110111
OffSpring are 101010 <3> and 111010 <4>, best is 111010

当调用mutate方法时,结果为:

OffSpring are 101101 <4> and 100110 <5>, best is 100110
OffSpring are 101010 <3> and 1100 <5>, best is 1100
OffSpring are 100111 <4> and 10101 <5>, best is 10101
OffSpring are 110111 <5> and 111100 <5>, best is 111100
OffSpring are 101100 <5> and 110101 <4>, best is 101100
OffSpring are 11101 <4> and 101010 <3>, best is 11101

两个结果之间的差异在于正确结果中的两个后代具有正确的长度(在每个后代中有多少1个)并且其中最好的是正确选择的。虽然后者没有给出正确的长度然后产生错误的最佳后代。

1 个答案:

答案 0 :(得分:1)

副作用 ...

if(rand.nextDouble() <= mProb)
                original.flip(m);

...

可以假设original_.getChrom()直接返回基础BitSet,因此您最终会翻转bestOffSpring的叮咬,这会在您运行mutate()后影响健身功能得分。
要避免副作用,只需创建原始Bitset的副本

Bitset original = new Bitset(original_.getChrom().size());
original.or(original_.getChrom().size())

检查Defensive programming代码