Java:在列表

时间:2018-05-08 13:09:13

标签: java

我目前正在开发一个AI,它将为列表中的每个人做出决策。但是在迭代这个列表时,我得到了ConcurrentModificationException。我验证了我的removeDeads函数是否会导致这样的事情,但是因为它不在循环内部,所以它不应该。这是错误堆栈:

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:945)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
    at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:939)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:893)
    at IA.RLAI.play(RLAI.java:48)
    at Game.Game.play(Game.java:61)
    at Main.start(Main.java:136)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
    ... 1 more
Exception running application Main

问题是它永远不会在同一时刻发生。我可以迭代3个人以及15个人。

这是我的代码:

    public void play(Population population, Game game) throws Exception {
        //looking if some individuals died from the other player
        ArrayList<Individual> deads = new ArrayList<>();
        for(Individual i: population.getIndividuals()){
            if(i.getCurrentHP()==0){
                deads.add(i);
            }
        }
        population.getIndividuals().removeAll(deads);
        for (Individual dead: deads) {
            learn(dead);
        }

    //Normal individuals
    for (Individual me: population.getIndividuals()) {
        int size = Math.max(0, me.getMemory().size()-1);

        if(me.getMemory().isEmpty()){
            System.out.println(me.getMemory().toString());
        }else {
            System.out.println(me.getMemory().get(size).toString());
        }

        double[] inputs = new double[153];
        int i = 0;

        double[] toInsert = getAllyMap(me);
        System.arraycopy(toInsert, 0, inputs, i, 49);
        i+=49;

        toInsert = getEnemyMap(me, game);
        System.arraycopy(toInsert, 0, inputs, i, 49);
        i+=49;

        toInsert = getFoodMap(me);
        System.arraycopy(toInsert, 0, inputs, i, 49);
        i+=49;

        inputs[i++] = me.getPosition().getX()-population.getFoodBase().getX(); //Relative position to foodBase X
        inputs[i++] = me.getPosition().getY()-population.getFoodBase().getY(); //Relative position to foodBase Y
        inputs[i++] = me.getCurrentHP();
        inputs[i++] = me.getCurrentFoodLvl();
        inputs[i++] = me.getCurrentFoodStock();
        inputs[i++] = population.getMapping().getCase(population.getFoodBase()).getFoodQuantity();

        double[] outputs = network.forward(inputs);
        //calculus of the probability of the outputs
        double sumExp = 0;
        for(int j = 0; j<outputs.length; j++){
            sumExp += Math.exp(outputs[j]);
        }
        double[] proba = new double[outputs.length];
        for (int j = 0; j<outputs.length; j++){
            proba[j] = Math.exp(outputs[j])/sumExp;
        }
        //determination of the chosen output
        double[] probCuml = new double[outputs.length+1];
        probCuml[0] = 0;
        for (int j = 0; j < outputs.length; j++){
            probCuml[j+1] = probCuml[j]+proba[j];
        }
        double rand = Math.random();
        int choice = 1;
        for(int j = 1; j<probCuml.length; j++){
            if(rand < probCuml[j]){
                choice = j-1;
                break;
            }
        }
        //Action
        switch(choice){
            case 0:
                me.move(Actions.MoveUp);
                break;
            case 1:
                me.move(Actions.MoveDown);
                break;
            case 2:
                me.move(Actions.MoveRight);
                break;
            case 3:
                me.move(Actions.MoveLeft);
                break;
            case 4:
                Population toAttack = game.getOtherPopulation(population);
                me.attack(toAttack);
                break;
            case 5:
                me.collect();
                break;
            case 6:
                me.store();
                break;
            case 7:
                me.eat();
                break;
            case 8:
                me.copulate();
                break;
            default :
                throw new Exception("Out of Possible Choice");
        }
        me.regen();
        if(me.getCurrentHP()<=0){me.addMemory(Reinforcement.Die);}
        learn(me);
    }
    //looking for individuals that die of hunger but as they already learned, 

    no need to do it again
    population.areDead();
    System.out.println(" ");
}

这是我的areDead功能:

public ArrayList<Individual> areDead(){
        ArrayList<Individual> areDead = new ArrayList<>();
        for (Individual individual: individuals) {
            if(individual.getCurrentHP()<=0){
                areDead.add(individual);
            }
        }
        individuals.removeAll(areDead);
        return areDead;
    }

问题是我不知道这个异常来自哪里。它说它来自个人的循环,但没有任何东西可以修改其中的列表。

0 个答案:

没有答案