【问题标题】:Genetic Algorithm - Crossover and Mutation not working correctly遗传算法 - 交叉和突变无法正常工作
【发布时间】:2017-07-13 09:12:30
【问题描述】:

我正在使用GA Package 来最小化一个函数。以下是我实施的几个阶段。

0。库和数据集

library(clusterSim)      ## for index.DB()
library(GA)              ## for ga() 
data("data_ratio")
dataset2 <- data_ratio
set.seed(555)

1.二进制编码并生成初始种群。

initial_population <- function(object) {
    ## generate a population where for each individual, there will be number of 1's fixed between three to six
    population <- t(replicate(object@popSize, {i <- sample(3:6, 1); sample(c(rep(1, i), rep(0, object@nBits - i)))}))
    return(population)
}

2。适应度函数最小化 Davies-Bouldin (DB) 指数。

DBI2 <- function(x) {
    ## number of 1's will represent the initial selected centroids and hence the number of clusters
    cl <- kmeans(dataset2, dataset2[x == 1, ])
    dbi <- index.DB(dataset2, cl=cl$cluster, centrotypes = "centroids")
    score <- -dbi$DB

    return(score)
}

3.用户定义的交叉运算符。这种交叉方法将避免没有集群“打开”的情况。伪代码可以在here找到。

pairwise_crossover <- function(object, parents){
    fitness <- object@fitness[parents]
    parents <- object@population[parents, , drop = FALSE]
    n <- ncol(parents)
    children <- matrix(as.double(NA), nrow = 2, ncol = n)
    fitnessChildren <- rep(NA, 2)

    ## finding the min no. of 1's between 2 parents
    m <- min(sum(parents[1, ] == 1), sum(parents[2, ] == 1))
    ## generate a random int from range(1,m)
    random_int <- sample(1:m, 1)
    ## randomly select 'random_int' gene positions with 1's in parent[1, ]
    random_a <- sample(1:length(parents[1, ]), random_int)
    ## randomly select 'random_int' gene positions with 1's in parent[1, ]
    random_b <- sample(1:length(parents[2, ]), random_int)
    ## union them
    all <- sort(union(random_a, random_b))
    ## determine the union positions
    temp_a <- parents[1, ][all]
    temp_b <- parents[2, ][all]

    ## crossover
    parents[1, ][all] <- temp_b
    children[1, ] <- parents[1, ]
    parents[2, ][all] <- temp_a
    children[2, ] <- parents[2, ]

    out <- list(children = children, fitness = fitnessChildren)
    return(out)
}

4.突变。

k_min <- 2
k_max <- ceiling(sqrt(75))

my_mutation <- function(object, parent){
    pop <- parent <- as.vector(object@population[parent, ])
    for(i in 1:length(pop)){
            if((sum(pop == 1) < k_max) && pop[i] == 0 | (sum(pop == 1) > k_min && pop[i] == 1)) {
                    pop[i] <- abs(pop[i] - 1)
                    return(pop) 
            }

    }

}

5.把碎片放在一起。使用轮盘赌选择,交叉概率。 = 0.8,突变概率。 = 0.1

g2<- ga(type = "binary", 
    population = initial_population, 
    fitness = DBI2, 
    selection = ga_rwSelection,
    crossover = pairwise_crossover,
    mutation = my_mutation,
    pcrossover = 0.8,
    pmutation = 0.1,
    popSize = 100, 
    nBits = nrow(dataset2))

我以这样一种方式创建了我的初始人口,即对于人口中的每个人,1's 的数量将固定在三到六之间。交叉和变异算子旨在确保解决方案最终不会有太多集群 (1's) 被“打开”。在集成之前,我已经分别尝试了我的交叉和突变功能,它们似乎工作正常。

理想情况下,最终的解决方案将具有来自初始群体的1's +-=1 的数量,即,如果一个个体的染色体中有三个1's,它最终会随机有两个、三个或四个1's。但我得到了这个解决方案,它显示 12 个集群 (1's) 正在“打开”,这意味着交叉和变异算子运行良好。

> sum(g2@solution==1)
[1] 12

这里的问题可以通过复制所有代码来重现。任何熟悉 GA 包的人都可以在这里帮助我吗?

[已编辑]

尝试使用不同的数据集iris,让我陷入了以下错误。 (仅更改数据,其余设置保持不变)

0。库和数据集

library(clusterSim)      ## for index.DB()
library(GA)              ## for ga() 
## removed last column since it is a categorical data
dataset2 <- iris[-5]
set.seed(555)

> Error in kmeans(dataset2, centers = dataset2[x == 1, ]) : 
  initial centers are not distinct

我尝试查看code,发现此错误是由if(any(duplicated(centers))) 引起的。这可能意味着什么?

【问题讨论】:

  • 你能分享你的样本初始人口数据吗?
  • 它在initial_population 函数中,它将返回一个100 x 75 的二进制矩阵。我不太确定如何使用 ga 包访问它,但您可以使用 population &lt;- t(replicate(100, {i &lt;- sample(3:6, 1); sample(c(rep(1, i), rep(0, 75 - i)))})) 尝试一下
  • k_maxk_min?
  • 对不起,我错过了。 k_min = 2k_max = ceiling(sqrt(75))
  • mutation_rate?还有其他未定义的常量吗?

