You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言遗传算法:如何指定二进制染色体中1的数量

如何在R语言遗传算法中指定二进制染色体中1的数量?

我正在使用rbga函数(该问题同样适用于R语言中其他遗传算法实现方案),想知道是否可以指定二进制染色体中1的数量。

示例代码

data(iris)
library(MASS)
X <- as.data.frame(cbind(scale(iris[,1:4]), matrix(rnorm(36*150), 150, 36)))
Y <- iris[,5]

iris.evaluate <- function(indices) {
    print("Chromosome")
    print(indices)
    print("=================================")
    result = 1
    if (sum(indices) > 2) {
        huhn <- lda(X[,indices==1], Y, CV=TRUE)$posterior
        result = sum(Y != dimnames(huhn)[[2]][apply(huhn, 1,
                                                    function(x)
                                                        which(x == max(x)))]) / length(Y)
    }
    result
}

monitor <- function(obj) {
    minEval = min(obj$evaluations);
    plot(obj, type="hist");
}

woppa <- rbga.bin(size=40, mutationChance=0.05, zeroToOneRatio=10,
                  evalFunc=iris.evaluate, showSettings=TRUE, verbose=TRUE)

部分染色体示例

"Chromosome"
 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
"================================="
"Chromosome"
 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0
"================================="
"Chromosome"
 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0
"================================="
"Chromosome"
 0 0 0 1 0 0 0 0 0 0 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 1 0 0 0 0
"================================="

上述染色体中1的数量(即选中的特征数)分别为5、8、5和4。

我需要遵循某论文中的技术要求,应用遗传算法后需选取特定数量的特征,因此有两个问题:

  1. 是否可以在遗传算法中指定解/染色体所需的特征数量?
  2. 是否可以在最终解/染色体上实现该需求?若可以,具体如何操作?

问题1:在遗传算法运行中指定特征数量

可以通过两种核心方式实现约束:

方法1:修改适应度评估函数,添加惩罚机制

对不符合目标特征数量的染色体施加极高惩罚,让这类染色体在选择过程中被快速淘汰。比如你需要固定选择5个特征,可以修改评估函数如下:

iris.evaluate <- function(indices) {
    target_k <- 5  # 你需要的固定特征数量
    # 对不符合数量要求的染色体直接返回最差适应度(这里是最大错误率)
    if (sum(indices) != target_k) {
        return(1)
    }
    # 原有的评估逻辑
    huhn <- lda(X[,indices==1], Y, CV=TRUE)$posterior
    result = sum(Y != dimnames(huhn)[[2]][apply(huhn, 1,
                                                function(x)
                                                    which(x == max(x)))]) / length(Y)
    result
}

这种方法简单直接,不需要修改遗传算法的核心逻辑,适合rbga.bin这类参数较少的实现。

方法2:自定义遗传操作(交叉/变异)

如果需要更严格的约束,可以重写交叉和变异函数,确保生成的新染色体始终满足1的数量要求:

  • 交叉操作:只交换两个染色体中相同位置的0和1,或者交换固定数量的1的位置,保证交叉后1的总数不变。
  • 变异操作:每次变异时,必须将一个0转为1的同时,把另一个1转为0,保持总数恒定。

不过rbga.bin本身没有开放自定义交叉、变异的参数,你可能需要切换到更灵活的遗传算法包(如GA包),或者直接修改genalg包的源码实现。


问题2:在最终解上实现特征数量约束

如果不在算法运行过程中约束,也可以在得到遗传算法的结果后进行处理:

方法1:筛选种群中符合数量要求的最优解

运行完遗传算法后,从所有迭代产生的种群个体中,筛选出1的数量符合要求的个体,再从中选择适应度最优的:

target_k <- 5
# 从种群中筛选出特征数量符合要求的个体
valid_pop <- woppa$population[apply(woppa$population, 1, sum) == target_k, ]
# 对应筛选出的个体的适应度值
valid_evals <- woppa$evaluations[apply(woppa$population, 1, sum) == target_k]

# 找到适应度最优的个体(这里错误率最小)
if (length(valid_evals) > 0) {
    best_valid_idx <- which.min(valid_evals)
    best_valid_chromosome <- valid_pop[best_valid_idx, ]
    print("符合数量要求的最优染色体:")
    print(best_valid_chromosome)
} else {
    print("种群中没有符合数量要求的个体,请调整算法参数或运行次数")
}

方法2:调整最优解的特征数量

如果种群中没有完全符合要求的个体,可以对最优解进行微调:

  • 如果最优解的1的数量多于目标值:随机去掉多余的1;
  • 如果少于目标值:随机添加缺少的1。

但这种方法可能会降低解的最优性,仅适合对精度要求不高的场景。


内容的提问来源于stack exchange,提问作者vic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:07:29