C# 基于重量和价值的遗传算法将物品储存在3辆卡车中

C# 基于重量和价值的遗传算法将物品储存在3辆卡车中,c#,algorithm,genetic-algorithm,knapsack-problem,genetic,C#,Algorithm,Genetic Algorithm,Knapsack Problem,Genetic,我目前正在编写一个遗传算法来解决一个可能被认为与类似的问题,但区别因素是我在多辆“卡车”上存储物品,它们的价值/重要性基于1=最重要,3=最不重要 我是如何做到这一点的,是使用一个二进制整数数组,0=不在卡车上,1=在卡车上 在大多数情况下,该计划似乎正在做它需要做的事情。除了我比较染色体以找出每一代最好的三条染色体。个体是指没有染色体可以包含相同的项目,因为项目只能在一个卡车上的时间 这是我用来比较染色体的函数: private int[] getBestSolution(int co

我目前正在编写一个遗传算法来解决一个可能被认为与类似的问题,但区别因素是我在多辆“卡车”上存储物品,它们的价值/重要性基于1=最重要,3=最不重要

我是如何做到这一点的,是使用一个二进制整数数组,0=不在卡车上,1=在卡车上

在大多数情况下,该计划似乎正在做它需要做的事情。除了我比较染色体以找出每一代最好的三条染色体。个体是指没有染色体可以包含相同的项目,因为项目只能在一个卡车上的时间

这是我用来比较染色体的函数:

    private int[] getBestSolution(int count)
    {
        int[] Genes = new int[3];
        int min1 = Global.p.population[0].fitness;
        int min2 = Global.p.population[0].fitness;
        int min3 = Global.p.population[0].fitness;
        int ref1 = 0;
        int ref2 = 0;
        int ref3 = 0;
        bool areSame = true;

        //searches for the first "Fittest" chromosome and stores to ref1
        for (int i = 0; i < Global.population; i++)
        {
                if (min1 > Global.p.population[i].fitness)
                {
                    min1 = Global.p.population[i].fitness;
                    ref1 = i;
                }
        }

        //searches for 2nd fittest, while also checking they are different
        for (int i = 0; i < Global.population; i++)
        {
            areSame = arrayCompare(Global.p.population[ref1].chromosome, Global.p.population[i].chromosome);
            if(areSame == true)
            {
                continue;
            }
            if (min2 > Global.p.population[i].fitness)
            {
                min2 = Global.p.population[i].fitness;
                ref2 = i;
            }
        }

        //Searches for 3rd fittest while checking that it is different from the first two
        for (int i = 0; i < Global.population; i++)
        {
            areSame = arrayCompare(Global.p.population[ref1].chromosome, Global.p.population[i].chromosome);
            if (areSame == true)
            {
                continue;
            }
            areSame = arrayCompare(Global.p.population[ref2].chromosome, Global.p.population[i].chromosome);
            if(areSame == true)
            {
                continue;
            }
            if (min3 > Global.p.population[i].fitness)
            {
                min3 = Global.p.population[i].fitness;
                ref3 = i;
            }
        }
        //stores the reference of each chromosome and return
        Genes[0] = ref1;
        Genes[1] = ref2;
        Genes[2] = ref3;
        return Genes;
    }
private int[]getBestSolution(int计数)
{
int[]基因=新的int[3];
int min1=Global.p.population[0]。适合度;
int min2=Global.p.population[0]。适合度;
int min3=Global.p.population[0]。适合度;
int ref1=0;
int ref2=0;
int ref3=0;
bool arame=true;
//搜索第一条“最适合”的染色体并存储到参考文献1
对于(int i=0;iGlobal.p.population[i].fitness)
{
min1=全局.p.总体[i].适应度;
ref1=i;
}
}
//搜索第二名,同时检查他们是否不同
对于(int i=0;iGlobal.p.population[i].fitness)
{
min2=全局.p.总体[i].适应度;
ref2=i;
}
}
//搜索第三名,同时检查它是否与前两名不同
对于(int i=0;iGlobal.p.population[i].fitness)
{
min3=全局.p.总体[i].适应度;
ref3=i;
}
}
//存储每个染色体的引用并返回
基因[0]=ref1;
基因[1]=ref2;
基因[2]=ref3;
返回基因;
}
这是我用来将染色体与之前选择的染色体进行比较的函数,以确保它们不包含相同的值

    public bool arrayCompare(int[] a, int[] b)
    {
        for (int i = 0; i < a.Length; i++)
        {
            if ((a[i] == 1) && b[i] == 1)
            {
                return true;
            }
        }
        return false;
    }
public bool arrayCompare(int[]a,int[]b)
{
for(int i=0;i
通过在代码的不同点使用断点并检查值与预期值之间的差异,我已经将其缩小到这两个导致问题的函数

最后,是问题本身。getBestSolution()完美地生成第一个“最适合”的值。第二个和第三个值保持其初始化为“总体[0].fitness”的状态,并显示该值

我试图改变育种结构,育种的选择标准,因为我相信如果没有包含不同值的染色体,它将保持初始状态。出于同样的原因,我还使用了更多的人群进行了测试,所以我认为他们的行为一定是我的代码中的一个问题

非常感谢您的帮助。

1。关于代码的注释。 您应该将
min1
min2
min3
初始化为高于适应度最大值的值,因为在
Global.p.population[0]的情况下,适应度是人群中的最佳适应度,您永远找不到第二和第三个最佳,因为在这种情况下,没有任何个人的适应度低于
Global.p.population[0]。适应度

2.你使用的基因的概率。 我可能错了,但这是我对你所描述的问题的理论

在随机分布中,对于一个基因,两个个体的基因值总共有4种可能的组合。在这4个组合中,有3个个体没有共同的基因设置为
1

               Individual 1    Individual 2   Match criterion    Probability
Combination 1:      0               0               Yes            25% | 
Combination 2:      0               1               Yes            25% | 75%
Combination 3:      1               0               Yes            25% |
Combination 4:      1               1               No             25%
这意味着对于只有一个基因的个体,你有75%的机会找到两个符合标准的个体。换句话说,如果你比较100个个体的基因,你会发现平均有75对个体符合标准。但是会有一些种群你找不到它们,而大多数种群你会找到它们

随着基因数量的增加,百分比会下降。每次你在染色体上添加一个基因,你必须乘以75/100符合标准的个体百分比。每次你添加2个基因时,你必须将百分比乘以56,25/100

Number of genes         percentage of individuals matching the criterion
      1                                75,00%
      2                                56,25% = 75,00 * 75,00 / 100

      4                                31,64% = 56,25 * 56,25 / 100

      6                                17,79% = 31,64 * 56,25 / 100

      8                                10,01% = 17,79 * 56,25 / 100

    [...]

     16                                 1%
这意味着,对于一个由16个基因组成的染色体和100个群体,你会发现平均有1对个体符合标准。如果你想要3个人符合标准,那么这个百分比甚至更小。对于6个基因,找到这3个个体的概率应该在1.5%左右

所以问题是,在一个群体中,没有足够的个体对符合标准

3.另一种设计算法的方法。 在你的算法中,y
gene[0] = 1 (item 0 is in truck 1)
gene[1] = 0 (item 1 is not in any truck) 
gene[2] = 3 (item 2 is in truck 3)
gene[3] = 2 (item 3 is in truck 2)
gene[4] = 1 (item 4 is in truck 1)
first best individual:
----------------------
truck1: item1 item2
truck2: item3 item4
truck3: item5 item6 item7
not in any truck: item0

second best individual:
-----------------------
truck1: item1 item3
truck2: item2 item5
truck3: item4 item6
not in any truck: item0 item7