标签: r genetic-algorithm mutation crossover


【解决方案1】:

值得一提的几点:

  1. crossover 中,为了随机选择parent[1, ] 中带有1 的“random_int”基因位置,您将以下代码行从

    random_a &lt;- sample(1:length(parents[1, ]), random_int)

    random_a &lt;- sample(which(parents[1, ]==1), random_int)

    对于其他父母也是如此。

    但是,我认为这种交叉策略可以保证任何后代最多可以打开簇位的总数,因为它的父代的 1 位的最大数量(在这种情况下可以是初始种群中的 6 个,不应该如果您只希望解决方案基因有 1 位差异,则为 4?)。

    下图显示了3个随机选择的位置,其中至少有一个亲本基因有1位,同时交叉和后代产生。

  1. mutation函数中,我认为,更明确地说,我们应该改变这行代码

    if((sum(pop == 1) &lt; k_max) &amp;&amp; pop[i] == 0 | (sum(pop == 1) &gt; k_min &amp;&amp; pop[i] == 1))

    通过

    if((sum(pop == 1) &lt; k_max &amp;&amp; pop[i] == 0) | (sum(pop == 1) &gt; k_min &amp;&amp; pop[i] == 1))

    带有适当的括号。

  2. 另外,您的 fitness 函数(Davies-Bouldin's index 测量集群分离)似乎有利于打开更多集群。

最后我认为是mutation 是罪魁祸首,如果您将k_max 更改为低值(例如,3)并将pmutation 更改为低值(例如,pmutation = 0.01),您会在最终解决方案所有基因都打开了 4 位。

[已编辑]

set.seed(1234)
k_min = 2
k_max = 3 #ceiling(sqrt(75))
#5. Putting the pieces together. Using roulette-wheel selection, crossover prob. = 0.8, mutation prob. = 0.1
g2<- ga(type = "binary", 
        population = initial_population, 
        fitness = DBI2, 
        selection = ga_rwSelection,
        crossover = pairwise_crossover,
        mutation = my_mutation,
        pcrossover = 0.8,
        pmutation = 0.01,
        popSize = 100, 
        nBits = nrow(dataset2))    

g2@solution # there are 6 solution genes
    x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36 x37
[1,]  0  0  0  0  0  0  1  0  1   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[2,]  0  0  0  0  0  0  1  0  0   0   1   0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[3,]  0  0  0  0  0  0  1  0  0   0   1   0   0   0   0   0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[4,]  0  0  0  0  0  0  1  1  0   0   0   0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[5,]  0  0  0  1  0  0  0  0  0   0   1   0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[6,]  0  0  0  1  0  0  0  0  0   0   1   0   0   0   0   0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
     x38 x39 x40 x41 x42 x43 x44 x45 x46 x47 x48 x49 x50 x51 x52 x53 x54 x55 x56 x57 x58 x59 x60 x61 x62 x63 x64 x65 x66 x67 x68 x69 x70 x71 x72
[1,]   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[2,]   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[3,]   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[4,]   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[5,]   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[6,]   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
     x73 x74 x75
[1,]   0   0   0
[2,]   0   0   0
[3,]   0   0   0
[4,]   0   0   0
[5,]   0   0   0
[6,]   0   0   0

rowSums(g2@solution) # all of them have 4 bits on
#[1] 4 4 4 4 4 4

[EDIT2]

  1. 实际上crossover策略保证没有额外的位开启组合双亲,即孩子的1位总数=双亲的1位总数,但任何单个孩子都可以有更多位打开。下面显示了单个后代可以比任何父母打开更多位的示例:

【讨论】:

  • 谢谢先生指出我的错误!是的,我同意你关于crossover 运算符的观点,我的目的是测试聚类算法的不同初始质心。关于mutation,我尝试了k_max = 3pmutation = 0.01,在检查最佳解决方案g2@solution 时,我发现有12 位(簇)被打开。为什么会这样?它会与您指出的第 3 点有关吗?
  • @jacky_learns_to_code 是的,可能是因为这个,添加了一些可重现的代码,其中最终的解决方案只包含 4 位集合。
  • 先生,您好,crossover 确实保证了后代最多具有其父母的最大 1 位。但我担心的是,在检查rowSums(g2@solution) 后,关闭了突变(pmutation = 0),我注意到 1 的位数总是大于最大值。其父级的1位数,为什么会这样?
  • @jacky_learns_to_code 很好。实际上,crossover 策略保证了结合双亲时不会打开额外的位,即孩子中 1 的总数 = 父母中的 1 总数,但是任何单个孩子都可以打开更多位,加了一个例子,看看吧。
  • 这个例子完全有道理,谢谢先生!最后,crossover 的行为很大程度上取决于随机索引
猜你喜欢
  • 2014-08-12
  • 2016-09-16
  • 2014-02-07
  • 1970-01-01
  • 2012-09-23
  • 2011-03-10
  • 2016-08-31
  • 2015-07-03
相关资源
最近更新 更多