我有一個叫做Operators
的類,它包含三種靜態方法:crossover
,mutate
,bestOffSpring
。我呼籲在另一類這些方法如:從一個類調用靜態方法的問題
List<Cell> offSpring = Operators.crossover(parent1, parent2);
Cell bestOffSpring = Operators.bestOffSpring(offSpring);
Cell mutatedChild = Operators.mutate(bestOffSpring);
,我面對的是,當我剛打電話crossover
和bestOffSpring
,其結果是否正確產生的問題。但是,當我撥打mutate
方法時,其他兩個的結果不正確。換句話說,調用mutate
方法會影響crossover
和bestOffSpring
的結果。我檢查了三種方法的邏輯,並沒有發現任何錯誤。
我的問題是調用一個類的很多靜態方法會影響它們的結果嗎?
這裏是三個方法的代碼:
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),並且正確選擇其中最好的。而後者並沒有給出正確的長度,然後產生錯誤的最好的後代。
有很多需要的信息丟失。您需要向我們顯示導致「錯誤」輸出的調用的確切序列,然後非常清楚地解釋輸出應該是什麼以及實際輸出是錯誤的。我們還需要查看「Cell」類的定義。沒有這個,至少沒有人能真正幫助你。 –
如果沒有可變狀態,則方法無法影響彼此的結果。如果沒有MCVE,我們可以用它來重現這一點,但沒人能對此做更多的說明。 –
什麼對我來說是突出的,是你修改成原來的,然後_then_創建副本(而不是其他方式):'original.flip(m);' - >'Cell mutated = new Cell(original) ;'。這意味着原始文件和副本都會發生變化。如果這是有意的,做一個副本是沒有意義的。 –