简体   繁体   English

结构和数组

[英]structs and arrays

I am currently looking at this: 我目前正在看这个:

some Genetic Algorithm 一些遗传算法

This is some adapted code: 这是一些改编的代码:

struct Chromosome
{
    public bool[] genes;
    public int fitness;
}

I have never used structs in my evolutionary algorithms/genetic algorithms. 我从未在我的进化算法/遗传算法中使用过结构体。 Is it not a bit pointless to use arrays in structs - especially when I have to make deep copies? 在结构中使用数组是不是没有意义 - 特别是当我必须制作深拷贝时? Is there any advantage of using structs in this scenario? 在这种情况下使用结构有什么好处吗?

Thanks. 谢谢。

I don't see any problem with this... In GAs its all about validating the fitness of your candidates. 我没有看到任何问题......在GAs中,它的全部内容都是为了验证候选人的健康状况。 the struct just capsulates all the information for your candidate. 结构只是封装候选人的所有信息。 therefore the fitness is directly associated with your gene. 因此,适应性与您的基因直接相关。 It makes perfect sense to store it in the same class/struct. 将它存储在同一个类/结构中是完全合理的。

If you do not store the fitness with your gene you have to map it somehow. 如果你没有用你的基因存储健康,你必须以某种方式映射它。 This would be an unnecessary hassle. 这将是一个不必要的麻烦。 Or, if you do not want to store the fitness at all you have to recalculate it evertime you compare two candidates against each other. 或者,如果你根本不想存储健身,你必须重新计算它,你将两个候选人相互比较。 Would not be wise. 不明智。 especially if the fitness evaluation is rather complex (for example in a GA to evaluate the best parameters for a simulation). 特别是如果适应度评估相当复杂(例如在GA中评估模拟的最佳参数)。

I would use a class that implements the interface IComparable. 我会使用一个实现IComparable接口的类。 Two candidates would than be compared by there fitness. 两个候选人将被比较健身。 Then you only need to sort your list of candidates and pick, for example, the best 10 candidates for the next generation (Always depends on the type of GA you are using). 然后你只需要对你的候选人名单进行排序,然后选择下一代最好的10个候选人(总是取决于你正在使用的GA的类型)。

about the bool array... I don't see any problem with this either. 关于bool数组...我也没有看到任何问题。 If this is how your gene is represented best... perfect :). 如果这是你的基因最好的代表...完美:)。 The representation as a integer is also fine but in some cases it might make the x-over operation a bit complicated... always depends on the case... 表示为整数也很好,但在某些情况下,它可能会使x-over操作有点复杂......总是取决于案例......

The bool array will not get deep copied automatically in this case. 在这种情况下,bool数组不会自动深度复制。 So you're not really benefitting from structs because when you assign Chromosome to a new one, the reference in both would be to the same bool[ ] 所以你并没有真正受益于结构,因为当你将染色体分配给一个新结构时,两者中的引用将是相同的bool []

Instead of using a bool[] you can just use a number: let's say int . 而不是使用bool []你可以只使用一个数字:让我们说int A chromosome with genes = 3 represents gene: 0000 0000 0000 0000 0000 0011. A chromosome with genes = 42134 represents gene: 0000 0000 1010 0100 1001 0110. int is 32 bits which means that you can represent chromosomes with 2 32 genes this way. 基因= 3的染色体代表基因:0000 0000 0000 0000 0000 0011.具有基因= 42134的染色体代表基因:0000 0000 1010 0100 1001 0110.int是32位,这意味着您可以用这种方式表示具有2 32个基因的染色体。 You avoid having to worry about deep copying an array and this is faster and more efficient in terms of memory consumption too. 您可以避免担心深度复制数组,这在内存消耗方面也更快,更高效。 Use Int64 if you need more genes. 如果您需要更多基因,请使用Int64。

