我正在创建一个游戏,允许两个用户在涉及部队军队的迷你游戏中相互竞争(例如;士兵、坦克、骑兵(,无论谁获胜,都可以选择使用遗传算法优化他们的军队。
军队的最大空间为100个单位,士兵占1个单位,坦克(10个单位(和骑兵(5个单位(。
士兵的伤害率为5,坦克的伤害率为15,骑兵的伤害率为10。
我的遗传算法旨在最大化总攻击值,同时最小化军队空间。
public static Army processArmy(Army reference) {
ArrayList<Army> armyPopulation = new ArrayList<Army>(); // creates population of Armies based on original reference.
for (int i=0; i<100; i++) {
Army copy = new Army(reference.getCountry(), 0); // creates a bunch of Armies, copying the original.
for (int j=0; j<reference.size(); j++) {
copy.addTroop(reference.getTroop(j));
//System.out.println(copy.size());
}
Army generated = new Army(reference.getCountry(), 0); // new Knapsack that will be apart of the population.
boolean canRun = true;
while (canRun && (reference.size() <= 100)) {
int randomNum = (int)(Math.random() * (((copy.size()-1) + 1)));
if ((generated.size() + copy.getTroop(randomNum).getWeight()) < reference.getMaxSize() && (copy.getTroop(randomNum) != null)) {
generated.addTroop(copy.getTroop(randomNum));
System.out.println(generated.size());
copy.removeTroop(randomNum);
} else {
canRun = false;
}
}
armyPopulation.add(generated);
}
int indexOfBest = 0;
int valueOfBest = 0;
for(int k=0; k<armyPopulation.size(); k++) {
if (armyPopulation.get(k).getTotalAttack() > valueOfBest){
indexOfBest = k;
}
}
Army bestArmy = armyPopulation.get(indexOfBest);
System.out.println("Generation 1: Best army has a size of " + bestArmy.size() + " and attack power of " + bestArmy.getTotalAttack());
// Mutation portion of code
boolean hasNotChanged = true; // has not changed in 100 generations
int generationsUnchanged = 0; // counts how many times the previous Army is equal to the newest Army/generated Army
int stopIt = 0;
while (hasNotChanged && (generationsUnchanged < 100)) {
for (int m=0; m<100; m++) {
Army copy = new Army(reference.getCountry(), 0); // copy will be an exact copy of reference, which means copy will inititally have all the items in it. It will
// be used as a list for the algorithm to pick which item should go into the newly generated Army.
// Copy is used, unlike reference, because we do not want to delete the items within the reference Army for future generations.
for (int j=0; j<reference.size(); j++) {
copy.addTroop(reference.getTroop(j));
}
Army copyBest = new Army(copy.getCountry(), 0); // bestArmy's items are copied into the copyBest Army.
for (int p=0; p<bestArmy.size(); p++) {
copyBest.addTroop(bestArmy.getTroop(p));
}
Army generated = new Army(reference.getCountry(), 0); // will create a Army to be put into the ArmyPopulation ArrayList
boolean canRun = true; // boolean condition on if while() loop should run; blanket caution boolean
// while loop will handle the creation of the new generated Army, which will be added into the ArmyPopulation ArrayList
while (canRun && (generated.size() <= reference.getMaxSize())) {
int randomNum = (int)(Math.random() * (((copy.size()-1) + 1))); // picks a number that is [0, copy.size())
int randomNumBest = (int)(Math.random() * (((copyBest.size()-1) + 1)));
if (((randomNum < copy.size()) && (randomNumBest < copyBest.size())) && ((generated.size() + copy.getTroop(randomNum).getWeight()) < reference.getMaxSize()) && ((generated.size() + copyBest.getTroop(randomNumBest).getWeight()) < reference.getMaxSize())){
int randomTwoThirds = (int)(Math.random() * 3); // will generate a number betwen [0, 3]
if (randomTwoThirds >= 2) { // for every random number above >=2, it will be added into the Army; this is used to mutate and randomize the Armys
generated.addTroop(copy.getTroop(randomNum));
copy.removeTroop(randomNum); // this removes the same item from the Army copy to prevent duplicates
} else {
generated.addTroop(copyBest.getTroop(randomNumBest)); // for every number < 2, it will just add the copyBest item that is referenced through copyBest[randomNum]
copyBest.removeTroop(randomNumBest); // this removes the same item from the Army copyBest to prevent duplicates
}
} else {
canRun = false;
}
}
armyPopulation.add(generated);
}
indexOfBest = 0; // stores index of best/most fittest Army
valueOfBest = 0; // stores value of best/most fittest Army
for(int k=0; k<armyPopulation.size(); k++) {
if (armyPopulation.get(k).getTotalAttack() > valueOfBest){ // if the newest Army is more fit than the current-pointed "most fit" Army, change it to the new one
indexOfBest = k;
}
}
if (bestArmy.getTotalAttack() == armyPopulation.get(indexOfBest).getTotalAttack()) { // if the best stored Army has the same value as the most newly "fittest" Army
generationsUnchanged++; // in the nth generation, then generations unchanged + 1.
stopIt++;
} else if (bestArmy.getTotalAttack() < armyPopulation.get(indexOfBest).getTotalAttack()) {
bestArmy = armyPopulation.get(indexOfBest); // if the newest "fittest" Army from newest population has a greater value, point it as most fit.
}
if(generationsUnchanged == 100){
hasNotChanged = false;
}
System.out.println("Best army has a total of " + bestArmy.size() + " soldiers and attack value of " + bestArmy.getTotalAttack());
if (bestArmy.size() == 1) { // just for aesthetic/correct grammar
System.out.println("There is " + bestArmy.size() + " troop contained in the army.");
} else {
System.out.println("There are " + bestArmy.size() + " troops contained in the army.");
}
}
return bestArmy;
}
标有的陆军参考是获胜者的军队。但是,我确信军队已经满员,因为在游戏之前,您必须至少有 100 名士兵才能开始比赛。
返回的错误是军队的规模为 0,因此没有部队或任何攻击力。
第 1 代:最佳军队规模为 0,攻击力为 0最佳军队共有 0 名士兵,攻击值为 0 军队中包含 0
名部队。
(int( Math.random(( 将始终返回 0。 如果要像这样转换类型,则需要在计算周围加上括号,仅排除类型转换