优化算法-随机搜索、爬山法、模拟退火法、遗传算法2

案例2: 涉及偏好的优化

这里考虑另一种使用优化算法来解决的不同问题。一般表述为:如何将有限的资源分配给多个表达了偏好的人,并根据他们的意愿,尽可能地满足需求。

假设你在东京的酒店定了5间房(A,B,C,D,E),5间房各有其风格特点,朋友们根据自己的喜好,给你发了想入住的房间首选、备选。5间房,10个人,每2人一间,每个人都有自己的首选房间和备选房间。

你发现他们中有>2个人都对同一间房感兴趣,该怎么安排他们的入住,才能使得他们尽可能的满意呢?

假设你统计到朋友们的及首选、备选房号为:
(老高:A,B),(老张:A,C),(老刘:A,D),(老宋:B,E),(老何:C,D),(老牛:B,D),(老李:E,C),(老赵:D,A),(老钱:C,D),(老曾:D,E)

思路同之前分析的行程优化问题基本一致,但这个问题背景下,题解的定义域要做调整,以体现每个房间只能住两个人这个约束条件。

简单理解就是,酒店经理把5间房的10张房卡(一个房间住2人,每人1张房卡)拿出来。你们10人来抽取房卡,房卡被拿走就没有了,其余的人只能在剩下的房卡中选择。即最开始题解域为[A,A,B,B,C,C,D,D,E,E],第一个人老高抽走了一个房卡A,那么轮到第二个人老张选房间时,题解域变成了[A,B,B,C,C,D,D,E,E],老张也抽走了A。那么轮到老刘时,题解域变成了[B,B,C,C,D,D,E,E],依次进行下去,直到剩下最后一个人抽取。

 

思路逻辑

Python 代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#@Time: 2019-11-13 22:35
#@Author: gaoll

import datetime
import random
import math
import optimization
from optimization import randomoptimize
from optimization import hillclimb
from optimization import annealingoptimize
from optimization import geneticoptimize

#5间房
dorms = ['A','B','C','D','E'] 

#每个人的首选和次选
prefs=[('Gao',('A','B')),('Zhang',('A','C')),('Liu',('A','D')),('Song',('B','E')),('He',('C','D')),('Niu',('B','D')),('Li',('E','C')),('Zhao',('D','A')),('Qian',('C','D')),('Zeng',('D','E'))]

#10个人依次选房,定义域为:
domain = []
for i in range(len(prefs)):
	domain.append((0,len(prefs)-i-1)) #第一个选房人有10张房卡可选,所以它的可行域为[0,9],一个值就表示10张房卡中选第几张房卡;后选之人的题解域随之依次减少

#对给出的一个题解sol进行解释
def printsolution(sol):
	dorm_cards = dorms*2 #5间房,每个房间住两人,共有10张房卡

	results = []
	for i in range(len(sol)):
		dorm = dorm_cards[sol[i]] #表示选取了dorm_cards房卡列表中的第sol[i]张房卡代表的房间
		results.append((prefs[i][0],dorm)) #prefs[i][0]第i个人选了dorm这间房	
		del dorm_cards[sol[i]] #房卡选完后,从题解域中删除,后面的人不能再选,只能从剩下的房卡中选择

	print(results)

#如对下面的一个题解的解释:
sol=[0,0,0,0,0,0,0,0,0,0]
printsolution(sol)
'''运行结果:[('Gao', 'A'), ('Zhang', 'B'), ('Liu', 'C'), ('Song', 'D'), ('He', 'E'), ('Niu', 'A'), ('Li', 'B'), ('Zhao', 'C'), ('Qian', 'D'), ('Zeng', 'E')]'''

#成本函数,由每个人的首选、次选房间和她最终被入住的房间进行比较。如果入住的是首选房,成本+0,如果入住的是次选房,成本+1,如果都不是,成本+3
def dormcost(sol):
	cost = 0
	dorm_cards = dorms*2 #5间房,每个房间住两人,共有10张房卡
	for i in range(len(sol)):
		dorm = dorm_cards[sol[i]] #入住房间
		person = prefs[i][0] #入住人
		first_dorm = prefs[i][1][0]  #首选房
		second_dorm = prefs[i][1][1]  #次选房
		#计算成本
		if dorm == first_dorm: 
			cost+=0
		elif dorm == second_dorm:
			cost +=1
		else:
			cost +=3
		del dorm_cards[sol[i]]  #删除被选择的房卡

	return cost

#执行优化函数
#已经定义了定义域和成本函数,可选择上篇博文中定义的四种优化函数执行求解

#调用随机搜索算法
sol1 = randomoptimize(domain,dormcost)
print(dormcost(sol1))
printsolution(sol1)

#调用爬山法
sol2 = hillclimb(domain,dormcost)
print(dormcost(sol2))
printsolution(sol2)

#调用模拟退火算法
sol3 = annealingoptimize(domain,dormcost,T=100)
print(dormcost(sol3))
printsolution(sol3)

#调用遗传算法
sol4 = geneticoptimize(domain,dormcost)
print(dormcost(sol4))
printsolution(sol4)

'''
#四种优化算法,运行结果展示
5
[('Gao', 'B'), ('Zhang', 'C'), ('Liu', 'A'), ('Song', 'E'), ('He', 'D'), ('Niu', 'B'), ('Li', 'E'), ('Zhao', 'A'), ('Qian', 'C'), ('Zeng', 'D')]
7
[('Gao', 'A'), ('Zhang', 'B'), ('Liu', 'A'), ('Song', 'D'), ('He', 'C'), ('Niu', 'B'), ('Li', 'E'), ('Zhao', 'D'), ('Qian', 'C'), ('Zeng', 'E')]
17
[('Gao', 'D'), ('Zhang', 'D'), ('Liu', 'A'), ('Song', 'B'), ('He', 'E'), ('Niu', 'B'), ('Li', 'C'), ('Zhao', 'A'), ('Qian', 'E'), ('Zeng', 'C')]
4
[('Gao', 'A'), ('Zhang', 'B'), ('Liu', 'A'), ('Song', 'E'), ('He', 'C'), ('Niu', 'B'), ('Li', 'E'), ('Zhao', 'D'), ('Qian', 'C'), ('Zeng', 'D')]
'''

Done

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值