如何确定基因组的特征?

发布于 2024-12-04 12:10:13 字数 455 浏览 8 评论 0原文

在人工智能中,是否有任何简单和/或非常直观的例子来说明如何将基因组应用到模拟中?

基本上,我正在做一个简单的演练(不是教程,而是总结性质的东西),它详细介绍了如何实现一个基因组,该基因组在总结中改变了“个体”的特征。

这些基因不会是这样的东西:

  • 质量、
  • 强度
  • 、长度
  • 等。

相反,它们应该是定义上述东西,从基因组的实际特征中抽象出基因组。模拟的居民。

我足够清楚自己想要什么吗?

无论如何,如果有任何你尝试过的方法那就更好了,并且以 的形式实现进化这些性游泳者,那么无论如何,请继续发布它!灵感越有趣越好:)

In AI, are there any simple and/or very visual examples of how one could implement a genome into a simulation?

Basically, I'm after a simple walkthrough (not a tutorial, but rather something of a summarizing nature) which details how to implement a genome which changes the characteristics in an 'individual' in a sumlation.

These genes would not be things like:

  • Mass
  • Strength
  • Length,
  • Etc..

But rather they should be the things defining the above things, abstracting the genome from the actual characteristics of the inhabitants of the simulation.

Am I clear enough on what I want?

Anyway, if there's any way that you have tried that's better, and that implements evolution in a form like these sexual swimmers, then by all means, go ahead and post it! The more fun inspiration the better :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

-黛色若梦 2024-12-11 12:10:13

如果您自己实现“个体”,那么任何对象都可以充当您的基因组。

特征

进一步简化此过程的一种方法是将特征转换为枚举。通过这种方式,您可以通过选择特征来对父母的基因进行简单的重组,并通过随机选择特征的枚举值之一来进行基因的突变。

一旦它起作用,您就可以对值范围进行更细致的了解,但是使用枚举可以帮助我首先让事情变得清晰。

健身

然后,为了赋予这些特征,您需要一个描述表现的健身函数。特征之间的关系取决于您,因此您可以用任何有意义的方式对其进行描述。这只是提供了一种比较两个基因组的一致方法。

模拟

然后,要运行模拟,只需从几个父母开始,并生成一堆孩子来相互完成。这当然可以自动化,但为了清楚起见,这里有一个明确的示例。

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();
    }
}

编码

因为听起来您想要将特征编码到序列中,该序列具有序列中明确的一些特征以及从这些特征派生的其他特征。

您可以将您的值范围(如上面的枚举)编码为一个整数,其中的块表示您的显式特征。

例如,如果您有两个显式特征,每个特征有四个可能值,则可以将集合编码为 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();
    }
}

我希望这就是您正在寻找的内容。祝你好运。

If you are implementing your 'individuals' yourself then any object can act as your genome.

Characteristics

One way to simplify this further is to turn your characteristics into enums. This way you can have a simple recombination of the parent's genes by selecting characteristics from them and a mutation of the gene by random selection of one of the enum values for a characteristic.

Once this is working you can get more nuanced with value ranges but using enums helps me keeps things clear at first.

Fitness

Then to give these characteristics meaning you need a fitness function that describes performance. The relationship between the characteristics is up to you so you can describe it in any way that makes sense. This just provides a consistant way to compare two genomes.

Simulation

Then to run a simulation just start with a few parents and generate a bunch of children to complete with each other. This can of course be automated but here is an explicit example for clarity.

Java Example

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();
    }
}

Encoding

Since it sounds like you want to encode the characteristics into a sequence having some characteristics explicit in the sequence and others derived from those.

You can do this my encoding your rangle of values, like the enums above, into an integer with chunks representing your explicit characteristics.

For example if you have two explicit characteristics with four possible values each you may encode the set as an integer in the form of 00XX + XX00. So for example 0111 might corresponds to a mass of 01 and a length of 11. What this does is let you mutate by changing the bits within the sequence itself.

Java Example

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();
    }
}

I hope this is what you are looking for. Good luck.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文