1

AI において、ゲノムをシミュレーションに実装する方法の単純な、および/または非常に視覚的な例はありますか?

基本的に、私は簡単なウォークスルー(チュートリアルではなく、要約的な性質のもの)を求めています。これは、合計で「個体」の特性を変更するゲノムを実装する方法を詳しく説明しています。

これらの遺伝子は次のようなものではありません。

  • 質量
  • 長さ、
  • 等..

しかし、むしろそれらは、シミュレーションの住民の実際の特性からゲノムを抽象化して、上記のものを定義するものであるべきです.

私は自分が何を望んでいるのかを十分に明確にしていますか?

とにかく、あなたが試した方法がより良く、これらの性的な水泳選手のような形で進化を実装する方法があれば、ぜひ投稿してください! 楽しいインスピレーションがあればあるほど良いです:)

4

1 に答える 1

3

「個人」を自分で実装している場合、任意のオブジェクトがゲノムとして機能できます。

特徴

これをさらに単純化する 1 つの方法は、特性を列挙型に変換することです。このようにして、親の遺伝子から特性を選択することで親の遺伝子を簡単に組み換えたり、特性の列挙値の 1 つをランダムに選択して遺伝子を突然変異させたりすることができます。

これが機能するようになると、値の範囲をより細かく調整できますが、列挙型を使用すると、最初は物事を明確に保つことができます。

フィットネス

次に、これらの特性に意味を与えるには、パフォーマンスを表すフィットネス関数が必要です。特性間の関係はあなた次第なので、意味のある方法で説明できます。これは、2 つのゲノムを比較するための一貫した方法を提供するだけです。

シミュレーション

次に、シミュレーションを実行するには、いくつかの親から始めて、互いに完成させるためにたくさんの子を生成します。これはもちろん自動化できますが、わかりやすくするためにここに明示的な例を示します。

Java の例

import java.util.PriorityQueue;

class Genome implements Comparable<Genome> {

    public enum Mass {
        LIGHT(1),
        AVERAGE(2),
        HEAVY(3);

        final Integer value;
        Mass(Integer value) {
            this.value = value;
        }
    }

    public enum Strength {
        WEAK(1),
        AVERAGE(2),
        STRONG(3);

        final Integer value;
        Strength(Integer value) {
            this.value = value;
        }

    }

    public enum Length {
        SHORT(1),
        AVERAGE(2),
        LONG(3);

        final Integer value;
        Length(Integer value) {
            this.value = value;
        }
    }

    private final Mass mass;
    private final Strength strength;
    private final Length length;

    public Genome(Mass mass, Strength strength, Length length) {

            this.mass = mass;
            this.strength = strength;
            this.length = length;
    }

    private Integer fitness() {

        return strength.value * length.value - mass.value * mass.value;
    }

    @Override public int compareTo(Genome that) {

        // notice the fitter is less in precedence
        if(this.fitness() > that.fitness())
            return -1;
        else if(this.fitness() < that.fitness())
            return 1;
        else // this.fitness() == that.fitness()
            return 0;
    }

    public static Genome recombine(Genome... parents) {

        if(parents.length < 1)
            return null;

        // Select parents randomly and then characteristics from them
        Mass mass = parents[(int)(Math.random() * parents.length)].mass;
        Strength strength = parents[(int)(Math.random() * parents.length)].strength;
        Length length = parents[(int)(Math.random() * parents.length)].length;;

        return new Genome(mass, strength, length);
    }

    public static Genome mutate(Genome parent) {

        // Select characteristics randomly
        Mass mass = Mass.values()[(int)(Math.random() * Mass.values().length)];
        Strength strength = Strength.values()[(int)(Math.random() * Strength.values().length)];
        Length length = Length.values()[(int)(Math.random() * Length.values().length)];

        return new Genome(mass, strength, length);
    }

    public static void main() {

        PriorityQueue<Genome> population = new PriorityQueue<Genome>();

        Genome parent1 = new Genome(Mass.LIGHT, Strength.STRONG, Length.SHORT);
        Genome parent2 = new Genome(Mass.AVERAGE, Strength.AVERAGE, Length.AVERAGE);
        Genome parent3 = new Genome(Mass.HEAVY, Strength.WEAK, Length.LONG);

        population.add(parent1);
        population.add(parent2);
        population.add(parent3);

        Genome child1 = Genome.recombine(parent1, parent2);
        Genome child2 = Genome.recombine(parent1, parent2);
        Genome child3 = Genome.recombine(parent1, parent3);
        Genome child4 = Genome.recombine(parent1, parent3);
        Genome child5 = Genome.recombine(parent2, parent3);
        Genome child6 = Genome.recombine(parent2, parent3);
        Genome child7 = Genome.recombine(parent1, parent2, parent3);
        Genome child8 = Genome.recombine(parent1, parent2, parent3);
        Genome child9 = Genome.recombine(parent1, parent2, parent3);

        child1 = Genome.mutate(child1);
        child2 = Genome.mutate(child2);
        child4 = Genome.mutate(child4);
        child8 = Genome.mutate(child8);

        population.add(child1);
        population.add(child2);
        population.add(child3);
        population.add(child4);
        population.add(child5);
        population.add(child6);
        population.add(child7);
        population.add(child8);
        population.add(child9);

        // and the winner is...
        Genome fittest = population.peek();
    }
}

