Генетический алгоритм: ничего не добавляется? - PullRequest
0 голосов
/ 06 июня 2018

Я создаю игру, которая позволяет двум пользователям соревноваться друг с другом в мини-игре, в которой участвует армия войск (например, солдат, танк, кавалерия), и тот, кто победит, получает возможность оптимизировать свою армию с помощьюгенетический алгоритм.

Максимальное армейское пространство составляет 100 единиц, с солдатом, занимающим 1 единицу, танком (10 единиц) и кавалерией (5 единиц).

У солдата уровень урона 5, у танка - 15, у кавалерии - 10. 10. 1005

Мой генетический алгоритм стремится максимизировать общее значение атаки, покасведение к минимуму пространства в армии.

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 войск.

1 Ответ

0 голосов
/ 06 июня 2018

(int) Math.random () всегда будет возвращать 0. Если вы хотите преобразовать тип, подобный этому, вам нужно заключить скобки в рамки вычисления, исключая только тип-тип

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...