我现在应该知道问题是什么,但我遇到了麻烦。我的问题在于Java Arraylist。我试图通过类方法(kgenetics类中的addStartingPop)将对象添加到arraylist。这个方法在main中被调用,它应该更新kgenetics的类成员,这是一个arrayList。在main中调用addStartPop()之后,我尝试在main之后打印出新的填充。但是,如果您注意到,Item数组不是我期望的那样。问题:问题是这些值确实被添加到数组列表中,但似乎它们并没有完全修改我想要它们。
这是运行程序的输出:
在调用addStartPop()
之后,这应该是Arraylist中的内容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隐式使用引用的问题。任何人都可以帮助我吗?
这是我的代码,我将概述错误:
在main方法中,在创建开始填充之后,我打印出应该是随机创建的样本的新种群,但是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);
}
}
}
}
请求的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(负责添加背包对象)的地方,ksim作为成员的arraylist。这应该保留添加到函数addStartPop()中的arraylist的随机背包但是当我在main中打印人口后,值是错误的
我一直试图解决这个问题。请帮忙,如果需要,我可以提供更多代码。感谢
答案 0 :(得分:1)
似乎kgen保留了一个背包(baseKnapsack)的副本,然后你到处都使用这个背包的阵列。如果您将baseKnapsack中的列表传递给您创建的每个新Knapsack项目,它们都将使用相同的列表。而不是
newKnapsack = new Knapsack(this.baseKnapsack.getNumberOfItems(),this.baseKnapsack.getCapacity(),**this.baseKnapsack.getItemsArray()**,this.baseKnapsack.getScore());
尝试这样的事情:
newKnapsack = new Knapsack(this.baseKnapsack.getNumberOfItems(),this.baseKnapsack.getCapacity(),**new Item[baseKnapsack.totalNunberOfItems]**,this.baseKnapsack.getScore());