エンコーディング

シーケンスで明示的ないくつかの特性とそれらから派生した他の特性を持つシーケンスに特性をエンコードしたいように聞こえるので。

上記の列挙型のような値の範囲を、明示的な特性を表すチャンクを持つ整数にエンコードすることで、これを行うことができます。

たとえば、それぞれ 4 つの可能な値を持つ 2 つの明示的な特性がある場合、セットを 00XX + XX00 の形式の整数としてエンコードできます。したがって、たとえば 0111 は質量 01 と長さ 11 に対応する場合があります。これにより、シーケンス自体のビットを変更して変異させることができます。

Java の例

import java.util.PriorityQueue;

class Genome implements Comparable<Genome> {

    private final Integer sequence;

    private static final Integer bitmaskChunk = 3; // ...0011

    private static final Integer shiftMass = 0; // ...00XX
    private static final Integer shiftLength = 2; // ...XX00

    private static final Integer shiftModulus = 4; // ...0000

    private Integer getMass() {

        return (sequence >>> shiftMass) & bitmaskChunk;
    }

    private  Integer getLength() {

        return (sequence >>> shiftLength) & bitmaskChunk;
    }

    public Integer getStrength() {

        return getMass() * getLength();
    }

    public Genome(Integer sequence) {

        this.sequence = sequence % (1 << Genome.shiftModulus);
    }

    private Integer fitness() {

        // Some performance measure
        return getStrength() * getLength() - getMass() * getMass();
    }

    @Override public int compareTo(Genome that) {

        // notice the fitter is less in precedence
        if(this.fitness() > that.fitness())
            return -1;
        else if(this.fitness() < that.fitness())
            return 1;
        else // this.fitness() == that.fitness()
            return 0;
    }

    public static Genome recombine(Genome... parents) {

        if(parents.length < 1)
            return null;

        Integer sequence = 0;

        // Select parents randomly and then characteristics from them
        sequence += parents[(int)(Math.random() * parents.length)].getMass() << Genome.shiftMass;
        sequence += parents[(int)(Math.random() * parents.length)].getLength() << Genome.shiftLength;

        return new Genome(sequence);
    }

    public static Genome mutate(Genome parent) {

        Integer sequence = parent.sequence;

        // Randomly change sequence in some way
        sequence *= (int)(Math.random() * (1 << Genome.shiftModulus));

        return new Genome(sequence);
    }

    public static void main() {

        PriorityQueue<Genome> population = new PriorityQueue<Genome>();

        Genome parent1 = new Genome((int)(Math.random() * (1 << Genome.shiftModulus)));
        Genome parent2 = new Genome((int)(Math.random() * (1 << Genome.shiftModulus)));
        Genome parent3 = new Genome((int)(Math.random() * (1 << Genome.shiftModulus)));

        population.add(parent1);
        population.add(parent2);
        population.add(parent3);

        Genome child1 = Genome.recombine(parent1, parent2);
        Genome child2 = Genome.recombine(parent1, parent2);
        Genome child3 = Genome.recombine(parent1, parent3);
        Genome child4 = Genome.recombine(parent1, parent3);
        Genome child5 = Genome.recombine(parent2, parent3);
        Genome child6 = Genome.recombine(parent2, parent3);
        Genome child7 = Genome.recombine(parent1, parent2, parent3);
        Genome child8 = Genome.recombine(parent1, parent2, parent3);
        Genome child9 = Genome.recombine(parent1, parent2, parent3);

        child1 = Genome.mutate(child1);
        child2 = Genome.mutate(child2);
        child4 = Genome.mutate(child4);
        child8 = Genome.mutate(child8);

        population.add(child1);
        population.add(child2);
        population.add(child3);
        population.add(child4);
        population.add(child5);
        population.add(child6);
        population.add(child7);
        population.add(child8);
        population.add(child9);

        // and the winner is...
        Genome fittest = population.peek();
    }
}

これがあなたが探しているものであることを願っています。幸運を。

于 2011-09-15T16:39:35.197 に答える