首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Flappy Bird遗传算法种群的改进

Flappy Bird遗传算法种群的改进
EN

Stack Overflow用户
提问于 2018-02-04 21:23:44
回答 1查看 226关注 0票数 1

我正在尝试创建一种遗传算法,它可以学习玩飞鸟。我让游戏正常运行,这是我的Bird类:

代码语言:javascript
复制
public class Bird extends Player {

public NNetwork network;

public Bird(float x, float y, float velX, float velY, float width, float height) {
    super(x, y, velX, velY, width, height);
    NTopology topo = new NTopology(3,5,1);
    network = new NNetwork(topo, 0.1f, 0.1f, true);
}

public void reset() {
    setAlive(true);
    setX(0f);
    setY(1000f);
    setVelY(0f);
}

/**
 * Feeds the parameters into the neural net
 * @param dyTop height difference to the top edge
 * @param dyBot height difference to the bottom edge
 * @param dx distance to the obstacles
 * @return true if the bird thinks it would be good to jump
 */
public void jump(float dyTop, float dyBot,float dx) {
    network.feed(dyTop, dyBot, dx);
    if(network.getOutputs()[0]>0f) super.flap();
}

public void update(float dyTop, float dyBot, float dx) {
    super.update();
    jump(dyTop, dyBot, dx);
}

public Bird mutate() {
    Bird ret = this;
    ret.network.mutate();
    ret.setAlive(true);
    ret.setScore(0f);
    ret.setX(0);
    ret.setY(1000);
    return ret;
}

}

这些是种群变异函数

代码语言:javascript
复制
public ArrayList<Bird> sortBirds(ArrayList<Bird> birds) {
    ArrayList<Bird> ret = birds;
    Collections.sort(ret, new Comparator<Bird>() {
        @Override
        public int compare(Bird bird, Bird t1) {
            return bird.getScore() < t1.getScore() ? 1 : -1;
        }
    });
    lastBestScore = ret.get(0).getScore();
    return ret;
}


public ArrayList<Bird> repopulate(ArrayList<Bird> birds) {
    birds = sortBirds(birds);
    Bird bestBird = this.birds.get(0);
    Bird[] retA = new Bird[birds.size()];
    birds.toArray(retA);
    retA[0] = bestBird;
    for(int i = 0; i < 3; i++) {   //replace the 3 worst birds with mutations of the best one (there are always at least 5 birds)
        retA[retA.length-1-i] = bestBird.mutate();
    }
    ArrayList<Bird> ret = new ArrayList<>(Arrays.asList(retA));
    for(Bird b : ret) {b.reset();}
    generation++;
    return ret;
}

Bird.reset()函数只是复活了这只鸟,并将它设置回起点。当每只鸟都死了时,就会调用repopulate()。从理论上讲,随着时间的推移,这些函数应该会改善我的种群数量,但当一只鸟比其他鸟更好时,下一代又会变差。

是我误解了遗传算法的工作原理,还是代码中有bug?(如果您需要更多代码,我可以将其发布)

EN

回答 1

Stack Overflow用户

发布于 2018-02-09 17:36:36

首先,你的代码中没有交叉,这是非常糟糕的。它通常会提供更好的结果。

其次,你是否只保留了最好的基因组和它的3个突变,而其余的种群只是从头开始再生?-这不会很好地工作,因为你需要更多的多样性。

如果你想单独使用突变,我建议将最好的一半克隆到新一代,而另一半-最好的一半的突变。但我敢肯定,在这种情况下,你也会陷入局部最大值,但这将比你所做的要好得多。

从我使用Flappy Bird的经验来看,最好从常量列开始,因为它对鸟来说更容易学习,对你来说也更容易调试。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48608511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档