Update: You're question is so cool btw. 更新:你的问题是如此酷,顺便说一句。 In case you have restrictions to the possible gene combinations in some segments, you need to construct the Int32 byte by byte according to the restrictions. 如果您对某些段中可能的基因组合有限制,则需要根据限制逐字节构造Int32。 To illustrate, I assumed an example for some restrictions on a Chromosome and randomly mutated a Chromosome but with respect to restraints. 为了说明,我假设了一个关于染色体的一些限制并且随机突变染色体但关于限制的例子。

        //The following creates a random chromosome with restrictions
        //to the genes as described in the following:

        //Let's say that the following pattern must be adhered to: 
        //byte 1 = xxxx xxxx (anything)
        //byte 2 = 1011 xxxx (restricted)
        //byte 3 = [0000 or 1111] xxxx (restricted)
        //byte 4 = 0000 1111 (fixed value)

        Random rnd = new Random();
        byte[] randomByte = new byte[1]; //xxxx xxxx xxxx xxxx

        byte restrictedByte2 = 
            (byte)(Math.Pow(2,7) * 1 + Math.Pow(2,6) * 0 + 
            Math.Pow(2,5) * 1 + Math.Pow(2,4) * 1 + 
            rnd.Next(0, 16)); //1011 xxxx

        //in byte 3, the first (most significant) for bits are restricted to either 0000 or 1111. 
        //That's either number 0 * 16 = 0 or number 15 * 16 = 240. I multiplied by 2^4 because it's shifted
        //4 bytes to the left.
        byte higherBits = (byte)(rnd.Next(0, 2/*upper bound exclusive*/) == 1?240:0);
        //random lower bits (xxxx).
        byte lowerBits = (byte)(Math.Pow(2,0) * rnd.Next(0, 2) + Math.Pow(2,1) * rnd.Next(0, 2) + 
            Math.Pow(2,2) * rnd.Next(0, 2) + Math.Pow(2,3) * rnd.Next(0, 2) + 
            rnd.Next(0, 16));

        byte restrictedByte3 = (byte)(lowerBits + higherBits);

        byte restrictedByte4 = 143; //constant

        //Create an Int32 from the four bytes.
        int randomMutation = BitConverter.ToInt32(
            new byte[] { randomByte[1], restrictedByte2, restrictedByte3, restrictedByte4 }, 0);

Typically, we use a struct to represent something that can be considered pretty primitive. 通常,我们使用struct来表示可以被认为非常原始的东西。 According to MSDN , it should be a type that represents a single "value", 16 bytes or less in size, and so on. 根据MSDN ,它应该是一个表示单个“值”的类型,大小为16个字节或更小,依此类推。

The main thing to keep in mind with a struct is the value-type semantics, so passing this in and out of functions will create a copy. 要记住struct是值类型语义,因此将此函数传入和传出函数将创建一个副本。 Cost wise this won't be too bad since what you are copying is 1 reference (to the array of bool) and 1 int, but it does create some interesting side effects if you try to modify the array reference in another method or from a copy. 成本方面这不会太糟糕,因为您复制的是1个引用(对于bool数组)和1个int,但如果您尝试在另一个方法中修改数组引用或从复制。

Many people assume struct will always be more efficient than class , but this is not always the case and usually this micro-optimization is more dangerous than helpful because it introduces the side-effects of working with a value type. 许多人认为struct总是比class更有效,但情况并非总是如此,通常这种微优化比有用更危险,因为它引入了使用值类型的副作用。

As for the array of bool you can either create and set bits in an int or use the BitArray specialized class in the BCL. 对于bool数组,您可以在int创建和设置位,也可以在BCL中使用BitArray专用类。

So, the long and the short of it is, if this is legacy code and you want to keep the struct , it will work, but it can byte you if you expect it to act like a class does when passed/copied. 所以,它的长短都是,如果这是遗留代码并且你想保留struct ,那么它将起作用,但是如果你希望它在传递/复制时像一个class那样行事,它就可以对你进行编码。 However, looking at what it's holding, it doesn't meet the MSDN guidance for what struct is best suited for. 但是,看看它持有什么,它不符合MSDN对哪种struct最适合的指导。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM