遗传算法:什么都没有添加?

Genetic algorithm: nothing getting added?

我正在创建一个游戏,允许两个用户在涉及军队(例如士兵、坦克、骑兵)的迷你游戏中相互竞争,获胜者将获得优化其军队的选项用遗传算法。

最大军队space是100个单位,士兵占1个单位,坦克(10个单位),骑兵(5个单位)。

士兵的伤害率为5,坦克的伤害率为15,骑兵的伤害率为10。

我的遗传算法寻求最大化总攻击值,同时最小化军队内的 space。

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,因此没有部队或任何攻击力。

Generation 1: Best army has a size of 0 and attack power of 0
Best army has a total of 0 soldiers and attack value of 0
There are 0 troops contained in the army.

(int) Math.random() 总是 return 0。 如果你想像这样转换类型,你需要在计算周围加上括号,只排除类型转换