用遗传算法解决非线性优化问题,代码出错,希望可以debug一下

想用遗传算法求解一个非线性优化问题,但遇到了错误,错误显示“ValueError: empty range for randrange() (1, 1, 0)”,希望有大佬可以帮忙看看~


```python
import random
from deap import base, creator, tools

def find_optimal_batch_number(actual_quantity, fixed_cost, rated_quantity):
    # 定义适应度函数
    def evaluate(individual):
        num_batches = individual[0]
        cost = fixed_cost * num_batches * (1 + ((actual_quantity / (num_batches * rated_quantity)) ** 3))
        return cost,

    # 创建遗传算法工具箱
    creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
    creator.create("Individual", list, fitness=creator.FitnessMin)

    toolbox = base.Toolbox()
    toolbox.register("attr_int", random.randint, 1, max(2, actual_quantity))
    toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_int, 1)
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)
    toolbox.register("evaluate", evaluate)
    toolbox.register("mate", tools.cxTwoPoint)
    toolbox.register("mutate", tools.mutUniformInt, low=1, up=actual_quantity, indpb=0.5)
    toolbox.register("select", tools.selTournament, tournsize=3)

    # 初始化种群
    pop = toolbox.population(n=50)

    # 迭代求解
    NGEN = 50
    for gen in range(NGEN):
        # 评估种群中每个个体的适应度
        fitnesses = list(map(toolbox.evaluate, pop))
        for ind, fit in zip(pop, fitnesses):
            ind.fitness.values = fit

        # 选择下一代种群
        offspring = toolbox.select(pop, len(pop))
        offspring = list(map(toolbox.clone, offspring))

        # 交叉和变异
        for child1, child2 in zip(offspring[::2], offspring[1::2]):
            if random.random() < 0.5:
                toolbox.mate(child1, child2)
                del child1.fitness.values
                del child2.fitness.values

        for mutant in offspring:
            if random.random() < 0.2:
                toolbox.mutate(mutant)
                del mutant.fitness.values

        # 评估新种群中每个个体的适应度
        invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
        fitnesses = map(toolbox.evaluate, invalid_ind)
        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit

        # 更新种群
        pop[:] = offspring

    # 获取最优解
    best_individual = tools.selBest(pop, 1)[0]
    optimal_num_batches = best_individual[0]

    return optimal_num_batches

# 示例用法
actual_quantity = 1  # 实际货物数量
fixed_cost = 100  # 固定成本
rated_quantity = 200  # 额定货物数量

optimal_batch_number = find_optimal_batch_number(actual_quantity, fixed_cost, rated_quantity)
print("最佳运输批数:", optimal_batch_number)


```

错误信息 "ValueError: empty range for randrange() (1, 1, 0)" 是由于在调用 toolbox.register("mutate", tools.mutUniformInt, low=1, up=actual_quantity, indpb=0.5) 函数时,up 参数的值为 1,导致了范围为空。这可能是因为传入的 actual_quantity 参数值较小所导致的。

请检查 actual_quantity 参数的值是否正确,确保其大于 1。如果 actual_quantity 的值不大于 1,则需要进行相应的调整以避免此错误。

这个报错通常是由于参数范围设置错误导致的。在你的代码中,报错是由于在创建attr_int属性时使用了random.randint(1, max(2, actual_quantity)),但当actual_quantity的值为1时,参数范围变成了range(1, 1),导致randrange()函数的参数错误。

为了解决这个问题,你可以在设置参数范围时增加一些额外的逻辑,以确保范围的有效性。以下是修改后的代码:

import random
from deap import base, creator, tools

def find_optimal_batch_number(actual_quantity, fixed_cost, rated_quantity):
    # 定义适应度函数
    def evaluate(individual):
        num_batches = individual[0]
        cost = fixed_cost * num_batches * (1 + ((actual_quantity / (num_batches * rated_quantity)) ** 3))
        return cost,

    # 创建遗传算法工具箱
    creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
    creator.create("Individual", list, fitness=creator.FitnessMin)

    toolbox = base.Toolbox()
    # 修正参数范围
    max_quantity = max(2, actual_quantity)
    toolbox.register("attr_int", random.randint, 1, max_quantity)
    toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_int, 1)
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)
    toolbox.register("evaluate", evaluate)
    toolbox.register("mate", tools.cxTwoPoint)
    toolbox.register("mutate", tools.mutUniformInt, low=1, up=max_quantity, indpb=0.5)
    toolbox.register("select", tools.selTournament, tournsize=3)

    # 初始化种群
    pop = toolbox.population(n=50)

    # 迭代求解
    NGEN = 50
    for gen in range(NGEN):
        # 评估种群中每个个体的适应度
        fitnesses = list(map(toolbox.evaluate, pop))
        for ind, fit in zip(pop, fitnesses):
            ind.fitness.values = fit

        # 选择下一代种群
        offspring = toolbox.select(pop, len(pop))
        offspring = list(map(toolbox.clone, offspring))

        # 交叉和变异
        for child1, child2 in zip(offspring[::2], offspring[1::2]):
            if random.random() < 0.5:
                toolbox.mate(child1, child2)
                del child1.fitness.values
                del child2.fitness.values

        for mutant in offspring:
            if random.random() < 0.2:
                toolbox.mutate(mutant)
                del mutant.fitness.values

        # 评估新种群中每个个体的适应度
        invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
        fitnesses = map(toolbox.evaluate, invalid_ind)
        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit

        # 更新种群
        pop[:] = offspring

    # 获取最优解
    best_individual = tools.selBest(pop, 1)[0]
    optimal_num_batches = best_individual[0]

    return optimal_num_batches

# 示例用法
actual_quantity = 1  # 实际货物数量
fixed_cost = 100  # 固定成本
rated_quantity = 200  # 额定货物数量

optimal_batch_number = find_optimal_batch_number(actual_quantity, fixed_cost, rated_quantity)
print("最佳运输批数:", optimal_batch_number)

通过在 toolbox.register("attr_int", random.randint, 1, max_quantity) 中使用 max_quantity 作为参数范围的上限,确保范围始终大于等于2。这样就解决了报错问题,并确保了参数范围的有效性。

遗传算法的Python实现(非线性函数优化问题为例)
可以参考下
https://blog.csdn.net/qq_43445362/article/details/108307132

ValueError: empty range for randrange() (1, 1, 0) 这个错误的意思就是说当前是一个空循环,因为andrange() (1, 1, 0) 第一个参数是指循环的起始值,第二个值是循环的终止值,终止值必须要大于起始值,否则相当于循环一个空的东西。所以你需要检查下你的程序中使用到的循环的地方的代码,看下是否有存在空循环的情况。

参数范围超限了