2016-07-22 24 views
0

我有一個叫做Operators的類,它包含三種靜態方法:crossover,mutate,bestOffSpring。我呼籲在另一類這些方法如:從一個類調用靜態方法的問題

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

,我面對的是,當我剛打電話crossoverbestOffSpring,其結果是否正確產生的問題。但是,當我撥打mutate方法時,其他兩個的結果不正確。換句話說,調用mutate方法會影響crossoverbestOffSpring的結果。我檢查了三種方法的邏輯,並沒有發現任何錯誤。

我的問題是調用一個類的很多靜態方法會影響它們的結果嗎?

這裏是三個方法的代碼:

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

下面是一個例子,調用交叉和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

有很多需要的信息丟失。您需要向我們顯示導致「錯誤」輸出的調用的確切序列,然後非常清楚地解釋輸出應該是什麼以及實際輸出是錯誤的。我們還需要查看「Cell」類的定義。沒有這個,至少沒有人能真正幫助你。 –

+4

如果沒有可變狀態,則方法無法影響彼此的結果。如果沒有MCVE,我們可以用它來重現這一點,但沒人能對此做更多的說明。 –

+1

什麼對我來說是突出的,是你修改成原來的,然後_then_創建副本(而不是其他方式):'original.flip(m);' - >'Cell mutated = new Cell(original) ;'。這意味着原始文件和副本都會發生變化。如果這是有意的,做一個副本是沒有意義的。 –

回答

1

副作用 ...

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

...

人們可以推測original_.getChrom()返回直接底層位集合,所以你最終翻轉的bestOffSpring叮咬這反過來又會影響在運行mutate()後,健身功能得分。
爲了避免副作用只是創建原始比特集

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

的副本檢查Defensive programming標籤

相關問題