基于贪心策略、邻域搜索和遗传算法的设施分配优化问题

基于贪心策略、邻域搜索和遗传算法的设施分配优化问题

算法概论期末项目

摘要

使用贪心算法、邻域搜索(不同邻域方法)和遗传算法(不同选择、变异、交叉方法),解决设施分配优化问题

1. 导言

问题重述

有一些设施,每个设施有不同的承载量,设施承载不能超过这个值
有一些顾客,每个顾客有不同的需求量
没有顾客使用的设施,不需要启动,无需维护费,否则需要维护费
把一名顾客,分配到一台设施,需要一定的调度费
尝试找到一种方案,分配每一个顾客一个设施,使总体费用尽可能最优

贪心算法

该算法不断生成随机解,并与现有最优解进行比较,如果随机解更好就替换之

邻域搜索

该算法从一个初始解出发,通过邻域函数生成解的邻域,再在邻域中 搜索出更优的解来替换当前解,通过不断的迭代过程实现解

遗传算法

该算法模拟生物遗传进化的特点,对问题进行编码,进行选择、交叉、变异操作,不断迭代寻找更优解

2. 实验过程

问题编码

我采用整数编码,即一个解是一个长度为顾客数的数组,对应顾客的数组元素就是该顾客被分配的设施

这样编码可以方便后面的邻域、变异、交叉操作

代价函数

根据题目的定义定义代价函数,即设施开放代价和用户调度代价的总和
特别地,如果一个解使一个设施超出承载量,则它的代价为最大值(MAX_NUM

计算代价

def get_cost(assign):
    if not is_assign_valid(assign):
        return MAX_NUM
    cost = 0
    fset = set()
    for i in range(customer_num):
        fset.add(assign[i])
        cost += allocating_cost[assign[i]][i]
    for i in range(facility_num):
        if i in fset:
            cost += facility_cost[i]
    return cost

判断解是否合法:

def is_assign_valid(assign):
    real_facility_capacity = [0] * facility_num
    for i in range(customer_num):
        real_facility_capacity[assign[i]] += customer_demand[i]
    for i in range(facility_num):
        if real_facility_capacity[i] > facility_capacity[i]:
            return False
    return True

数据读入

数据71个样例,三种格式,需要处理,使批处理得以运行

def get_data(index):
    global facility_num
    global customer_num
    global facility_capacity
    global facility_cost
    global allocating_cost
    global customer_demand
    with open('Instances/p' + str(index), 'r')as f:
        lines = f.read()
    arr = lines.replace('.', ' ').replace(chr(0), '').replace('\n', ' ').split()
    for i in range(len(arr)):
        arr[i] = int(arr[i])
    facility_num, customer_num = arr[0], arr[1]
    facility_capacity, facility_cost = [], []
    ind = 2
    for i in range(facility_num):
        facility_capacity.append(arr[ind])
        facility_cost.append(arr[ind + 1])
        ind += 2
    customer_demand = []
    for i in range(customer_num):
        customer_demand.append(arr[ind])
        ind += 1
    # ac[f, c]
    allocating_cost = []
    for i in range(facility_num
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值