Commit 35b28e4c authored by Allvey's avatar Allvey

new branch

parent 7376b7ca
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2021/7/26 14:35
# @Author : Opfer
# @Site :
# @File : path_plannner.py
# @Software: PyCharm
import numpy
from settings import *
from static_data_process import *
load_area_uuid_to_index_dict, unload_area_uuid_to_index_dict, \
load_area_index_to_uuid_dict, unload_area_index_to_uuid_dict = build_work_area_uuid_index_map()
load_area_num, unload_area_num = len(load_area_uuid_to_index_dict), len(unload_area_uuid_to_index_dict)
class PathPlanner:
def __init__(self):
# 路线行驶成本
self.rout_cost = np.array((unload_area_num, load_area_num))
# 路段集合
self.lane_set = {}
# 车辆长度
self.truck_length = 10
def path_cost_generate(self, path_id):
pass
def lane_cost_generate(self, lane_id):
# 道路长度
lane_length = 100
# 路段实际矿卡速度
actual_speed = 20
# 车辆自由行驶时的速度
clear_speed = 25
# 1. 计算阻塞时车辆密度
truck_density = lane_length / self.truck_length
# 2. 读取实际车流速度
actual_speed = 20
# 3. 计算路段阻塞程度
lane_blockage = (1 - actual_speed / clear_speed) * truck_density
......@@ -31,6 +31,10 @@ from traffic_flow_planner import *
from settings import *
from static_data_process import *
# item = session_postgre.query(Lane).first()
#
# print(item.LaneIds)
# 全局参数设定
# 空载任务集合
......@@ -45,7 +49,7 @@ empty_speed = 25
# 重载矿卡速度,单位(km/h)
heavy_speed = 22
# 卸目标卸载量
# 卸载设备目标卸载量
dump_target_mass = 5000
# 挖机目标装载量
......@@ -87,6 +91,11 @@ dynamic_excavator_set = set(update_autodisp_excavator())
dynamic_dump_set = set(update_autodisp_dump())
item = session_postgre.query(Lane).first()
print(item.LaneIds)
# 设备映射类, 存储除工作区以外的映射关系
# 其余设备类继承该类
class DeviceMap:
......@@ -141,7 +150,7 @@ class DumpInfo(DeviceMap):
# self.cur_dump_ava_time = np.zeros(self.dumps)
# # 模拟各设备可用时间(防止调度修改真实产量)
# self.sim_dump_ava_time = np.zeros(self.dumps)
# 用于动态调度的卸载集合
# 用于动态调度的卸载设备集合
self.dynamic_dump_set = []
# 开始时间
self.start_time = datetime.now()
......@@ -160,7 +169,10 @@ class DumpInfo(DeviceMap):
def get_dump_actual_mass(self):
return self.cur_dump_real_mass
# 更新卸点卸载时间
def get_dynamic_dump_set(self):
return self.dynamic_dump_set
# 更新卸载设备卸载时间
def update_dump_unloadtime(self):
self.unloading_time = np.zeros(self.dumps)
......@@ -177,12 +189,12 @@ class DumpInfo(DeviceMap):
unload_count = unload_count + 1
self.unloading_time[self.dump_uuid_to_index_dict[dump_id]] = ave_unload_time / unload_count
except Exception as es:
logger.error(f'卸载 {dump_id} 卸载时间信息缺失, 已设为默认值(1min)')
logger.error(f'卸载设备 {dump_id} 卸载时间信息缺失, 已设为默认值(1min)')
logger.error(es)
self.unloading_time[self.dump_uuid_to_index_dict[dump_id]] = 1.00
# print("average_unload_time: ", self.unloading_time[self.dump_uuid_to_index_dict[dump_id]])
# 更新卸实际卸载量
# 更新卸载设备实际卸载量
def update_actual_unload_thoughout(self):
self.cur_dump_real_mass = np.zeros(self.dumps)
now = datetime.now().strftime('%Y-%m-%d')
......@@ -204,7 +216,7 @@ class DumpInfo(DeviceMap):
# 装载设备映射
self.load()
# # 初始化卸可用时间
# # 初始化卸载设备可用时间
# self.cur_dump_ava_time = np.full(self.dumps,
# (datetime.now() - self.start_time) / timedelta(hours=0, minutes=1,
# seconds=0))
......@@ -226,7 +238,7 @@ class DumpInfo(DeviceMap):
# # 同步虚拟卸载量
# self.sim_dump_real_mass = copy.deepcopy(self.cur_dump_real_mass)
# # 计算卸载预估产量
# # 计算卸载设备预估产量
# self.update_pre_unload_throughout()
......@@ -248,7 +260,7 @@ class ExcavatorInfo(DeviceMap):
# self.cur_excavator_ava_time = np.zeros(self.excavators)
# # 模拟各设备可用时间(防止调度修改真实产量)
# self.sim_excavator_ava_time = np.zeros(self.excavators)
# 用于动态调度的卸载集合
# 用于动态调度的卸载设备集合
self.dynamic_excavator_set = []
# 开始时间
self.start_time = datetime.now()
......@@ -267,6 +279,9 @@ class ExcavatorInfo(DeviceMap):
def get_excavator_actual_mass(self):
return self.cur_excavator_real_mass
def get_dynamic_excavator_set(self):
return self.dynamic_excavator_set
# 更新挖机装载时间
def update_excavator_loadtime(self):
self.loading_time = np.zeros(self.excavators)
......@@ -332,7 +347,7 @@ class ExcavatorInfo(DeviceMap):
# # 同步挖机虚拟装载量
# self.sim_excavator_real_mass = copy.deepcopy(self.cur_excavator_real_mass)
# # 计算卸载预估产量
# # 计算卸载设备预估产量
# self.update_pre_load_throughout()
......@@ -352,6 +367,24 @@ class WalkManage(DeviceMap):
# 备停区行走时间(面向设备)
self.park_to_load_eq = np.full((park_num, len(update_autodisp_excavator())), M)
def get_com_time_area(self):
return self.com_time_area
def get_go_time_area(self):
return self.go_time_area
def get_com_time_eq(self):
return self.com_time_eq
def get_go_time_eq(self):
return self.go_time_eq
def get_park_to_load_area(self):
return self.park_to_load_area
def get_park_to_load_eq(self):
return self.park_to_load_eq
def update_walk_time(self):
self.load()
......@@ -426,20 +459,16 @@ class TruckInfo(DeviceMap):
self.walker = WalkManage()
# 矿卡数量
self.trucks = len(dynamic_truck_set)
# 矿卡抵达卸时间
# 矿卡抵达卸载设备时间
self.cur_truck_reach_dump = np.zeros(self.trucks)
# 矿卡抵达挖机时间
self.cur_truck_reach_excavator = np.zeros(self.trucks)
# 用于动态派车的矿卡集合
self.dynamic_truck_set = []
# 用于动态派车的挖机集合
self.dynamic_excavator_set = []
# 用于动态调度的卸载点集合
self.dynamic_dump_set = []
# 矿卡装载/卸载时间
# 矿卡最后装载/卸载时间
self.last_load_time = {}
self.last_unload_time = {}
# 相对矿卡装载/卸载时间
# 相对矿卡最后装载/卸载时间
self.relative_last_load_time = {}
self.relative_last_unload_time = {}
# 矿卡当前任务
......@@ -453,9 +482,34 @@ class TruckInfo(DeviceMap):
self.payload = np.zeros(self.trucks)
# 矿卡当前行程(第一列为出发地序号, 第二列为目的地序号)
self.truck_current_trip = np.full((self.trucks, 2), -1)
# 矿卡最后装载/卸载时间
self.last_load_time = {}
self.last_unload_time = {}
def get_truck_current_trip(self):
return self.truck_current_trip
def get_truck_current_task(self):
return self.truck_current_task
def get_truck_num(self):
return self.trucks
def get_truck_reach_dump(self):
return self.cur_truck_reach_dump
def get_truck_reach_excavator(self):
return self.cur_truck_reach_excavator
def get_dynamic_truck_set(self):
return self.dynamic_truck_set
def get_realative_last_load_time(self):
return self.relative_last_load_time
def get_realative_last_unload_time(self):
return self.relative_unlast_load_time
def get_payload(self):
return self.payload
# 更新矿卡当前任务
def update_truck_current_task(self):
......@@ -540,8 +594,8 @@ class TruckInfo(DeviceMap):
# 更新矿卡行程
def update_truck_trip(self):
com_time_area = self.walker.com_time_area
go_time_area = self.walker.go_time_area
com_time_area = self.walker.get_com_time_area()
go_time_area = self.walker.get_go_time_area()
# 初始化矿卡行程, -1代表备停区
self.truck_current_trip = np.full((self.trucks, 2), -1)
......@@ -647,61 +701,61 @@ class Dispatcher(DeviceMap):
self.truck = TruckInfo()
self.walker = WalkManage()
# 模拟挖机/卸产量(防止调度修改真实产量)
self.sim_dump_real_mass = np.zeros(self.dump.dumps)
self.sim_excavator_real_mass = np.zeros(self.excavator.excavators)
# 模拟挖机/卸载设备产量(防止调度修改真实产量)
self.sim_dump_real_mass = np.zeros(self.dump.get_dump_num())
self.sim_excavator_real_mass = np.zeros(self.excavator.get_excavator_num())
# 真实设备可用时间
self.cur_truck_reach_dump = np.zeros(self.truck.trucks)
self.cur_truck_reach_excavator = np.zeros(self.truck.trucks)
self.cur_excavator_ava_time = np.zeros(self.excavator.excavators)
self.cur_dump_ava_time = np.zeros(self.dump.dumps)
self.cur_truck_reach_dump = np.zeros(self.truck.get_truck_num())
self.cur_truck_reach_excavator = np.zeros(self.truck.get_truck_num())
self.cur_excavator_ava_time = np.zeros(self.excavator.get_excavator_num())
self.cur_dump_ava_time = np.zeros(self.dump.get_dump_num())
# 卡车完成装载及卸载时间(矿卡可用时间)
self.cur_truck_ava_time = np.zeros(self.truck.trucks)
self.cur_truck_ava_time = np.zeros(self.truck.get_truck_num())
# 模拟矿卡可用时间
self.sim_truck_ava_time = np.zeros(self.truck.trucks)
self.sim_truck_ava_time = np.zeros(self.truck.get_truck_num())
# 模拟各设备可用时间(防止调度修改真实产量)
self.sim_excavator_ava_time = np.zeros(self.excavator.excavators)
self.sim_dump_ava_time = np.zeros(self.dump.dumps)
# 挖机/卸点预计产量(包含正在驶往挖机/卸点那部分矿卡的载重)
self.pre_dump_real_mass = np.zeros(self.dump.dumps)
self.pre_excavator_real_mass = np.zeros(self.excavator.excavators)
self.sim_excavator_ava_time = np.zeros(self.excavator.get_excavator_num())
self.sim_dump_ava_time = np.zeros(self.dump.get_dump_num())
# 挖机/卸载设备预计产量(包含正在驶往挖机/卸载设备那部分矿卡的载重)
self.pre_dump_real_mass = np.zeros(self.dump.get_dump_num())
self.pre_excavator_real_mass = np.zeros(self.excavator.get_excavator_num())
# 维护一个矿卡调度表
self.Seq = [[] for _ in range(self.truck.trucks)]
self.Seq = [[] for _ in range(self.truck.get_truck_num())]
# 调度开始时间
self.start_time = datetime.now()
# self.relative_now_time = datetime.now() - self.start_time
# 下面是交通流调度部分
# 驶往挖机的实际车流
self.actual_goto_excavator_traffic_flow = np.zeros((self.dump.dumps, self.excavator.excavators))
# 驶往卸的实际车流
self.actual_goto_dump_traffic_flow = np.zeros((self.dump.dumps, self.excavator.excavators))
self.actual_goto_excavator_traffic_flow = np.zeros((self.dump.get_dump_num(), self.excavator.get_excavator_num()))
# 驶往卸载设备的实际车流
self.actual_goto_dump_traffic_flow = np.zeros((self.dump.get_dump_num(), self.excavator.get_excavator_num()))
# 驶往挖机的实际车次
self.goto_dump_truck_num = np.zeros((self.dump.dumps, self.excavator.excavators))
# 驶往卸的实际车次
self.goto_excavator_truck_num = np.zeros((self.dump.dumps, self.excavator.excavators))
self.goto_dump_truck_num = np.zeros((self.dump.get_dump_num(), self.excavator.get_excavator_num()))
# 驶往卸载设备的实际车次
self.goto_excavator_truck_num = np.zeros((self.dump.get_dump_num(), self.excavator.get_excavator_num()))
# 驶往挖机的理想车流
self.opt_goto_dump_traffic_flow = np.zeros((self.dump.dumps, self.excavator.excavators))
# 驶往卸的实际车流
self.opt_goto_excavator_traffic_flow = np.zeros((self.dump.dumps, self.excavator.excavators))
self.opt_goto_dump_traffic_flow = np.zeros((self.dump.get_dump_num(), self.excavator.get_excavator_num()))
# 驶往卸载设备的实际车流
self.opt_goto_excavator_traffic_flow = np.zeros((self.dump.get_dump_num(), self.excavator.get_excavator_num()))
# 更新矿卡预计抵达目的地时间
def update_truck_reach_time(self):
try:
excavators = self.excavator.excavators
dumps = self.dump.dumps
trucks = self.truck.trucks
excavators = self.excavator.get_excavator_num()
dumps = self.dump.get_dump_num()
trucks = self.truck.get_truck_num()
truck_current_task = self.truck.truck_current_task
truck_current_task = self.truck.get_truck_current_task()
truck_current_trip = self.truck.truck_current_trip
truck_current_trip = self.truck.get_truck_current_trip()
cur_truck_reach_excavator = self.truck.cur_truck_reach_excavator
cur_truck_reach_excavator = self.truck.get_truck_reach_excavator()
cur_truck_reach_dump = self.truck.cur_truck_reach_dump
cur_truck_reach_dump = self.truck.get_truck_reach_dump()
excavator_ava_ls = [[] for _ in range(excavators)]
dump_ava_ls = [[] for _ in range(dumps)]
......@@ -752,7 +806,7 @@ class Dispatcher(DeviceMap):
logger.error("挖机可用时间计算异常")
logger.error(es)
# 更新卸预计可用时间
# 更新卸载设备预计可用时间
def update_dump_ava_time(self, dump_ava_ls):
unloading_time = self.dump.get_unloading_time()
......@@ -771,20 +825,20 @@ class Dispatcher(DeviceMap):
unloading_time[dump_index]
self.cur_truck_ava_time[int(tmp[i][1])] = self.cur_dump_ava_time[dump_index]
# 若卸可用时间严重偏离,进行修正
# 若卸载设备可用时间严重偏离,进行修正
if abs(self.cur_dump_ava_time[dump_index] - now) > 60:
self.cur_dump_ava_time[dump_index] = now
if abs(self.cur_truck_ava_time[int(tmp[i][1])] - now) > 60:
self.cur_truck_ava_time[int(tmp[i][1])] = now
except Exception as es:
logger.error("卸可用时间计算异常")
logger.error("卸载设备可用时间计算异常")
logger.error(es)
# 更新实际交通流
def update_actual_traffic_flow(self):
truck_current_task = self.truck.truck_current_task
payload = self.truck.payload
truck_current_task = self.truck.get_truck_current_task()
payload = self.truck.get_payload()
for item in session_mysql.query(EquipmentPair).filter(EquipmentPair.createtime >= self.start_time).all():
dump_index = self.dump_uuid_to_index_dict[item.dump_id]
......@@ -810,40 +864,47 @@ class Dispatcher(DeviceMap):
((datetime.now() - self.start_time) / timedelta(hours=0, minutes=1,
seconds=0))
# 更新卸预计产量
# 更新卸载设备预计产量
def update_pre_unload_throughout(self):
truck_current_task = self.truck.get_truck_current_task()
payload = self.truck.get_payload()
try:
self.pre_dump_real_mass = copy.deepcopy(self.dump.cur_dump_real_mass)
for i in range(self.truck.trucks):
self.pre_dump_real_mass = copy.deepcopy(self.dump.get_dump_actual_mass())
for i in range(self.truck.get_truck_num()):
# task = self.truck_current_stage[i][0]
task = self.truck.truck_current_task[self.truck_index_to_uuid_dict[i]]
end_area_index = self.truck.truck_current_trip[i][1]
task = truck_current_task[self.truck_index_to_uuid_dict[i]]
end_area_index = self.truck.get_truck_current_trip()[i][1]
# 若矿卡正常行驶,需要将该部分载重计入实时产量
if task in heavy_task_set:
self.pre_dump_real_mass[end_area_index] = self.pre_dump_real_mass[end_area_index] + \
self.truck.payload[i]
self.pre_dump_real_mass[end_area_index] = self.pre_dump_real_mass[end_area_index] + payload[i]
else:
pass
except Exception as es:
logger.error("卸预计装载量计算异常")
logger.error("卸载设备预计装载量计算异常")
logger.error(es)
# 更新挖机预计产量
def update_pre_load_throughout(self):
truck_current_task = self.truck.get_truck_current_task()
payload = self.truck.get_payload()
try:
self.pre_excavator_real_mass = copy.deepcopy(self.excavator.cur_excavator_real_mass)
self.pre_excavator_real_mass = copy.deepcopy(self.excavator.get_excavator_actual_mass())
for i in range(self.truck.trucks):
# task = self.truck_current_stage[i][0]
task = self.truck.truck_current_task[self.truck_index_to_uuid_dict[i]]
end_area_index = self.truck.truck_current_trip[i][1]
task = truck_current_task[self.truck_index_to_uuid_dict[i]]
end_area_index = self.truck.get_truck_current_trip()[i][1]
# 若矿卡正常行驶,需要将该部分载重计入实时产量
if task in empty_task_set:
self.pre_excavator_real_mass[end_area_index] = self.pre_excavator_real_mass[end_area_index] + \
self.truck.payload[i]
payload[i]
else:
pass
except Exception as es:
logger.error("挖机/卸预计装载量计算异常")
logger.error("挖机/卸载设备预计装载量计算异常")
logger.error(es)
def period_update(self):
......@@ -852,7 +913,7 @@ class Dispatcher(DeviceMap):
self.load()
# 更新卸对象
# 更新卸载设备对象
self.dump.period_update()
# 更新挖机对象
......@@ -879,13 +940,13 @@ class Dispatcher(DeviceMap):
# 挖机可用时间
self.update_excavator_ava_time(excavator_reach_list)
# 卸可用时间
# 卸载设备可用时间
self.update_dump_ava_time(dump_reach_list)
# 挖机预计装载量
self.update_pre_load_throughout()
# 卸预计卸载量
# 卸载设备预计卸载量
self.update_pre_unload_throughout()
def sim_para_reset(self):
......@@ -895,7 +956,7 @@ class Dispatcher(DeviceMap):
self.sim_excavator_ava_time = copy.deepcopy(self.cur_excavator_ava_time)
self.sim_dump_ava_time = copy.deepcopy(self.cur_dump_ava_time)
# 电铲\卸载点产量重置
# 挖机\卸载设备产量重置
self.sim_dump_real_mass = copy.deepcopy(self.pre_dump_real_mass)
self.sim_excavator_real_mass = copy.deepcopy(self.pre_excavator_real_mass)
......@@ -904,21 +965,21 @@ class Dispatcher(DeviceMap):
# 矿卡对应序号
truck_index = self.truck_uuid_to_index_dict[truck_id]
# 矿卡行程
trip = self.truck.truck_current_trip[truck_index]
trip = self.truck.get_truck_current_trip()[truck_index]
# 矿卡当前任务
task = self.truck.truck_current_task[self.truck_index_to_uuid_dict[truck_index]]
task = self.truck.get_truck_current_task()[self.truck_index_to_uuid_dict[truck_index]]
# 挖机目标产量
excavator_target_mass = self.excavator.excavator_target_mass
excavator_target_mass = self.excavator.get_excavator_target_mass()
# 挖机装载时间
loading_time = self.excavator.loading_time
# 卸目标产量
dump_target_mass = self.dump.dump_target_mass
# 卸卸载时间
unloading_time = self.dump.unloading_time
loading_time = self.excavator.get_loading_time()
# 卸载设备目标产量
dump_target_mass = self.dump.get_dump_target_mass()
# 卸载设备卸载时间
unloading_time = self.dump.get_unloading_time()
# 路网信息
park_to_load_eq = self.walker.park_to_load_eq
go_time_eq = self.walker.go_time_eq
com_time_eq = self.walker.com_time_eq
park_to_load_eq = self.walker.get_park_to_load_eq()
go_time_eq = self.walker.get_o_time_eq()
com_time_eq = self.walker.get_com_time_eq()
now = float((datetime.now() - self.start_time) / timedelta(hours=0, minutes=1, seconds=0))
......@@ -932,8 +993,8 @@ class Dispatcher(DeviceMap):
if task == -2:
logger.info("矿卡状态:矿卡启动或故障恢复")
logger.info("矿卡行程:无")
logger.info(f'涉及电铲:{list(self.excavator_uuid_to_index_dict.keys())}')
logger.info(f'电铲饱和度:{(1 - self.sim_excavator_real_mass / excavator_target_mass)}')
logger.info(f'涉及挖机:{list(self.excavator_uuid_to_index_dict.keys())}')
logger.info(f'挖机饱和度:{(1 - self.sim_excavator_real_mass / excavator_target_mass)}')
logger.info(
f'行程时间:{(np.maximum(self.sim_excavator_ava_time, now + park_to_load_eq[0, :]) + loading_time - now)}')
logger.info(f'行驶时间:{park_to_load_eq[0, :] + loading_time}')
......@@ -949,32 +1010,32 @@ class Dispatcher(DeviceMap):
logger.info("矿卡状态:矿卡空载")
logger.info(f'矿卡行程:{self.dump_index_to_uuid_dict[trip[0]]}-{self.excavator_index_to_uuid_dict[trip[1]]}')
logger.info(f'涉及卸:{list(self.dump_uuid_to_index_dict.keys())}')
logger.info(f'卸饱和度:{(1 - self.sim_dump_real_mass / dump_target_mass)}')
logger.info(f'涉及卸载设备:{list(self.dump_uuid_to_index_dict.keys())}')
logger.info(f'卸载设备饱和度:{(1 - self.sim_dump_real_mass / dump_target_mass)}')
logger.info(
f'行程时间:{(np.maximum(self.sim_dump_ava_time, self.sim_truck_ava_time[truck_index] + go_time_eq[:, trip[1]]) + unloading_time - self.sim_truck_ava_time[truck_index])}')
logger.info(f'行驶时间:{go_time_eq[:, trip[1]] + unloading_time}')
# 卡车空载,计算下一次卸载点
target = np.argmax(10 * (1 - self.sim_dump_real_mass / dump_target_mass) /
(np.maximum(self.sim_dump_ava_time,
# self.sim_truck_reach_excavator[truck_index] + self.loading_time[trip[1]]
self.sim_truck_ava_time[truck_index]
+ go_time_eq[:, trip[1]]) + unloading_time
- self.sim_truck_ava_time[truck_index]))
# # 卡车空载,计算下一次卸载设备
# target = np.argmax(10 * (1 - self.sim_dump_real_mass / dump_target_mass) /
# (np.maximum(self.sim_dump_ava_time,
# # self.sim_truck_reach_excavator[truck_index] + self.loading_time[trip[1]]
# self.sim_truck_ava_time[truck_index]
# + go_time_eq[:, trip[1]]) + unloading_time
# - self.sim_truck_ava_time[truck_index]))
# try:
# assert self.actual_goto_dump_traffic_flow.shape == (self.excavators, self.dumps)
# assert self.opt_goto_dump_traffic_flow.shape == (self.excavators, self.dumps)
# except Exception as es:
# logger.warning(es)
# self.actual_goto_dump_traffic_flow = \
# np.array(self.actual_goto_dump_traffic_flow).reshape((self.excavators, self.dumps))
# self.opt_goto_dump_traffic_flow = \
# np.array(self.opt_goto_dump_traffic_flow).reshape((self.excavators, self.dumps))
#
# target = np.argmin(
# self.actual_goto_dump_traffic_flow[int(trip[1]), :] / self.opt_goto_dump_traffic_flow[int(trip[1]), :])
try:
assert self.actual_goto_dump_traffic_flow.shape == (self.excavators, self.dumps)
assert self.opt_goto_dump_traffic_flow.shape == (self.excavators, self.dumps)
except Exception as es:
logger.warning(es)
self.actual_goto_dump_traffic_flow = \
np.array(self.actual_goto_dump_traffic_flow).reshape((self.excavators, self.dumps))
self.opt_goto_dump_traffic_flow = \
np.array(self.opt_goto_dump_traffic_flow).reshape((self.excavators, self.dumps))
target = np.argmin(
self.actual_goto_dump_traffic_flow[int(trip[1]), :] / self.opt_goto_dump_traffic_flow[int(trip[1]), :])
logger.info(f'目的地:{self.dump_index_to_uuid_dict[target]}')
......@@ -982,8 +1043,8 @@ class Dispatcher(DeviceMap):
logger.info("矿卡状态:矿卡重载")
logger.info(f'矿卡行程:{self.excavator_index_to_uuid_dict[trip[0]]}-{self.dump_index_to_uuid_dict[trip[1]]}')
logger.info(f'涉及卸:{list(self.excavator_uuid_to_index_dict.keys())}')
logger.info(f'卸饱和度:{(1 - self.sim_excavator_real_mass / excavator_target_mass)}')
logger.info(f'涉及卸载设备:{list(self.excavator_uuid_to_index_dict.keys())}')
logger.info(f'卸载设备饱和度:{(1 - self.sim_excavator_real_mass / excavator_target_mass)}')
logger.info(
f'行程时间:{(np.maximum(self.sim_excavator_ava_time, self.sim_truck_ava_time[truck_index] + com_time_eq[trip[1], :]) + loading_time - self.sim_truck_ava_time[truck_index])}')
logger.info(f'行驶时间:{com_time_eq[trip[1], :] + loading_time}')
......@@ -1015,14 +1076,14 @@ class Dispatcher(DeviceMap):
def schedule_construct(self):
# 读取所需信息
trucks = self.truck.trucks
truck_current_trip = self.truck.truck_current_trip
truck_current_task = self.truck.truck_current_task
payload = self.truck.payload
unloading_time = self.dump.unloading_time
loading_time = self.excavator.loading_time
go_time_area = self.walker.go_time_area
com_time_area = self.walker.com_time_area
trucks = self.truck.get_truck_num()
truck_current_trip = self.truck.get_truck_current_trip()
truck_current_task = self.truck.get_truck_current_task()
payload = self.truck.get_payload()
unloading_time = self.dump.get_unloading_time()
loading_time = self.excavator.get_loading_time()
go_time_area = self.walker.get_go_time_area()
com_time_area = self.walker.get_com_time_area()
# Seq初始化
Seq = [[truck_current_trip[i][1], -1] for i in range(trucks)]
......@@ -1067,7 +1128,7 @@ class Dispatcher(DeviceMap):
# 更新变量,预计产量更新
self.sim_dump_real_mass[target_eq_index] = self.sim_dump_real_mass[target_eq_index] + \
payload[truck]
# 预计卸可用时间更新
# 预计卸载设备可用时间更新
self.sim_dump_ava_time[target_eq_index] = (
max(
self.sim_dump_ava_time[target_eq_index],
......@@ -1101,7 +1162,7 @@ class Dispatcher(DeviceMap):
try:
record = {"truckId": self.truck_index_to_uuid_dict[i]}
task = self.truck.truck_current_task[self.truck_index_to_uuid_dict[i]]
task = self.truck.get_truck_current_task()[self.truck_index_to_uuid_dict[i]]
if task in empty_task_set:
item = session_mysql.query(Dispatch).filter_by(
dump_id=self.dump_index_to_uuid_dict[Seq[i][1]], isauto=1, isdeleted=0).first()
......
......@@ -9,7 +9,6 @@
# 数据库设备, redis设置, 日志设置
from tables import *
from urllib.parse import quote
import logging.handlers
......
......@@ -124,7 +124,7 @@ def update_deveices_map(unload_area_uuid_to_index_dict, load_area_uuid_to_index_
load_area_uuid_to_index_dict[load_area_id]
excavator_num = excavator_num + 1
if excavator_num < 1 or dump_num < 1:
raise Exception("无动态派车计划可用-动态派车挖机/卸映射失败")
raise Exception("无动态派车计划可用-动态派车挖机/卸载设备映射失败")
except Exception as es:
logger.warning(es)
......@@ -191,7 +191,7 @@ def update_autodisp_excavator():
for item in session_mysql.query(Dispatch).filter_by(isdeleted=0, isauto=1).all():
dynamic_excavator_list.append(item.exactor_id)
if len(dynamic_excavator_list) < 1:
raise Exception("无动态派车计划可用-动态派车挖机/卸集合读取异常")
raise Exception("无动态派车计划可用-动态派车挖机/卸载设备集合读取异常")
except Exception as es:
logger.warning(es)
......@@ -205,7 +205,7 @@ def update_autodisp_dump():
for item in session_mysql.query(Dispatch).filter_by(isdeleted=0, isauto=1).all():
dynamic_dump_list.append(item.dump_id)
if len(dynamic_dump_list) < 1:
raise Exception("无动态派车计划可用-动态派车挖机/卸集合读取异常")
raise Exception("无动态派车计划可用-动态派车挖机/卸载设备集合读取异常")
except Exception as es:
logger.warning(es)
return dynamic_dump_list
......
......@@ -209,6 +209,16 @@ class EquipmentPair(Base):
self.isdeleted = isdeleted
self.createtime = createtime
class Lane(Base):
# 表的名字
__tablename__ = 'Geo_Node'
Id = Column(VARCHAR(36), primary_key=True)
LaneIds = Column(VARCHAR(100))
def __init__(self, Id, LaneIds):
self.Id = Id
self.LaneIds = LaneIds
class Dispatch(Base):
# 表的名字:
__tablename__ = 'sys_dispatch_setting'
......
......@@ -18,35 +18,39 @@ from settings import *
# 需要提供的值
# traffic_programme_para.excavator_strength[excavator_index] = 200 # 挖机最大装载能力,单位吨/小时
# traffic_programme_para.dump_strength[dump_index] = 200 # 卸载设备最大卸载能力,单位吨/小时
# traffic_programme_para.grade_loading_array[excavator_index] = 100 # 挖机装载物料品位
# traffic_programme_para.excavator_priority_coefficient[excavator_index] = 1 # 挖机优先级
# traffic_programme_para.dump_strength[dump_index] = 200 # 卸载设备最大卸载能力,单位吨/小时
# traffic_programme_para.dump_priority_coefficient[dump_index] = 1 # 卸载设备优先级
# traffic_programme_para.grade_upper_dump_array[dump_index] = 100 # 卸点品位上限
# traffic_programme_para.grade_lower_dump_array[dump_index] = 100 # 卸点品位下限
# traffic_programme_para.dump_priority_coefficient[dump_index] = 1 # 卸载设备优先级
class TrafficProgPara(object):
def __init__(self, num_of_load_area, num_of_unload_area, num_of_excavator, num_of_dump):
self.load_area_uuid_to_ref_id_dict = {} # 用于保存装载点uuid到id的映射
self.load_area_ref_id_to_uuid_dict = {} # 用于保存装载点id到uuid的映射
self.unload_area_uuid_to_ref_id_dict = {} # 用于保存卸载点uuid到id的映射
self.unload_area_ref_id_to_uuid_dict = {} # 用于保存卸载点id到uuid的映射
self.load_area_uuid_to_index_dict = {} # 用于保存装载点uuid到id的映射
self.load_area_index_to_uuid_dict = {} # 用于保存装载点id到uuid的映射
self.unload_area_uuid_to_index_dict = {} # 用于保存卸载点uuid到id的映射
self.unload_area_index_to_uuid_dict = {} # 用于保存卸载点id到uuid的映射
self.excavator_uuid_to_ref_id_dict = {} # 用于保存挖机uuid到id的映射
self.excavator_ref_id_to_uuid_dict = {} # 用于保存挖机id到uuid的映射
self.dump_uuid_to_ref_id_dict = {} # 用于保存卸点uuid到id的映射
self.dump_ref_id_to_uuid_dict = {} # 用于保存卸点id到uuid的映射
self.excavator_uuid_to_index_dict = {} # 用于保存挖机uuid到id的映射
self.excavator_index_to_uuid_dict = {} # 用于保存挖机id到uuid的映射
self.dump_uuid_to_index_dict = {} # 用于保存卸点uuid到id的映射
self.dump_index_to_uuid_dict = {} # 用于保存卸点id到uuid的映射
self.dump_uuid_to_unload_area_uuid_dict = {} # 用于保存卸点与卸载区的绑定关系(uuid)
self.excavator_uuid_to_load_area_uuid_dict = {} # 用于保存挖机与装载区的绑定关系(uuid)
self.dump_ref_id_to_unload_area_ref_id_dict = {} # 用于保存卸点与卸载区的绑定关系(id)
self.excavator_ref_id_to_load_area_ref_id_dict = {} # 用于保存挖机与装载区的绑定关系(id)
self.dump_index_to_unload_area_index_dict = {} # 用于保存卸点与卸载区的绑定关系(id)
self.excavator_index_to_load_area_index_dict = {} # 用于保存挖机与装载区的绑定关系(id)
self.excavator_strength = np.zeros(num_of_excavator) # 用于保存电铲的工作强度,单位是t/h
self.excavator_priority_coefficient = np.zeros(num_of_excavator) # 每个电铲的优先级系数
self.grade_loading_array = np.zeros(num_of_excavator) # 用于保存电铲挖掘矿石的品位
self.excavator_strength = np.zeros(num_of_excavator) # 用于保存挖机的工作强度,单位是t/h
self.excavator_priority_coefficient = np.zeros(num_of_excavator) # 每个挖机的优先级系数
self.grade_loading_array = np.zeros(num_of_excavator) # 用于保存挖机挖掘矿石的品位
self.dump_strength = np.zeros(num_of_dump) # 卸载点的工作强度,单位是t/h
self.dump_priority_coefficient = np.zeros(num_of_dump) # 每个卸载点的优先级系数
self.goto_unload_area_factor = np.full((num_of_load_area, num_of_unload_area), 10, dtype=float) # 卸载道路的运输系数
......@@ -79,16 +83,16 @@ def extract_excavator_info(traffic_programme_para):
for dispatch in session_mysql.query(Dispatch).filter_by(isdeleted=0, isauto=1).all():
excavator_id = dispatch.exactor_id
load_area_id = dispatch.load_area_id
if excavator_id not in traffic_programme_para.excavator_uuid_to_ref_id_dict:
if excavator_id not in traffic_programme_para.excavator_uuid_to_index_dict:
# excavator_uuid <-> excavator_uuid
traffic_programme_para.excavator_uuid_to_ref_id_dict[excavator_id] = excavator_index
traffic_programme_para.excavator_ref_id_to_uuid_dict[excavator_index] = excavator_id
traffic_programme_para.excavator_uuid_to_index_dict[excavator_id] = excavator_index
traffic_programme_para.excavator_index_to_uuid_dict[excavator_index] = excavator_id
# excavator_uuid -> load_area_uuid
traffic_programme_para.excavator_uuid_to_load_area_uuid_dict[excavator_id] = load_area_id
# excavator_id -> load_area_id
traffic_programme_para.excavator_ref_id_to_load_area_ref_id_dict[
traffic_programme_para.excavator_uuid_to_ref_id_dict[excavator_id]] = \
traffic_programme_para.load_area_uuid_to_ref_id_dict[load_area_id]
traffic_programme_para.excavator_index_to_load_area_index_dict[
traffic_programme_para.excavator_uuid_to_index_dict[excavator_id]] = \
traffic_programme_para.load_area_uuid_to_index_dict[load_area_id]
traffic_programme_para.excavator_strength[excavator_index] = 300 # 挖机最大装载能力,单位吨/小时
traffic_programme_para.grade_loading_array[excavator_index] = 100 # 挖机装载物料品位
......@@ -103,14 +107,14 @@ def extract_dump_info(traffic_programme_para):
dump_id = dispatch.dump_id
if dump_id not in traffic_programme_para.dump_uuid_to_unload_area_uuid_dict:
# dump_uuid <-> dump_id
traffic_programme_para.dump_uuid_to_ref_id_dict[dump_id] = dump_index
traffic_programme_para.dump_ref_id_to_uuid_dict[dump_index] = dump_id
traffic_programme_para.dump_uuid_to_index_dict[dump_id] = dump_index
traffic_programme_para.dump_index_to_uuid_dict[dump_index] = dump_id
# dump_uuid -> unload_area_uuid
traffic_programme_para.dump_uuid_to_unload_area_uuid_dict[dump_id] = unload_area_id
# dump_id -> unload_area_id
traffic_programme_para.dump_ref_id_to_unload_area_ref_id_dict[
traffic_programme_para.dump_uuid_to_ref_id_dict[dump_id]] = \
traffic_programme_para.unload_area_uuid_to_ref_id_dict[unload_area_id]
traffic_programme_para.dump_index_to_unload_area_index_dict[
traffic_programme_para.dump_uuid_to_index_dict[dump_id]] = \
traffic_programme_para.unload_area_uuid_to_index_dict[unload_area_id]
traffic_programme_para.dump_strength[dump_index] = 300 # 卸载设备最大卸载能力,单位吨/小时
traffic_programme_para.grade_upper_dump_array[dump_index] = 100 # 卸点品位上限
......@@ -129,13 +133,13 @@ def extract_walk_time_info(traffic_programme_para):
load_area_id = str(walk_time.load_area_id)
unload_area_id = str(walk_time.unload_area_id)
if load_area_id not in traffic_programme_para.load_area_uuid_to_ref_id_dict:
traffic_programme_para.load_area_uuid_to_ref_id_dict[load_area_id] = load_area_index
traffic_programme_para.load_area_ref_id_to_uuid_dict[load_area_index] = load_area_id
if load_area_id not in traffic_programme_para.load_area_uuid_to_index_dict:
traffic_programme_para.load_area_uuid_to_index_dict[load_area_id] = load_area_index
traffic_programme_para.load_area_index_to_uuid_dict[load_area_index] = load_area_id
load_area_index = load_area_index + 1
if unload_area_id not in traffic_programme_para.unload_area_uuid_to_ref_id_dict:
traffic_programme_para.unload_area_uuid_to_ref_id_dict[unload_area_id] = unload_area_index
traffic_programme_para.unload_area_ref_id_to_uuid_dict[unload_area_index] = unload_area_id
if unload_area_id not in traffic_programme_para.unload_area_uuid_to_index_dict:
traffic_programme_para.unload_area_uuid_to_index_dict[unload_area_id] = unload_area_index
traffic_programme_para.unload_area_index_to_uuid_dict[unload_area_index] = unload_area_id
unload_area_index = unload_area_index + 1
# 路网信息读取
......@@ -143,8 +147,8 @@ def extract_walk_time_info(traffic_programme_para):
load_area_id = str(walk_time.load_area_id)
unload_area_id = str(walk_time.unload_area_id)
# 将uuid转为id
load_area_index = traffic_programme_para.load_area_uuid_to_ref_id_dict[load_area_id]
unload_area_index = traffic_programme_para.unload_area_uuid_to_ref_id_dict[unload_area_id]
load_area_index = traffic_programme_para.load_area_uuid_to_index_dict[load_area_id]
unload_area_index = traffic_programme_para.unload_area_uuid_to_index_dict[unload_area_id]
# 运输路线距离
traffic_programme_para.goto_load_area_distance[unload_area_index][load_area_index] = walk_time.to_load_distance
......@@ -153,7 +157,7 @@ def extract_walk_time_info(traffic_programme_para):
# 卸载道路上,每运输1吨货物需要一辆卡车运行时长,等于(该卸载道路上车辆平均运行时长/卡车平均实际装载量)
# 单位为辆小时/吨
# i代表第i个电铲,j代表第j个卸载点
# i代表第i个挖机,j代表第j个卸载点
# walktime_goto_unload_point单位是秒,需要除以3600,转成小时
traffic_programme_para.goto_load_area_factor[unload_area_index][load_area_index] = \
(60 / 1000 * walk_time.to_load_distance / traffic_programme_para.empty_speed) / traffic_programme_para.payload
......@@ -161,14 +165,14 @@ def extract_walk_time_info(traffic_programme_para):
# 装载道路上,每提供1吨的装载能力需要一辆卡车运行时长,等于(该装载道路上车辆平均运行时长/卡车平均装载能力)
# 单位为辆小时/吨
# i代表第i个卸载点,j代表第j个电铲
# i代表第i个卸载点,j代表第j个挖机
# walktime_goto_excavator单位是秒,需要除以3600,转成小时
traffic_programme_para.goto_unload_area_factor[load_area_index][unload_area_index] = \
(60 / 1000 * walk_time.to_unload_distance / traffic_programme_para.heavy_speed) / traffic_programme_para.payload
# / traffic_programme_para.avg_goto_excavator_weight[unload_area_index][load_area_index]
# 从数据库中读取电铲和卸载点相关参数,并将线性规划所用参数保存在TrafficProgPara类中
# 从数据库中读取挖机和卸载点相关参数,并将线性规划所用参数保存在TrafficProgPara类中
def traffic_programme_para_init(num_of_load_area, num_of_unload_area, num_of_excavator, num_of_dump):
# 初始化流量规划参数类
traffic_programme_para = TrafficProgPara(num_of_load_area, num_of_unload_area, num_of_excavator, num_of_dump)
......@@ -192,8 +196,8 @@ def traffic_programme_para_init(num_of_load_area, num_of_unload_area, num_of_exc
for i in range(num_of_excavator):
for j in range(num_of_dump):
# 查找挖机绑定的装载区, 卸载设备绑定的卸载区
load_area_index = traffic_programme_para.excavator_ref_id_to_load_area_ref_id_dict[i]
unload_area_index = traffic_programme_para.dump_ref_id_to_unload_area_ref_id_dict[j]
load_area_index = traffic_programme_para.excavator_index_to_load_area_index_dict[i]
unload_area_index = traffic_programme_para.dump_index_to_unload_area_index_dict[j]
# 逻辑道路因子赋值, 来自实际道路因子
traffic_programme_para.goto_excavator_factor[j][i] = \
......@@ -202,7 +206,7 @@ def traffic_programme_para_init(num_of_load_area, num_of_unload_area, num_of_exc
traffic_programme_para.goto_unload_point_factor[i][j] = \
traffic_programme_para.goto_unload_area_factor[load_area_index][unload_area_index]
# 每条卸载道路的优先级,等于电铲的优先级乘以卸载点的优先级
# 每条卸载道路的优先级,等于挖机的优先级乘以卸载点的优先级
traffic_programme_para.priority_coefficient[i][j] = traffic_programme_para.excavator_priority_coefficient[i] \
* traffic_programme_para.dump_priority_coefficient[j]
......@@ -211,7 +215,7 @@ def traffic_programme_para_init(num_of_load_area, num_of_unload_area, num_of_exc
traffic_programme_para.goto_load_area_distance[unload_area_index][load_area_index]
traffic_programme_para.goto_dump_distance[i][j] = \
traffic_programme_para.goto_load_area_distance[load_area_index][unload_area_index]
traffic_programme_para.goto_unload_area_distance[load_area_index][unload_area_index]
return traffic_programme_para
......@@ -222,13 +226,13 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
max_unload_weigh_alg_flag, truck_total_num,
goto_excavator_dis, goto_dump_dis, min_throughout,
grade_lower_array=None, grade_upper_array=None):
row = len(coefficient) # 代表电铲的个数,第i行代表第i台电铲
row = len(coefficient) # 代表挖机的个数,第i行代表第i台挖机
col = len(coefficient[0]) # 代表卸载点的个数,第j行代表第j个卸载点
# prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)
# 卸载道路的流量,单位是吨/小时,i代表起点为第i个电铲,j代表终点为第j个卸载点
# 卸载道路的流量,单位是吨/小时,i代表起点为第i个挖机,j代表终点为第j个卸载点
var_x = [[pulp.LpVariable('x{0}{1}'.format(i, j), lowBound=0) for j in range(col)] for i in range(row)]
# 装载道路的流量,单位是吨/小时,i代表起点为第i个卸载点,j代表终点为第j个电铲
# 装载道路的流量,单位是吨/小时,i代表起点为第i个卸载点,j代表终点为第j个挖机
var_y = [[pulp.LpVariable('y{0}{1}'.format(i, j), lowBound=0) for j in range(row)] for i in range(col)]
flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]
......@@ -259,7 +263,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
pulp.lpSum(load_truck_totla_num_array) <= truck_total_num)
# 最大工作强度约束
# 约束每个电铲的工作强度
# 约束每个挖机的工作强度
for i in range(row):
prob += (pulp.lpSum(var_x[i]) <= b_excavator[i])
# 约束每个卸载点的工作强度
......@@ -268,7 +272,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
'''
# 车流基尔霍夫定理约束
# 进入电铲和从电铲出去的车辆个数需要相同
# 进入挖机和从挖机出去的车辆个数需要相同
for i in range(row):
prob += (pulp.lpSum(unload_truck_total_num_array[i]) == pulp.lpSum(load_truck_totla_num_array[:,i]))
# 从装载点离开和进来的车辆个数需要相同
......@@ -285,7 +289,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
prob += (pulp.lpSum((np.array(var_y))[j]) <= pulp.lpSum((np.array(var_x))[:, j]))
# 矿石品位约束卸载
# 去往卸载点的流量使用矩阵乘法乘以每个电铲处矿石的品位,得到每个卸载点的矿石品位总和
# 去往卸载点的流量使用矩阵乘法乘以每个挖机处矿石的品位,得到每个卸载点的矿石品位总和
grade_array = np.dot(grade_loading_array, var_x)
for j in range(col):
sum_traffic_unload = pulp.lpSum((np.array(var_x))[:, j])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment