我现在应该真的知道问题出在哪里,但我遇到了麻烦。我的问题是Java Arraylist。我正在尝试通过类方法(kgenetics 类中的 addStartingPop)将对象添加到数组列表中。这个方法在 main 中被调用,它应该更新 kgenetics 的类成员,它是一个 arrayList。在 main 中调用 addStartPop() 后,我尝试在 main 中打印出新的人口。但是,如果您注意到,Item 数组并不是我期望的那样。问题:问题是这些值确实被添加到了数组列表中,但似乎它们并没有完全修改我想要的样子。
这是运行程序的输出:
这是调用 addStartPop() 之后 Arraylist 中应该包含的内容
我在将每个背包添加到 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 方法中打印样本时,这就是打印出来的。分数(根据构成项目的两个数字计算)是正确的,但数组是最后添加的数组)
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 如何隐式使用引用的问题。谁能帮我吗?
这是我的代码,我将概述问题所在:
在主要方法中,在创建开始人口后,我用随机创建的样本打印出新人口应该是什么,但 ksim.printPopulation() 打印出的内容不正确。问题一定是如何在第二个代码块中创建和保存新样本。
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);
}
}
}
}
根据要求的背包对象:
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 方法中的代码。您会看到一个名为 where ksim(负责添加背包对象)到 ksim 作为成员的数组列表。这应该保留在函数 addStartPop() 中添加到数组列表中的随机背包但是当我在 main 中打印此之后的人口时,值是错误的
我一直试图弄清楚这一点。请帮助,如果需要,我可以提供更多代码。谢谢