游玩规则,既环境模拟器的实现
import xlrd
import numpy as np
import xlwt
import random
import math
import json
#导入更新了体力值的表格
data=xlrd.open_workbook("D:/PCstudy/data/Question_reults_end.xls")
table = data.sheets()[0]#选择第0张表
nrows = table.nrows # 行数
ncols = table.ncols # 列数
datamatrix = [] # 构造列表
for i in range(nrows):
rows = table.row_values(i) #获取第i行的内容
datamatrix.append(rows) #写入数据
#导入更新了地图的表格
data=xlrd.open_workbook("D:/PCstudy/data/graphs.xlsx")
graph = data.sheets()[0]#选择第0张表
grows = graph.nrows # 行数
gcols = graph.ncols # 列数
graphs = [] # 构造列表
for i in range(grows):
rows = graph.row_values(i) #获取第i行的内容
graphs.append(rows) #写入数据
#记录去过的景点,一共17个景点
#'蜀汉牌楼(出入口1)', '廊桥(出入口2)', '龙劲飞瀑', '樊家大院',
# '旺旺乐园-旋转木马', '川晋游乐园', '黄龙溪博物馆', '龙溪大酒店',
# '栖凤长廊', '石桥', '凤岛', '五孔桥',
# '镇江寺', '唐家大院', '古戏台', '古码头', '古龙寺' 800*17=13600m 1360m/800=1.6 16
#初始化速度,消耗的时间看作消耗的体力
speed = 300
'''
体力值<=1 0.1
体力值<=3 0.335
体力值<=5 0.525
体力值<=7 0.745
体力值<=10 0.855
体力值<=23 0.95
同类景点:
1桥:廊桥(出入口2)、石桥、五孔桥 0.886
2游乐园:'旺旺乐园-旋转木马', '川晋游乐园' 0.913
3寺庙:镇江寺、古龙寺 0.866
4大院:樊家大院、唐家大院 0.845
5古景点:古戏台, 古码头 0.456
工资:
一万一下 :0.7
一万至十万 :0.8
十万至二十五万 :0.834
二十五万至五十万 :0.896
五十万至七十五万 :0.954
七十五万至一百万 :0.978
一百万以上: 1
消费景点:'4 旺旺乐园-旋转木马', '5 川晋游乐园'
学历:
初中及以下
# 9.0 9.0 9.0 8.5 9.0 8.5 9.0 7.0 9.0 8.0 7.5 7.5 8.5 8.0 8.0 7.5 7.5
[0.1,0.1,0.1,0.05,0.1,0.05,0.1,0,0.1,0.01,0,0,0.05,0.01,0.01,0,0]
高中\中专\职校
# 9.0 9.0 8.5 8 7 8 7.5 8 9.0 8.5 8 8.5 8.5 8 8.5 8.5 8.5
[0.1,0.1,0.05,0.01,0,0.01,0,0.01,0.1,0.05,0.01,0.05,0.05,0.01,0.05,0.05,0.05]
大学
# 8.0 8.0 8 9 7 7.0 9.5 8.0 9.5 8.5 8.5 8.5 9 9 10.0 10.0 10.0
[0.01,0.01,0.01,0.1,0,0,0.1,0.01,0.1,0.05,0.05,0.05,0.1,0.1,0.2,0.2,0.2]
硕士研究生及以上
# 8 8 8 8.0 7 7 7.5 6.5 8 8 8 8 8.5 9.5 8.5 9.0 10.0
[0.01,0.01,0.01,0.01,0,0,0,0,0.01,0.01,0.01,0.01,0.05,0.1,0.05,0.1,0.2]
'''
same = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,1,0,4,2,2,0,0,0,1,0,1,3,4,5,5,3]]
same_values = [1,1-0.886,1-0.913,1-0.866,1-0.845,1-0.456]
study_values = [[0.1,0.1,0.1,0.05,0.1,0.05,0.1,0,0.1,0.01,0,0,0.05,0.01,0.01,0,0],
[0.1,0.1,0.05,0.01,0,0.01,0,0.01,0.1,0.05,0.01,0.05,0.05,0.01,0.05,0.05,0.05],
[0.01,0.01,0.01,0.1,0,0,0.1,0.01,0.1,0.05,0.05,0.05,0.1,0.1,0.2,0.2,0.2],
[0.01,0.01,0.01,0.01,0,0,0,0,0.01,0.01,0.01,0.01,0.05,0.1,0.05,0.1,0.2]]
#定义函数,POI值的改变
def POI_updata(POI0,POWER0,k):
#随着体力改变
#print(POWER0)
if POWER0 <= 1 : POI0 = [i * 0.42496 for i in POI0]
elif POWER0 <= 3 : POI0 = [i * 0.59735 for i in POI0]
elif POWER0 <= 5: POI0 = [i * 0.675874 for i in POI0]
elif POWER0 <= 7: POI0 = [i * 0.785986 for i in POI0]
elif POWER0 <= 12: POI0 = [i * 0.855324 for i in POI0]
elif POWER0 <= 23: POI0 = [i * 0.95432 for i in POI0]
else : POI0 = [i * 0.9785326 for i in POI0]
#随着相似度改变
sum = [1,1,1,1,1,1] # 记录每一类相似度总函数
same_historl = [0,0,0,0,0,0]
for i in range(17): #每一类去过的次数
if same[0][i] >1 & same[1][i] >0: same_historl[same[1][i]]+=1 #无类似的不会统计
for i in range(6): #每一类累加的相似度
if same_historl[i]>=2: sum[i]+=(1-same_values[same_historl[i]])
for i in range(17): #对景点进行相似度处理
if same[1][i] == 0 & same[0][i] > 1: POI0[i]*=0.51234 # 去过完全相同且没有跟它类似的景点
else :POI0[i]*=(1/sum[same[1][i]])
#随着工资改变
money = datamatrix[k][3]
if money == "一万一下":
POI0[4]*=0.80321
POI0[5]*=0.80321
elif money == "一万至十万":
POI0[4] *= 0.82456
POI0[5] *= 0.82456
elif money == "十万至二十五万" :
POI0[4] *= 0.854876
POI0[5] *= 0.854876
elif money == "二十五万至五十万":
POI0[4] *= 0.896567
POI0[5] *= 0.896567
elif money == "五十万至七十五万":
POI0[4] *= 0.954345
POI0[5] *= 0.954345
elif money == "七十五万至一百万":
POI0[4] *= 0.978234
POI0[5] *= 0.978234
# 随着学历改变
study = datamatrix[k][22]
if study == "初中及以下":
for i in range(17):
POI0[i]*=(1+study_values[0][i]*0.06662)
elif study == "高中\中专\职校":
for i in range(17):
POI0[i]*=(1+study_values[1][i]*0.06662)
elif study == "大学":
for i in range(17):
POI0[i] *= (1 + study_values[2][i]*0.06662)
else :
for i in range(17):
POI0[i] *= (1 + study_values[3][i]*0.06662)
# 偏置
for i in range(17):
POI0[i] += random.uniform(-0.005, 0.005)
if POI0[i] >1 : POI0[i] = 0.998
elif POI0[i] <0 : POI0[i] = 0
return POI0
POI_history = []
dicts = {}
#定义函数,每个用户的遍历所有情况
def routs(POI0,POWER0,v,k,ans,POI_ans,j): #兴趣度,体力值,去过景点列表(有序),第k个用户
# 体力不够,推荐终止;一直在休息,超过体力最大限度
if POWER0<1:
dic = [("visit_historal",v),("POI_sum",ans),("POI_historal",POI_ans)]
dic = dict(dic)
w = str(j)
dicts[w]=dic
return
i = random.randint(0,16) #随机选取下一个景点
last = v[len(v)-1] #上一个去过的景点
ans += POI0[i]
POWER0-=0.25
POWER0 -= graphs[last+1][i+1] / speed # 消耗体力:路程除以速度,消耗的时间就是消耗的体力
same[0][i]+=1 #记录下现在去的景点
v.append(i)
POI1=POI_updata(POI0,POWER0,k) #更新POI
POI_ans.append(POI1)
POI_history.append(POI1) #记录改变后的POI
routs(POI1,POWER0,v,k,ans,POI_ans,j)
for i in range(nrows):
#对于每一个用户来说,数据初始化:
if i == 0:
continue
dicts = {}
for j in range(1000):
#print(j+1) #第几个数据
# 所有景点的初始感兴趣度为
data = datamatrix[i]
POI0=data[5:22]
for w in range(17):
POI0[w]*=0.1
#初始体力为
POWER0=datamatrix[i][ncols-1]
#起始地点,永远是蜀汉牌楼
v = []
v.append(0) #加入第一个景点
same[0][0]+=1
POI0 = POI_updata(POI0,POWER0,i)
POI_history.append(POI0) #记录历史POI值
ans = 0 # 总满意度
ans += POI0[0]
POI_ans =[]
POI_ans.append(POI0)
routs(POI0,POWER0,v,i,ans,POI_ans,j+1)
# 写为json数据
path = "D:/PCstudy/pythonProject1/routing/user_data/user_visit_json"
path += str(i)
path += ".json"
with open(path, "w", encoding='utf-8') as f:
#json.dump(dicts, f) # 写为一行
json.dump(dicts, f, indent=2, sort_keys=False, ensure_ascii=False) # 写为多行