# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
import numpy as np
import random
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import pandas as pd
import math
import kmeans
from random import choice
Q0=0.5
ALPHA=0.5
BETA=0.5
ROE=0.5
'''客户信息'''
PN=16
posi=[[1,1],[2,2],[3,3],[4,4],[5,5],
[6,6],[7,7],[8,8],[9,9],[10,10],[11,11],[12,12],
[13,13],[14,14],[15,15],[16,16]]
buy=[1,10,3,4,5,6,7,8,2,10,5,1,2,4,6,3]
recy=[5,7,8,1,3,9,2,3,10,6,9,1,2,6,4,1]
'''分成几段呢'''
FenDuan=3
'''车的信息'''
bus1=[10,20]
bus2=[10,20]
Theta=10
busV1=bus1[0]+bus1[1]
busV2=bus2[0]+bus2[1]
# 先标记所有店都没走过为0
is_work=np.zeros(PN)
# 车的信息记录好
bus={}
bus[0]=bus1
bus[1]=bus2
'''先进行聚类分好类'''
#print(kmeans.all_routes)
all_routes=kmeans.all_routes
#print("距离",kmeans.distance)
dis=kmeans.distance
class answer:
def __init__(self):
self.routes={}
self.routes[0]=[]
self.routes[1]=[]
# fitness
self.COST=9999999
#在某一小段里挑点[2,3,9]
def four_steps(all_points):
points=all_points[:]
# # 先把去过的点都去掉
# for point in points:
# if is_work[point]==1:
# points.remove(point)
# 选好的点放里面
choose_list=[]
while len(points)!=0:
# 随机选一个点,这个点之前没走过
pi=choice(points)
points.remove(pi)
choose_list.append(pi)
return choose_list
#all_routes
#{0: [[2, 3, 9],
# [12, 13, 15, 10, 14, 10, 14],
# [5, 6, 11, 1, 7, 8, 2, 3, 9, 1, 7, 8, 2, 3, 9, 2, 3, 9]],
# 1: [[10, 14],
# [1, 7, 8, 2, 3, 9, 2, 3, 9],
# [0, 4, 12, 13, 15, 10, 14, 12, 13, 15, 10, 14, 10, 14]]}
def birth_answer(ans,all_routes):
length=len(all_routes[0])
choose_list={}
#遍历每一段
for i in range(length):
choose_list[0]=four_steps(all_routes[0][i])
choose_list[1]=four_steps(all_routes[1][i])
ans.routes[0].append(choose_list[0])
ans.routes[1].append(choose_list[1])
#顺便把点去过得删了
def remove(pointss):
points=pointss.copy()
# 先把去过的点都去掉
for point in points:
if is_work[point]==1:
points.remove(point)
return points
#x=answer()
#birth_answer(x,all_routes)
#route=x.routes
def get_cost_0(rout):
length=len(all_routes[0])
all_choose_list=rout.copy()
route=rout.copy()
COST=0
choose_list={}
#遍历每一段
for i in range(length):
choose_list[0]=remove(all_choose_list[0][i])
choose_list[1]=remove(all_choose_list[1][i])
if i==0:
# 第一个数代表上一个点是什么
# 第二个数代表是第几条路线的
# 第三个数代表是不是最后一个点
# 第四个表示蚁群算法选出的点
COST+=get_cost(-1,0,0,choose_list[0])
COST+=get_cost(-1,1,0,choose_list[1])
elif i==length-1:
COST+=get_cost(route[0][-1][-1],0,1,choose_list[0])
COST+=get_cost(route[1][-1][-1],1,1,choose_list[1])
else:
COST+=get_cost(route[0][-1][-1],0,0,choose_list[0])
COST+=get_cost(route[1][-1][-1],1,0,choose_list[1])
return COST
def get_cost(former,bus_num,is_last,choose_list):
# choose_list=choose_list[0]
# former=-1
# bus_num=0
# is_last=0
# 就跑当前这一段就行了,不是完全失败就标记走过
# which用来标记是第一段还是中间,还是最后一段(要不要去仓库)
COST=0
#第一段是从仓库出来
if former==-1:
# dis的PN里是仓库
COST+=dis[choose_list[0],PN]
else:
COST+=dis[choose_list[0],former]
length=len(choose_list)
i=0
for i in range(length):
now=choose_list[i]
# 不考虑上一个用户
if i==0:
mai=buy[now]
bus[bus_num][1]+=min(bus[bus_num][0],mai)
bus[bus_num][1]-=recy[now]
bus[bus_num][0]-=mai
# 考虑上一个用户
# 先考虑上一个点有没有失败'''
# 如果失败,那就会仓库分两种情况'''
if bus[bus_num][0]<0 and bus[bus_num][1]<0:
#print("遇到失败")
# 失败的话就不标记因为下段路还要走
#通过算成本比较用哪种
d1=dis[choose_list[i-1],PN]
d2=dis[now,choose_list[i-1]]
d3=dis[now,PN]
if d1+d3<d2:
COST+=(3*d1+d3)
#第一种情况:JL+=3*(上一点i-1到仓库的距离)+(仓库到i的距离)
#bus1[1]为负数,加上等于减去
mai=buy[now]
bus[bus_num][1]=busV1-Theta+min(Theta,mai)-recy[now]
bus[bus_num][0]=Theta-mai
else:
COST+=(2*d1+d2)
#第二种情况:JL+=2*(上一点i-1到仓库的距离)+(i-1到i的距离)
mai=buy[now]
bus[bus_num][1]=busV1-Theta+min(Theta,mai)-recy[now]+bus[bus_num][1]
bus[bus_num][0]=Theta-mai
elif bus[bus_num][0]<0 and bus[bus_num][1]>0:
# 标记当前点已经走过
is_work[now]=1
#先把成本算上去
COST+=dis[choose_list[i-1],now]
bus[bus_num][0]=-1*buy[now]
bus[bus_num][1]=bus[bus_num][1]-recy[now]
#考虑最后一段半失败也回仓库
if is_last==1:
d1=dis[choose_list[i-1],PN]
d2=dis[now,choose_list[i-1]]
d3=dis[now,PN]
if d1+d3<d2:
COST+=(3*d1+d3)
else:
COST+=(2*d1+d2)
elif bus[bus_num][0]>0 and bus[bus_num][1]<0:
is_work[now]=1
COST+=dis[choose_list[i-1],now]
mai=buy[now]
bus[bus_num][1]=min(bus[bus_num][0],mai)-recy[now]
bus[bus_num][0]=bus[bus_num][0]-mai
#考虑最后一段半失败也回仓库
if is_last==1:
d1=dis[choose_list[i-1],PN]
d2=dis[now,choose_list[i-1]]
d3=dis[now,PN]
if d1+d3<d2:
COST+=(3*d1+d3)
else:
COST+=(2*d1+d2)
else:
is_work[now]=1
COST+=dis[choose_list[i-1],now]
mai=buy[now]
bus[bus_num][1]=bus[bus_num][1]+min(bus[bus_num][0],mai)-recy[now]
bus[bus_num][0]=bus[bus_num][0]-mai
if is_last==1:
COST+=dis[now,PN]
# 保存最终路线
return COST
all_routes={}
length=len(kmeans.all_routes)
#kmeans.all_routes
#{0: [[2, 3, 9], [10, 14]],
# 1: [[12, 13, 15], [1, 7, 8]],
# 2: [[5, 6, 11], [0, 4]]}
#解的特殊表示
ls0=[]
ls1=[]
for i in range(length):
route=kmeans.all_routes[i]
if i == 0:
ls0.append(route[0])
ls1.append(route[1])
else:
ls=route[0]
ls.extend(ls1[i-1])
ls0.append(ls)
ls=route[1]
ls.extend(ls0[i-1])
ls1.append(ls)
all_routes[0]=ls0
all_routes[1]=ls1
#all_routes
#{0: [[2, 3, 9],
# [12, 13, 15, 10, 14, 10, 14],
# [5, 6, 11, 1, 7, 8, 2, 3, 9, 1, 7, 8, 2, 3, 9, 2, 3, 9]],
# 1: [[10, 14],
# [1, 7, 8, 2, 3, 9, 2, 3, 9],
# [0, 4, 12, 13, 15, 10, 14, 12, 13, 15, 10, 14, 10, 14]]}
#测试
#算成本之前都要is_work=np.zeros(PN)
#a=answer()
#a.routes
#birth_answer(a,all_routes)
#is_work=np.zeros(PN)
#a.COST=get_cost_0(a.routes)
'''PSO算法''