私は今までに何が問題なのかを本当に知る必要がありますが、私は問題を抱えています。私の問題はJavaArraylistにあります。クラスメソッド(kgeneticsクラスのaddStartingPop)を使用してオブジェクトを配列リストに追加しようとしています。このメソッドはmainで呼び出され、arrayListであるkgeneticsのクラスメンバーを更新する必要があります。mainでaddStartPop()を呼び出した後、直後にmainで新しい母集団を出力しようとします。ただし、気付いた場合、Item配列は私が期待する方法ではありません。問題:問題は、値が配列リストに追加されることですが、私が望むように値が完全に変更されていないようです。
ここに、プログラムの実行からの出力があります。
これは、addStartPop()が呼び出された後にArraylistに含まれるべきものです。
配列リストに追加される前に、各ナップザックを印刷します(knapsackSamples)
Item: (1.0, 2.0, false)
Item: (1.0, 2.0, false)
Item: (4.0, 6.0, true)
Item: (3.0, 2.0, false)
Item: (1.0, 2.0, true)
Item: (8.0, 10.0, false)
Item: (1.0, 2.0, true)
Item: (5.0, 1.0, true)
Item: (7.0, 8.0, true)
Item: (6.0, 9.0, false)
Score: 37.0
Item: (1.0, 2.0, false)
Item: (1.0, 2.0, false)
Item: (4.0, 6.0, false)
Item: (3.0, 2.0, false)
Item: (1.0, 2.0, false)
Item: (8.0, 10.0, false)
Item: (1.0, 2.0, true)
Item: (5.0, 1.0, true)
Item: (7.0, 8.0, true)
Item: (6.0, 9.0, false)
Score: 24.0
これは、mainメソッドでサンプルを印刷するときに印刷されるものです。スコア(アイテムを構成する2つの数値から計算)は正しいですが、配列は最後に追加された配列です)
Item 0
Item: (1.0, 2.0, false)
Item: (1.0, 2.0, false)
Item: (4.0, 6.0, false)
Item: (3.0, 2.0, false)
Item: (1.0, 2.0, false)
Item: (8.0, 10.0, false)
Item: (1.0, 2.0, true)
Item: (5.0, 1.0, true)
Item: (7.0, 8.0, true)
Item: (6.0, 9.0, false)
Score: 37.0
Item 1
Item: (1.0, 2.0, false)
Item: (1.0, 2.0, false)
Item: (4.0, 6.0, false)
Item: (3.0, 2.0, false)
Item: (1.0, 2.0, false)
Item: (8.0, 10.0, false)
Item: (1.0, 2.0, true)
Item: (5.0, 1.0, true)
Item: (7.0, 8.0, true)
Item: (6.0, 9.0, false)
Score: 24.0
よくわかりませんが、Javaが暗黙的に参照を使用する方法に問題がある可能性があると思います。誰かが私を助けることができますか?
これが私のコードで、何が悪いのかを概説します。
mainメソッドでは、開始母集団が作成された後、ランダムに作成されたサンプルを使用して新しい母集団を出力しますが、ksim.printPopulation()が出力するものは正しくありません。問題は、コードの2番目のブロックで新しいサンプルを作成して保存する方法にあるはずです。
package gaknapsack2;
import java.util.List;
import java.util.ArrayList;
public class GAknapsackmain {
public static void main(String[] args) {
float knapsackCapacity = 18.5f;
int startPop = 2;
int populationLimit = 1000;
List<Knapsack> listholder = new ArrayList<Knapsack>(populationLimit);
Item[] items = new Item[10];
items[0] = new Item(1.0f,2.0f,false);
items[1] = new Item(1.0f,2.0f,false);
items[2] = new Item(4.0f,6.0f,false);
items[3] = new Item(3.0f,2.0f,false);
items[4] = new Item(1.0f,2.0f,false);
items[5] = new Item(8.0f,10.0f,false);
items[6] = new Item(1.0f,2.0f,false);
items[7] = new Item(5.0f,1.0f,false);
items[8] = new Item(7.0f,8.0f,false);
items[9] = new Item(6.0f,9.0f,false);
Knapsack itemKnapsack = new Knapsack(items.length,knapsackCapacity,items,0);
kgenetics ksim = new kgenetics(populationLimit,itemKnapsack,knapsackCapacity,startPop);
ksim.addStartingPop();
//ksim.setPopulation(listholder);
ksim.printPopulation();
}
}
package gaknapsack2;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
public class kgenetics {
private int maxPopulation;
private int startingPopulationSize;
//private Knapsack[] knapsackSamples;
private List<Knapsack> knapsackSamples = new ArrayList<Knapsack>(100);
//the knapsack to base all other knapsacks from
private Knapsack baseKnapsack;
private float knapsackCapacity;
public kgenetics(int mP,Knapsack ks, float capacity, int startPop){
this.maxPopulation = mP;
this.baseKnapsack = ks;
this.knapsackCapacity = capacity;
this.startingPopulationSize = startPop;
}
public float calculateScore(Knapsack k){
float weightTotal = 0.0f;
float valueTotal = 0.0f;
float totalScore = 0.0f;
for(int i = 0; i < k.getNumberOfItems();i++){
if(k.getItemAtIndex(i).isPresent() == true){
weightTotal += k.getItemAtIndex(i).getWeight();
valueTotal += k.getItemAtIndex(i).getValue();
}
}
//if oversize, take items out of knapsack until it is legal weight
if(weightTotal > this.knapsackCapacity){
int i = 0;
while(weightTotal > this.knapsackCapacity){
if(k.getItemAtIndex(i).isPresent() == true){
weightTotal -= k.getItemAtIndex(i).getWeight();
valueTotal -= k.getItemAtIndex(i).getValue();
k.getItemAtIndex(i).setPresent(false);
}
i++;
}
}
totalScore = weightTotal + valueTotal;
return totalScore;
}
public void printPopulation(){
for(int i = 0; i < this.knapsackSamples.size(); i++){
System.out.println("Item " + i);
this.knapsackSamples.get(i).printKnapsack();
System.out.println();
}
}
public void setPopulation(List<Knapsack> r){
this.knapsackSamples = r;
}
public void makeRandomSample(Knapsack k){
for(int i = 0; i < k.getNumberOfItems(); i++){
Random rand = new Random();
float x = rand.nextFloat();
if(x > 0.5){
k.getItemAtIndex(i).setPresent(true);
}
}
}
public void addNew(Knapsack k){
this.knapsackSamples.add(k);
}
public void addStartingPop(){
//Knapsack newKnapsack = new Knapsack(this.baseKnapsack.getNumberOfItems(),this.baseKnapsack.getCapacity(),this.baseKnapsack.getItemsArray(),this.baseKnapsack.getScore());
Knapsack newKnapsack;
for(int i = 0; i < this.startingPopulationSize;i++){
newKnapsack = new Knapsack(this.baseKnapsack.getNumberOfItems(),this.baseKnapsack.getCapacity(),this.baseKnapsack.getItemsArray(),this.baseKnapsack.getScore());
//might be a trouble area if pass by reference or value
//might have to test
newKnapsack.setRandomKnapsackItems(newKnapsack);
//this.makeRandomSample(newKnapsack);
float score = calculateScore(newKnapsack);
newKnapsack.setScore(score);
newKnapsack.setItems(newKnapsack.getItemsArray());
newKnapsack.printKnapsack();
this.knapsackSamples.add(newKnapsack);
}
//return newKnapsack;
}
//create a crossover between knapsacks thus creating a new possible solution
//add the probability for a mutation to occur during cross over
public Knapsack crossOver(Knapsack p1, Knapsack p2){
System.out.print("performing crossover\n");
p1.printKnapsack();
Random r = new Random();
Knapsack newKnapsack = new Knapsack(p1.getNumberOfItems(),p1.getCapacity(),p1.getItemsArray(),p1.getScore());
//Knapsack newKnapsack = new Knapsack();
//newKnapsack = p1;
//newKnapsack.printKnapsack();
//no bigger crossover than half of the number of items in knapsack
int rangeCrossover = r.nextInt(this.baseKnapsack.getNumberOfItems()/2);
int positionStart = r.nextInt(this.baseKnapsack.getNumberOfItems());
int positionEnd = (positionStart + rangeCrossover);
System.out.println("Crossover - posStart: "+ positionStart + " posEnd: " + positionEnd);
for(int i = 0; i < this.baseKnapsack.getNumberOfItems();i++){
if(i >= positionStart && i <= positionEnd){
newKnapsack.setItemAtIndex(i, p2.getItemAtIndex(i).isPresent());
}
}
System.out.print("finished crossover\n");
newKnapsack.printKnapsack();
return newKnapsack;
}
//create the reproduction function that performs the crossover on all knapsacks
public void reproduction(){
for(int i = 0; i < this.knapsackSamples.size();i+=2){
if(this.knapsackSamples.get(i + 1) != null){
Knapsack child = new Knapsack();
//Knapsack child = new Knapsack(p1.getNumberOfItems(),p1.getCapacity(),p1.getItemsArray(),p1.getScore());
//child.copyKnapsack(this.knapsackSamples.get(i));
//child.printKnapsack();
child = this.crossOver(this.knapsackSamples.get(i),this.knapsackSamples.get(i + 1));
child.setScore(this.calculateScore(child));
System.out.println("new child");
//child.printKnapsack();
Knapsack addthis = new Knapsack(child.getNumberOfItems(),child.getCapacity(),child.getItemsArray(),child.getScore());
//addthis.printKnapsack();
this.knapsackSamples.add(addthis);
}
}
}
}
要求されたKnapsackオブジェクト:
package gaknapsack2;
import java.util.Random;
public class Knapsack{
private int totalNumberOfItems;
private float knapSackCapacity;
private Item[] knapsackItems;
private float knapsackScore;
private float weight;
private float value;
public Knapsack(int totalNumOfItems, float cap, Item[] items, float s){
this.totalNumberOfItems = totalNumOfItems;
this.knapSackCapacity = cap;
this.knapsackItems = items;
this.knapsackScore = s;
}
public Knapsack(){
this.totalNumberOfItems = 0;
this.knapSackCapacity = 0;
this.knapsackItems = null;
this.knapsackScore = 0;
}
//randomly select items from the baseknapsack that was instaniated and
//set Items in it to have itemPresent = true
public void setRandomKnapsackItems(Knapsack k){
for(int i = 0; i < this.totalNumberOfItems; i++){
Random rand = new Random();
float x = rand.nextFloat();
if(x > 0.5){
k.knapsackItems[i].setPresent(true);
}
}
}
public void setItemAtIndex(int i, boolean b){
this.knapsackItems[i].setPresent(b);
}
public void setItems(Item[] i){
this.knapsackItems = i;
}
public Item getItemAtIndex(int i){
return this.knapsackItems[i];
}
public int getNumberOfItems(){
return this.totalNumberOfItems;
}
public float getCapacity(){
return this.knapSackCapacity;
}
public Item[] getItemsArray(){
Item[] copy = this.knapsackItems;
return copy;
}
public float getScore(){
return this.knapsackScore;
}
public void setScore(float f){
this.knapsackScore = f;
}
public Knapsack copyKnapsack(Knapsack k){
Knapsack kNew = new Knapsack();
kNew.totalNumberOfItems = k.totalNumberOfItems;
kNew.knapSackCapacity = k.knapSackCapacity;
for(int i = 0; i < k.totalNumberOfItems;i++){
kNew.knapsackItems[i] = k.knapsackItems[i].returnCopyOfItem();
}
kNew.knapsackScore = k.knapsackScore;
kNew.printKnapsack();
return kNew;
}
public void printKnapsack(){
for(int i = 0; i < this.totalNumberOfItems;i++){
this.knapsackItems[i].printItem();
}
System.out.println("Score: " + this.knapsackScore);
}
}
mainメソッドのコードに従う場合。ksimがメンバーとして持っている配列リストに呼び出されたwhereksim(ナップザックオブジェクトの追加を担当)が表示されます。これは、関数addStartPop()のarraylistに追加されたランダムなナップザックを保持する必要がありますが、この後の母集団をmainで出力すると、値が間違っています
私はしばらくの間これを理解しようとしてきました。助けてください。必要に応じて、さらにコードを追加できます。ありがとう