Commit 7573aef2 authored by Allvey's avatar Allvey

挖机/卸点优先级

路网物料禁止 模式切换 锁定禁止规则
parent d22b9d9f
......@@ -42,6 +42,8 @@ class DumpInfo(WalkManage):
self.exit_time = np.zeros(self.dynamic_dump_num)
# 卸载点物料类型
self.dump_material = {}
# 卸点优先级
self.dump_priority_coefficient = np.ones(self.dynamic_dump_num)
# 初始化读取映射及路网
self.period_map_para_load()
......@@ -65,6 +67,17 @@ class DumpInfo(WalkManage):
def get_dynamic_dump_set(self):
return self.dynamic_dump_set
def get_unloading_task_time(self):
unloading_time = self.unloading_time
dump_entrance_time = self.entrance_time
dump_exit_time = self.exit_time
unloading_task_time = unloading_time + dump_entrance_time + dump_exit_time
return unloading_task_time
# 更新卸载设备卸载时间
def update_dump_unloadtime(self):
self.unloading_time = np.zeros(self.dynamic_dump_num)
......@@ -121,18 +134,6 @@ class DumpInfo(WalkManage):
self.entrance_time[self.dump_uuid_to_index_dict[dump_id]] = 0.50
self.exit_time[self.dump_uuid_to_index_dict[dump_id]] = 0.50
# 读取卸载任务时间
def get_unloading_task_time(self):
unloading_time = self.unloading_time
dump_entrance_time = self.entrance_time
dump_exit_time = self.exit_time
unloading_task_time = unloading_time + dump_entrance_time + dump_exit_time
return unloading_task_time
# 更新卸载设备实际卸载量
def update_actual_unload_thoughout(self):
self.cur_dump_real_mass = np.zeros(self.dynamic_dump_num)
......@@ -156,7 +157,12 @@ class DumpInfo(WalkManage):
for dump_id in dynamic_dump_set:
unload_area_id = session_mysql.query(Dispatch).filter_by(dump_id=dump_id).first().unload_area_id
dump_material_id = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().Material
self.dump_material[dump_id] = dump_material_id
self.dump_material[dump_id] = dump_material_id\
def update_dump_priority(self):
for dump_id in dynamic_dump_set:
item = session_mysql.query(Equipment).filter_by(id=dump_id).first()
self.dump_priority_coefficient[self.dump_uuid_to_index_dict[dump_id]] += item.priority
def para_period_update(self):
......@@ -169,11 +175,6 @@ class DumpInfo(WalkManage):
self.period_walk_para_load()
# # 初始化卸载设备可用时间
# self.cur_dump_ava_time = np.full(self.dynamic_dump_num,
# (datetime.now() - self.start_time) / timedelta(hours=0, minutes=1,
# seconds=0))
# 用于动态调度的卸载设备
self.dynamic_dump_set = set(update_autodisp_dump())
......@@ -182,14 +183,17 @@ class DumpInfo(WalkManage):
# 计算平均卸载时间
self.update_dump_unloadtime()
# 计算平均进出场时间
self.update_dump_entrance_exit_time()
# 计算实时卸载量
self.update_actual_unload_thoughout()
# 卸载目标产量
self.dump_target_mass = np.full(self.dynamic_dump_num, dump_target_mass)
# 更新卸点物料
self.update_dump_material()
# # 同步虚拟卸载量
# self.sim_dump_real_mass = copy.deepcopy(self.cur_dump_real_mass)
# 更新设备优先级
self.update_dump_priority()
# # 计算卸载设备预估产量
# self.update_pre_unload_throughout()
\ No newline at end of file
# 卸载目标产量
self.dump_target_mass = np.full(self.dynamic_dump_num, dump_target_mass)
\ No newline at end of file
......@@ -42,6 +42,10 @@ class ExcavatorInfo(WalkManage):
self.exit_time = np.zeros(self.dynamic_excavator_num)
# 挖机对应物料类型
self.excavator_material = {}
# 挖机设备优先级
self.excavator_priority_coefficient = np.ones(dynamic_excavator_num)
# 挖机物料优先级
self.excavator_material_priority = np.ones(dynamic_excavator_num)
# 初始化读取映射及路网
self.period_map_para_load()
......@@ -50,22 +54,6 @@ class ExcavatorInfo(WalkManage):
# 参数初始化
self.para_period_update()
# def period_map_para_load(self):
# # 关系映射
# self.excavator_uuid_to_index_dict = device_map.excavator_uuid_to_index_dict
# self.dump_uuid_to_index_dict = device_map.dump_uuid_to_index_dict
# self.excavator_index_to_uuid_dict = device_map.excavator_index_to_uuid_dict
# self.dump_index_to_uuid_dict = device_map.dump_index_to_uuid_dict
#
# self.dump_uuid_to_unload_area_uuid_dict = device_map.dump_uuid_to_unload_area_uuid_dict
# self.excavator_uuid_to_load_area_uuid_dict = device_map.excavator_uuid_to_load_area_uuid_dict
# self.excavator_index_to_load_area_index_dict = device_map.excavator_index_to_load_area_index_dict
# self.dump_index_to_unload_area_index_dict = device_map.dump_index_to_unload_area_index_dict
#
# def period_walk_para_load(self):
# self.truck_uuid_to_index_dict = device_map.truck_uuid_to_index_dict
# self.truck_index_to_uuid_dict = device_map.truck_index_to_uuid_dict
def get_loading_time(self):
return self.loading_time
......@@ -183,6 +171,26 @@ class ExcavatorInfo(WalkManage):
excavator_material_id = session_postgre.query(DiggingWorkArea).filter_by(Id=load_area_id).first().Material
self.excavator_material[excavator_id] = excavator_material_id
def update_excavator_priority(self):
for excavator_id in dynamic_excavator_set:
item = session_mysql.query(Equipment).filter_by(id=excavator_id).first()
self.excavator_priority_coefficient[self.excavator_uuid_to_index_dict[excavator_id]] = item.priority + 1
# 物料优先级控制
rule = 1
rule7 = session_mysql.query(DispatchRule).filter_by(id=7).first()
material_priority_use = rule7.disabled
if material_priority_use == 0:
rule = rule7.rule_weight
if rule == 0:
if session_mysql.query(Material).filter_by(id=self.excavator_material[excavator_id]).first().name == '土':
self.excavator_material_priority[self.excavator_uuid_to_index_dict[excavator_id]] = 5
elif rule == 2:
if session_mysql.query(Material).filter_by(id=self.excavator_material[excavator_id]).first().name == '煤':
self.excavator_material_priority[self.excavator_uuid_to_index_dict[excavator_id]] = 5
def para_period_update(self):
# print("Excavator update!")
......@@ -210,13 +218,12 @@ class ExcavatorInfo(WalkManage):
# 计算实时装载量
self.update_actual_load_throughout()
# 更新挖机物料
self.update_excavator_material()
# 更新挖机优先级
# 挖机目标产量
self.excavator_target_mass = np.full(
self.dynamic_excavator_num, excavator_target_mass
)
# # 同步挖机虚拟装载量
# self.sim_excavator_real_mass = copy.deepcopy(self.cur_excavator_real_mass)
# # 计算卸载设备预估产量
# self.update_pre_load_throughout()
\ No newline at end of file
......@@ -61,14 +61,14 @@ class TruckInfo(WalkManage):
# 矿卡卸点排斥关系
self.truck_dump_exclude = {}
# 排斥关系modify
self.excavator_exclude_modify = None
self.excavator_exclude_modify = np.zeros(self.dynamic_truck_num)
# 矿卡优先级
self.truck_priority = np.ones(self.dynamic_truck_num)
# 矿卡绑定物料
self.truck_material_bind = {}
# 矿卡绑定物料modify
self.dump_material_bind_modify = None
self.excavator_material_bind_modify = None
self.dump_material_bind_modify = np.zeros(self.dynamic_truck_num)
self.excavator_material_bind_modify = np.zeros(self.dynamic_truck_num)
# 引入对象
self.dump = DumpInfo()
self.excavator = ExcavatorInfo()
......@@ -78,29 +78,6 @@ class TruckInfo(WalkManage):
self.para_period_update()
# def period_map_para_load(self):
# # 关系映射
# self.excavator_uuid_to_index_dict = device_map.excavator_uuid_to_index_dict
# self.dump_uuid_to_index_dict = device_map.dump_uuid_to_index_dict
# self.excavator_index_to_uuid_dict = device_map.excavator_index_to_uuid_dict
# self.dump_index_to_uuid_dict = device_map.dump_index_to_uuid_dict
#
# self.dump_uuid_to_unload_area_uuid_dict = device_map.dump_uuid_to_unload_area_uuid_dict
# self.excavator_uuid_to_load_area_uuid_dict = device_map.excavator_uuid_to_load_area_uuid_dict
# self.excavator_index_to_load_area_index_dict = device_map.excavator_index_to_load_area_index_dict
# self.dump_index_to_unload_area_index_dict = device_map.dump_index_to_unload_area_index_dict
#
# self.truck_uuid_to_index_dict = device_map.truck_uuid_to_index_dict
# self.truck_index_to_uuid_dict = device_map.truck_index_to_uuid_dict
# def period_walk_para_load(self):
#
# self.walk_time_to_excavator = walk_manage.walk_time_to_excavator
# self.walk_time_to_dump = walk_manage.walk_time_to_dump
# self.walk_time_park_to_excavator = walk_manage.walk_time_park_to_excavator
# self.walk_time_to_load_area = walk_manage.walk_time_to_load_area
# self.walk_time_to_unload_area = walk_manage.walk_time_to_unload_area
def get_truck_current_trip(self):
return self.truck_current_trip
......@@ -343,47 +320,50 @@ class TruckInfo(WalkManage):
logger.error("读取矿卡有效载重异常-矿卡型号信息缺失")
logger.error(es)
print(self.payload)
def update_truck_priority(self):
self.truck_priority = np.zeros(self.dynamic_truck_num)
for truck_id in dynamic_truck_set:
item = session_mysql.query(Equipment).filter_by(id=truck_id).first()
truck_index = self.truck_uuid_to_index_dict[truck_id]
if item.priority == 0:
self.truck_priority[truck_index] = 2
elif item.priority == 1:
self.truck_priority[truck_index] = 1.5
elif item.priority == 2:
self.truck_priority[truck_index] = 1
elif item.priority == 3:
self.truck_priority[truck_index] = 0.5
self.truck_priority = np.full(self.dynamic_truck_num, 0)
rule6 = session_mysql.query(DispatchRule).filter_by(id=6).first()
if rule6.disabled == 0:
for truck_id in dynamic_truck_set:
item = session_mysql.query(Equipment).filter_by(id=truck_id).first()
truck_index = self.truck_uuid_to_index_dict[truck_id]
if item.priority == 0:
self.truck_priority[truck_index] = 0
elif item.priority == 1:
self.truck_priority[truck_index] = 2
elif item.priority == 2:
self.truck_priority[truck_index] = 5
elif item.priority == 3:
self.truck_priority[truck_index] = 10
def update_truck_dump_area_bind(self):
try:
self.truck_dump_bind = {}
for dump_area in session_postgre.query(DumpArea).all():
if dump_area.BindList is not None:
for truck_name in dump_area.BindList:
self.truck_dump_bind[truck_name_to_uuid_dict[truck_name]] = str(
dump_area.Id
)
rule5 = session_mysql.query(DispatchRule).filter_by(id=5).first()
if rule5.disabled == 0:
self.truck_dump_bind = {}
for dump_area in session_postgre.query(DumpArea).all():
if dump_area.BindList is not None:
for truck_name in dump_area.BindList:
self.truck_dump_bind[truck_name_to_uuid_dict[truck_name]] = str(
dump_area.Id
)
except Exception as es:
logger.error("矿卡-卸载区域绑定关系读取异常")
logger.error(es)
def update_truck_excavator_bind(self):
try:
self.truck_excavator_bind = {}
for excavator_id in dynamic_excavator_set:
item = session_mysql.query(Equipment).filter_by(id=excavator_id).first()
if item.bind_list is not None:
for truck_name in json.loads(item.bind_list):
self.truck_excavator_bind[
truck_name_to_uuid_dict[truck_name]
] = excavator_id
rule5 = session_mysql.query(DispatchRule).filter_by(id=5).first()
if rule5.disabled == 0:
self.truck_excavator_bind = {}
for excavator_id in dynamic_excavator_set:
item = session_mysql.query(Equipment).filter_by(id=excavator_id).first()
if item.bind_list is not None:
for truck_name in json.loads(item.bind_list):
self.truck_excavator_bind[
truck_name_to_uuid_dict[truck_name]
] = excavator_id
except Exception as es:
logger.error("矿卡-挖机绑定关系读取异常")
logger.error(es)
......@@ -397,21 +377,23 @@ class TruckInfo(WalkManage):
)
try:
for excavator_id in dynamic_excavator_set:
item = (
session_mysql.query(Equipment)
.filter_by(id=excavator_id, only_allowed=1)
.first()
)
if item is not None:
for truck_id in dynamic_truck_set:
if truck_uuid_to_name_dict[truck_id] not in item.bind_list:
self.truck_excavator_exclude[truck_id] = excavator_id
self.excavator_exclude_modify[
self.truck_uuid_to_index_dict[truck_id]
][
self.excavator_uuid_to_index_dict[excavator_id]
] = 1000000
rule5 = session_mysql.query(DispatchRule).filter_by(id=5).first()
if rule5.disabled == 0:
for excavator_id in dynamic_excavator_set:
item = (
session_mysql.query(Equipment)
.filter_by(id=excavator_id, only_allowed=1)
.first()
)
if item is not None:
for truck_id in dynamic_truck_set:
if truck_uuid_to_name_dict[truck_id] not in item.bind_list:
self.truck_excavator_exclude[truck_id] = excavator_id
self.excavator_exclude_modify[
self.truck_uuid_to_index_dict[truck_id]
][
self.excavator_uuid_to_index_dict[excavator_id]
] = 1000000
except Exception as es:
logger.error("矿卡-挖机禁止关系读取异常")
logger.error(es)
......@@ -431,19 +413,6 @@ class TruckInfo(WalkManage):
self.excavator_material_bind_modify = np.full((self.dynamic_truck_num, dynamic_excavator_num), 0)
self.dump_material_bind_modify = np.full((self.dynamic_truck_num, dynamic_excavator_num), 0)
# for truck_id in dynamic_truck_set:
# if truck_id in self.truck_dump_bind:
# unload_area_id = self.truck_dump_bind[truck_id]
# # unload_area_id = session_mysql.query(Dispatch.unload_area_id).filter_by(dump_id=dump_id).first()
# dump_material_id = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().Material
# self.truck_material_bind[truck_id] = dump_material_id
#
# if truck_id in self.truck_excavator_bind:
# excavator_id = self.truck_excavator_bind[truck_id]
# load_area_id = session_mysql.query(Dispatch).filter_by(exactor_id=excavator_id).first().load_area_id
# excavator_material_id = session_postgre.query(DiggerArea).filter_by(Id=load_area_id).first().Material
# self.truck_material_bind[truck_id] = excavator_material_id
for truck_id in dynamic_truck_set:
truck_index = self.truck_uuid_to_index_dict[truck_id]
......@@ -453,19 +422,12 @@ class TruckInfo(WalkManage):
dump_material_id = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().Material
self.truck_material_bind[truck_id] = dump_material_id
# unload_area_index = unload_area_uuid_to_index_dict[unload_area_id]
# for dump_index in range(dynamic_dump_num):
# if self.dump_index_to_unload_area_index_dict[dump_index] == unload_area_index:
# self.dump_material_bind_modify[truck_index][dump_index] = 1000000
if truck_id in self.truck_excavator_bind:
excavator_id = self.truck_excavator_bind[truck_id]
print(self.excavator.excavator_material)
# print(self.excavator.excavator_material)
excavator_material_id = self.excavator.excavator_material[excavator_id]
self.truck_material_bind[truck_id] = excavator_material_id
# excavator_index = self.excavator.excavator_uuid_to_index_dict[excavator_id]
# self.excavator_material_bind_modify[truck_index][excavator_index] = 1000000
for truck_id in dynamic_truck_set:
......@@ -498,31 +460,25 @@ class TruckInfo(WalkManage):
self.geo_length[truck_id] = session_mysql.query(EquipmentSpec).filter_by(id=truck_spec_id).first().length
self.geo_width[truck_spec_id] = session_mysql.query(EquipmentSpec).filter_by(id=truck_spec_id).first().width
# print("-------------------------------------------")
# print("truck")
# print(self.truck_uuid_to_index_dict)
# print("truck_material_bind")
# print(self.truck_material_bind)
# print("excavator")
# print(dynamic_excavator_set)
# print(self.excavator_material_bind_modify)
# print("dump")
# print(dynamic_dump_set)
# print(self.dump_material_bind_modify)
def update_truck_speed(self):
for truck_id in dynamic_truck_set:
self.empty_speed[truck_id] = session_mysql.query(EquipmentSpec.max_speed). \
Join(Equipment, EquipmentSpec.id == Equipment.equipment_spec). \
filter(Equipment.id == truck_id).first()
self.heavy_speed[truck_id] = session_mysql.query(EquipmentSpec.max_speed). \
Join(Equipment, EquipmentSpec.id == Equipment.equipment_spec). \
filter(Equipment.id == truck_id).first()
self.empty_speed[truck_id] = session_mysql.query(EquipmentSpec). \
join(Equipment, EquipmentSpec.id == Equipment.equipment_spec). \
filter(Equipment.id == truck_id).first().max_speed
self.heavy_speed[truck_id] = session_mysql.query(EquipmentSpec). \
join(Equipment, EquipmentSpec.id == Equipment.equipment_spec). \
filter(Equipment.id == truck_id).first().max_speed
def para_period_update(self):
# print("Para truck update!")
# 设备优先级启用
rule6 = session_mysql.query(DispatchRule).filter_by(id=6).first().disabled
# 锁定禁止启用
rule5 = session_mysql.query(DispatchRule).filter_by(id=5).first().disabled
logger.info("Para truck update!")
# 装载周期参数
......@@ -545,16 +501,20 @@ class TruckInfo(WalkManage):
# 更新有效载重
self.update_truck_payload()
# 更新绑定关系
self.update_truck_dump_area_bind()
if not rule5:
self.update_truck_excavator_bind()
# 更新绑定关系
self.update_truck_dump_area_bind()
# 更新禁止关系
self.update_truck_excavator_exclude()
self.update_truck_excavator_bind()
# 更新矿卡调度优先级
self.update_truck_priority()
# 更新禁止关系
self.update_truck_excavator_exclude()
if not rule6:
# 更新矿卡调度优先级
self.update_truck_priority()
# 更新矿卡物料类型
self.update_truck_material()
......@@ -570,6 +530,9 @@ class TruckInfo(WalkManage):
# 更新卡车当前行程
self.update_truck_trip()
# 矿卡速度更新
self.update_truck_speed()
# def period_update(self):
#
# print("Truck update!")
......
......@@ -6,12 +6,10 @@
# @File : path_plannner.py
# @Software: PyCharm
import numpy
from settings import *
from static_data_process import *
from settings import *
from para_config import *
from equipment.truck import TruckInfo
from path_plan.priority_control import weighted_walk_cost, available_walk
from para_config import *
from tables import *
M = 1000000
......@@ -51,13 +49,27 @@ class PathPlanner(WalkManage):
to_unload_cost = 0
# 装载道路总成本初始化
to_load_cost = 0
# 道路权重
weighted_distance = weighted_walk_cost()
# 修正因子
weight = 10000
# 阻塞成本权重
alpha = 10000
alpha = 1 * weight
# 距离成本权重
beta = 1
# 距离成本启用
rule1 = session_mysql.query(DispatchRule).filter_by(id=1).first()
if rule1.disabled == 0:
alpha = alpha * rule1.rule_weight
# 拥堵成本启用
rule2 = session_mysql.query(DispatchRule).filter_by(id=2).first()
if rule2.disabled == 0:
beta = beta * rule2.rule_weight
try:
# 备停区处理
if is_park:
# 提取指定道路记录
......@@ -84,7 +96,7 @@ class PathPlanner(WalkManage):
to_unload_cost = alpha * cost_to_unload_blockage + beta * path.to_unload_distance
to_load_cost = alpha * cost_to_load_blockage + beta * path.to_load_distance
except Exception as es:
logger.error(f'道路{load_area_id-unload_area_id}行驶成本计算异常')
logger.error(f'道路{load_area_id + "-" +unload_area_id}行驶成本计算异常')
logger.error(es)
return to_load_cost, to_unload_cost
......@@ -118,33 +130,48 @@ class PathPlanner(WalkManage):
self.period_map_para_load()
try:
# 读取路网成本
for walk_time in session_postgre.query(WalkTime).all():
unload_area_index = unload_area_uuid_to_index_dict[str(walk_time.unload_area_id)]
load_area_index = load_area_uuid_to_index_dict[str(walk_time.load_area_id)]
self.cost_to_load_area[unload_area_index][load_area_index], \
self.cost_to_unload_area[unload_area_index][load_area_index] = \
self.path_cost_generate(walk_time.load_area_id, walk_time.unload_area_id, False)
# 读取备停区路网成本
for walk_time_park in session_postgre.query(WalkTimePark).all():
park_area_index = park_uuid_to_index_dict[str(walk_time_park.park_area_id)]
load_area_index = load_area_uuid_to_index_dict[str(walk_time_park.load_area_id)]
_, self.cost_park_to_load_area[park_area_index][load_area_index] = \
self.path_cost_generate(walk_time_park.load_area_id, walk_time_park.park_area_id, True)
except Exception as es:
logger.error('路网信息计成本计算异常')
logger.error(es)
# try:
# 读取路网成本
for walk_time in session_postgre.query(WalkTime).all():
print(str(walk_time.load_area_id), str(walk_time.unload_area_id))
print(walk_time.load_area_name, walk_time.unload_area_name)
load_area_id, unload_area_id = str(walk_time.load_area_id), str(walk_time.unload_area_id)
unload_area_index = unload_area_uuid_to_index_dict[unload_area_id]
load_area_index = load_area_uuid_to_index_dict[load_area_id]
self.cost_to_load_area[unload_area_index][load_area_index], \
self.cost_to_unload_area[unload_area_index][load_area_index] = \
self.path_cost_generate(load_area_id, unload_area_id, False)
# 读取备停区路网成本
for walk_time_park in session_postgre.query(WalkTimePark).all():
park_area_index = park_uuid_to_index_dict[str(walk_time_park.park_area_id)]
load_area_index = load_area_uuid_to_index_dict[str(walk_time_park.load_area_id)]
_, self.cost_park_to_load_area[park_area_index][load_area_index] = \
self.path_cost_generate(str(walk_time_park.load_area_id), str(walk_time_park.park_area_id), True)
# except Exception as es:
# logger.error('路网信息计成本计算异常')
# logger.error(es)
cost_to_excavator = np.zeros_like(self.distance_to_excavator)
cost_to_dump = np.zeros_like(self.distance_to_dump)
# 路网优先级
walk_weight = weighted_walk_cost()
walk_weight = walk_weight / walk_weight.min()
# 路网禁用关系
walk_available = available_walk()
print("path_weight", walk_weight)
for i in range(dynamic_dump_num):
for j in range(dynamic_excavator_num):
cost_to_excavator[i][j] = self.cost_to_load_area[self.dump_index_to_unload_area_index_dict[i]][self.excavator_index_to_load_area_index_dict[j]]
cost_to_dump[i][j] = self.cost_to_unload_area[self.dump_index_to_unload_area_index_dict[i]][self.excavator_index_to_load_area_index_dict[j]]
load_area_index = self.excavator_index_to_load_area_index_dict[j]
unload_area_index = self.dump_index_to_unload_area_index_dict[i]
cost_to_excavator[i][j] = self.cost_to_load_area[unload_area_index][load_area_index] / walk_weight[i][j]
cost_to_dump[i][j] = self.cost_to_unload_area[unload_area_index][load_area_index] / walk_weight[i][j] * walk_available[i][j]
logger.info("真实路网距离-驶往挖机:")
logger.info(self.distance_to_excavator)
......@@ -158,6 +185,8 @@ class PathPlanner(WalkManage):
logger.info("阻塞路网距离-驶往卸点:")
logger.info(cost_to_dump)
return cost_to_excavator, cost_to_dump, walk_weight, walk_available
class LaneInfo:
def __init__(self):
......
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2021/9/3 14:44
# @Author : Opfer
# @Site :
# @File : priority_control.py
# @Software: PyCharm
from equipment.truck import *
from equipment.dump import *
from equipment.excavator import *
from para_config import *
truck = TruckInfo()
excavator = ExcavatorInfo()
dump = DumpInfo()
def weighted_walk_cost():
excavator.update_excavator_priority()
dump.update_dump_priority()
walk_weight = np.ones((dynamic_dump_num, dynamic_excavator_num))
excavator_priority = excavator.excavator_priority_coefficient
excavator_material_priority = excavator.excavator_material_priority
dump_priority = dump.dump_priority_coefficient
dump_material_priority = np.ones(dynamic_dump_num)
rule6 = session_mysql.query(DispatchRule).filter_by(id=6).first()
if not rule6.disabled:
for dump_id in dynamic_dump_set:
for excavator_id in dynamic_excavator_set:
dump_index = dump.dump_uuid_to_index_dict[dump_id]
excavator_inedx = excavator.excavator_uuid_to_index_dict[excavator_id]
walk_weight[dump_index][excavator_inedx] += dump_priority[dump_index] * \
excavator_priority[excavator_inedx]
rule7 = session_mysql.query(DispatchRule).filter_by(id=7).first()
if not rule7.disabled:
for dump_id in dynamic_dump_set:
for excavator_id in dynamic_excavator_set:
dump_index = dump.dump_uuid_to_index_dict[dump_id]
excavator_inedx = excavator.excavator_uuid_to_index_dict[excavator_id]
walk_weight[dump_index][excavator_inedx] += dump_material_priority[dump_index] * \
excavator_material_priority[excavator_inedx]
logger.info("路网优先级")
logger.info(walk_weight)
return walk_weight
def available_walk():
excavator.update_excavator_material()
dump.update_dump_material()
walk_weight = np.ones((dynamic_dump_num, dynamic_excavator_num))
for dump_id in dynamic_dump_set:
for excavator_id in dynamic_excavator_set:
dump_index = dump.dump_uuid_to_index_dict[dump_id]
excavator_inedx = excavator.excavator_uuid_to_index_dict[excavator_id]
if excavator.excavator_material[excavator_id] != dump.dump_material[dump_id]:
walk_weight[dump_index][excavator_inedx] += 1000
logger.info("路网禁用关系")
logger.info(walk_weight)
return walk_weight
......@@ -10,16 +10,10 @@
# 实时调度模块
from traffic_flow.traffic_flow_planner import *
from static_data_process import *
from para_config import *
from settings import *
from equipment.truck import TruckInfo
from equipment.excavator import ExcavatorInfo
from equipment.dump import DumpInfo
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
# 调度类
class Dispatcher(WalkManage):
......@@ -520,6 +514,13 @@ class Dispatcher(WalkManage):
def truck_schedule(self, truck_id):
rule3 = session_mysql.query(DispatchRule).filter_by(id=3).first().disabled
rule4 = session_mysql.query(DispatchRule).filter_by(id=4).first().disabled
path = PathPlanner()
cost_to_excavator, cost_to_dump, walk_weight, walk_available = path.walk_cost()
# 矿卡对应序号
truck_index = self.truck_uuid_to_index_dict[truck_id]
# 矿卡行程
......@@ -538,11 +539,11 @@ class Dispatcher(WalkManage):
unloading_time = self.dump.get_unloading_time()
# 路网信息
walk_time_park_to_excavator = walk_manage.get_walk_time_park_to_excavator() \
* (empty_speed / self.truck.empty_speed[truck_id])
* (empty_speed / float(self.truck.empty_speed[truck_id]))
walk_time_to_dump = walk_manage.get_walk_time_to_dump() * \
(heavy_speed / self.truck.heavy_speed[truck_id])
walk_time_to_excavator = walk_manage.get_walk_time_to_excavator() * \
(empty_speed / self.truck.empty_speed[truck_id])
(empty_speed / float(self.truck.empty_speed[truck_id]))
# 出入场时间
loading_task_time = self.excavator.get_loading_task_time()
......@@ -563,6 +564,11 @@ class Dispatcher(WalkManage):
target = 0
logger.info("矿卡-挖机锁定")
logger.info(self.truck.excavator_material_bind_modify[truck_index])
logger.info("矿卡排斥关系")
logger.info(self.truck.excavator_exclude_modify[truck_index])
if task == -2:
try:
logger.info("矿卡状态:矿卡启动或故障恢复")
......@@ -587,19 +593,21 @@ class Dispatcher(WalkManage):
self.truck.truck_excavator_bind[truck_id]
]
else:
target = np.argmax(
transport_value = \
(
10
* (1 - self.sim_excavator_real_mass / excavator_target_mass)
/ (
np.maximum(
self.sim_excavator_ava_time,
now + walk_time_park_to_excavator[0, :],
10
* (1 - self.sim_excavator_real_mass / excavator_target_mass)
/ (
np.maximum(
self.sim_excavator_ava_time,
now + walk_time_park_to_excavator[0, :],
)
+ loading_task_time
- now
)
+ loading_task_time
- now
)
)
target = np.argmax(
transport_value
- self.truck.excavator_exclude_modify[truck_index]
- self.truck.excavator_material_bind_modify[truck_index]
)
......@@ -677,9 +685,18 @@ class Dispatcher(WalkManage):
target = key
break
else:
if rule3 and rule4:
print("here233")
transport_value = (cost_to_excavator / walk_weight * walk_available)[:, int(trip[1])]
logger.info("不含车流规划:")
logger.info(transport_value)
else:
print("here122")
transport_value = \
(self.actual_goto_dump_traffic_flow[int(trip[1]), :] + 0.001) \
/ (self.opt_goto_dump_traffic_flow[int(trip[1]), :] + 0.001)
target = np.argmin(
(self.actual_goto_dump_traffic_flow[int(trip[1]), :] + 0.001)
/ (self.opt_goto_dump_traffic_flow[int(trip[1]), :] + 0.001)
transport_value
+ self.truck.excavator_exclude_modify[truck_index]
+ self.truck.excavator_material_bind_modify[truck_index]
)
......@@ -762,9 +779,17 @@ class Dispatcher(WalkManage):
self.truck.truck_excavator_bind[truck_id]
]
else:
if rule3 and rule4:
print("here233")
transport_value = (cost_to_excavator / walk_weight * walk_available)[int(trip[1]), :]
else:
print("here122")
transport_value = \
(self.actual_goto_excavator_traffic_flow[trip[1], :] + 0.001) \
/ (self.opt_goto_excavator_traffic_flow[trip[1], :] + 0.001)
target = np.argmin(
(self.actual_goto_excavator_traffic_flow[trip[1], :] + 0.001)
/ (self.opt_goto_excavator_traffic_flow[trip[1], :] + 0.001)
transport_value
+ self.truck.excavator_exclude_modify[truck_index]
+ self.truck.excavator_material_bind_modify[truck_index]
)
......@@ -781,199 +806,202 @@ class Dispatcher(WalkManage):
def schedule_construct(self):
try:
# try:
# 读取所需信息
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()
# 读取所需信息
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()
# 出入场时间
loading_task_time = self.excavator.get_loading_task_time()
unloading_task_time = self.dump.get_unloading_task_time()
# 出入场时间
loading_task_time = self.excavator.get_loading_task_time()
unloading_task_time = self.dump.get_unloading_task_time()
walk_time_to_unload_area = walk_manage.get_walk_time_to_unload_area()
walk_time_to_load_area = walk_manage.get_walk_time_to_load_area()
walk_time_to_unload_area = walk_manage.get_walk_time_to_unload_area()
walk_time_to_load_area = walk_manage.get_walk_time_to_load_area()
# Seq初始化
Seq = [[truck_current_trip[i][1], -1] for i in range(trucks)]
# Seq初始化
Seq = [[truck_current_trip[i][1], -1] for i in range(trucks)]
# 根据矿卡最早可用时间顺序进行规划
temp = copy.deepcopy(self.cur_truck_ava_time) * self.truck.truck_priority
# 根据矿卡最早可用时间顺序进行规划
temp = copy.deepcopy(self.cur_truck_ava_time) - self.truck.truck_priority
try:
# 没有启动的矿卡加上一个很大的值,降低其优先级
for i in range(trucks):
task = truck_current_task[self.truck_index_to_uuid_dict[i]]
if task == -2:
temp[i] = temp[i] + M
except Exception as es:
logger.error(es)
index = np.argsort(temp.reshape(1, -1))
index = index.flatten()
# 对于在线矿卡已经赋予新的派车计划,更新其最早可用时间,及相关设备时间参数
for truck in index:
if len(Seq[truck]) > 0:
index = np.argsort(temp.reshape(1, -1))
index = index.flatten()
# try:
task = truck_current_task[self.truck_index_to_uuid_dict[truck]]
# 对于在线矿卡已经赋予新的派车计划,更新其最早可用时间,及相关设备时间参数
for truck in index:
if len(Seq[truck]) > 0:
# 矿卡结束当前派车计划后的目的地
end_eq_index = truck_current_trip[truck][1]
# try:
task = truck_current_task[self.truck_index_to_uuid_dict[truck]]
# 调用调度函数,得到最优目的地序号
target_eq_index = self.truck_schedule(
self.truck_index_to_uuid_dict[truck]
)
# 矿卡结束当前派车计划后的目的地
end_eq_index = truck_current_trip[truck][1]
# 写入Seq序列
Seq[truck][1] = target_eq_index
# 调用调度函数,得到最优目的地序号
target_eq_index = self.truck_schedule(
self.truck_index_to_uuid_dict[truck]
)
# except Exception as es:
# logger.error(f'矿卡 {truck_uuid_to_name_dict[self.truck_index_to_uuid_dict[truck]]} 派车计划计算异常')
# logger.error(es)
# 写入Seq序列
Seq[truck][1] = target_eq_index
try:
# except Exception as es:
# logger.error(f'矿卡 {truck_uuid_to_name_dict[self.truck_index_to_uuid_dict[truck]]} 派车计划计算异常')
# logger.error(es)
if task in empty_task_set:
target_area_index = self.dump_index_to_unload_area_index_dict[
target_eq_index
]
end_area_index = self.excavator_index_to_load_area_index_dict[
end_eq_index
]
# 更新变量,预计产量更新
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],
self.sim_truck_ava_time[truck]
+ walk_time_to_unload_area[target_area_index][
end_area_index
],
)
+ unloading_task_time[target_eq_index]
)
elif task in heavy_task_set:
target_area_index = (
self.excavator_index_to_load_area_index_dict[
target_eq_index
]
)
end_area_index = self.dump_index_to_unload_area_index_dict[
end_eq_index
]
# 更新变量,预计产量更新
self.sim_excavator_real_mass[target_eq_index] = (
self.sim_excavator_real_mass[target_eq_index]
+ payload[truck]
)
# 预计装载点可用时间更新
self.sim_excavator_ava_time[target_eq_index] = (
max(
self.sim_excavator_ava_time[target_eq_index],
self.sim_truck_ava_time[truck]
+ walk_time_to_unload_area[end_area_index][
target_area_index
],
)
+ loading_task_time[target_eq_index]
)
else:
pass
except Exception as es:
logger.error(
f"矿卡 {truck_uuid_to_name_dict[self.truck_index_to_uuid_dict[truck]]} 调度状态更新异常"
)
logger.error(es)
for i in range(len(Seq)):
try:
record = {"truckId": 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()
target_area_index = self.dump_index_to_unload_area_index_dict[
target_eq_index
]
end_area_index = self.excavator_index_to_load_area_index_dict[
end_eq_index
]
# 更新变量,预计产量更新
self.sim_dump_real_mass[target_eq_index] = (
self.sim_dump_real_mass[target_eq_index] + payload[truck]
)
record["exactorId"] = item.exactor_id
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %#I:%#M:%#S %p"
# 预计卸载设备可用时间更新
self.sim_dump_ava_time[target_eq_index] = (
max(
self.sim_dump_ava_time[target_eq_index],
self.sim_truck_ava_time[truck]
+ walk_time_to_unload_area[target_area_index][
end_area_index
],
)
+ unloading_task_time[target_eq_index]
)
elif task in heavy_task_set:
item = (
session_mysql.query(Dispatch)
.filter_by(
exactor_id=self.excavator_index_to_uuid_dict[Seq[i][1]],
isauto=1,
isdeleted=0,
)
.first()
target_area_index = (
self.excavator_index_to_load_area_index_dict[
target_eq_index
]
)
record["exactorId"] = self.excavator_index_to_uuid_dict[Seq[i][1]]
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %#I:%#M:%#S %p"
end_area_index = self.dump_index_to_unload_area_index_dict[
end_eq_index
]
# 更新变量,预计产量更新
self.sim_excavator_real_mass[target_eq_index] = (
self.sim_excavator_real_mass[target_eq_index]
+ payload[truck]
)
elif task == -2:
item = (
session_mysql.query(Dispatch)
.filter_by(
exactor_id=self.excavator_index_to_uuid_dict[Seq[i][1]],
isauto=1,
isdeleted=0,
# 预计装载点可用时间更新
self.sim_excavator_ava_time[target_eq_index] = (
max(
self.sim_excavator_ava_time[target_eq_index],
self.sim_truck_ava_time[truck]
+ walk_time_to_unload_area[end_area_index][
target_area_index
],
)
.first()
)
record["exactorId"] = item.exactor_id
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %#I:%#M:%#S %p"
+ loading_task_time[target_eq_index]
)
else:
pass
redis5.set(self.truck_index_to_uuid_dict[i], str(json.dumps(record)))
except Exception as es:
logger.error("调度结果写入异常-redis写入异常")
logger.error(f"调度结果:{Seq}")
logger.error(
f"矿卡 {truck_uuid_to_name_dict[self.truck_index_to_uuid_dict[truck]]} 调度状态更新异常"
)
logger.error(es)
for i in range(trucks):
print("dispatch_setting:")
print(redis5.get(self.truck_index_to_uuid_dict[i]))
except Exception as es:
logger.error("更新不及时")
logger.error(es)
for i in range(len(Seq)):
try:
record = {"truckId": 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()
)
record["exactorId"] = item.exactor_id
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %#I:%#M:%#S %p"
)
elif task in heavy_task_set:
item = (
session_mysql.query(Dispatch)
.filter_by(
exactor_id=self.excavator_index_to_uuid_dict[Seq[i][1]],
isauto=1,
isdeleted=0,
)
.first()
)
record["exactorId"] = self.excavator_index_to_uuid_dict[Seq[i][1]]
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %#I:%#M:%#S %p"
)
elif task == -2:
item = (
session_mysql.query(Dispatch)
.filter_by(
exactor_id=self.excavator_index_to_uuid_dict[Seq[i][1]],
isauto=1,
isdeleted=0,
)
.first()
)
record["exactorId"] = item.exactor_id
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %#I:%#M:%#S %p"
)
else:
pass
redis5.set(self.truck_index_to_uuid_dict[i], str(json.dumps(record)))
except Exception as es:
logger.error("调度结果写入异常-redis写入异常")
logger.error(f"调度结果:{Seq}")
logger.error(es)
for i in range(trucks):
print("dispatch_setting:")
print(redis5.get(self.truck_index_to_uuid_dict[i]))
# except Exception as es:
# logger.error("更新不及时")
# logger.error(es)
logger.info(
"#####################################周期更新结束#####################################"
......@@ -1084,10 +1112,6 @@ if __name__ == "__main__":
# # 下面三个函数保证程序定期执行,不用管他
# def process(dispatcher):
#
......
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2021/8/24 14:56
# @Author : Opfer
# @Site :
# @File : schedule_test.py
# @Software: PyCharm
import datetime
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
def my_job(id='my_job'):
print(id, '-->', datetime.datetime.now())
jobstores = {'default': MemoryJobStore()}
executors = {'default': ThreadPoolExecutor(10)}
job_defaults = {'coalesce': False, 'max_instances': 10}
scheduler = BlockingScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults)
scheduler.add_job(my_job, args=['job_interval'], id='ins1', trigger='interval', seconds=5)
scheduler.add_job(my_job, args=['job_interval'], id='ins2', trigger='interval', seconds=5)
if __name__ == '__main__':
try:
scheduler.start()
except SystemExit:
print('exit')
exit()
\ No newline at end of file
......@@ -142,7 +142,6 @@ class WalkTime(Base):
# self.walktime_load = walktime_load
# self.walktime_unload = walktime_unload
# class Truck(Base):
# __tablename__ = 'truck_status'
#
......@@ -410,3 +409,25 @@ class DiggingWorkArea(Base):
self.Id = Id
self.Material = Material
class DispatchRule(Base):
__tablename__ = 'sys_dispatch_rule'
id = Column(Integer, primary_key=True)
rule_weight = Column(Float)
disabled = Column(BOOLEAN)
def __init__(self, id, rule_weight, disabled):
self.id = id
self.rule_weight = rule_weight
self.disabled = disabled
class Material(Base):
__tablename__ = 'resource_materials'
id = Column(VARCHAR(40), primary_key=True)
name = Column(VARCHAR(40))
def __init__(self, id, name):
self.id = id
self.name = name
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2021/8/3 10:51
# @Time : 2021/8/31 15:17
# @Author : Opfer
# @Site :
# @File : __init__.py.py
# @File : __init__.py
# @Software: PyCharm
\ No newline at end of file
......@@ -8,15 +8,9 @@
# import
from static_data_process import *
from settings import *
from path_plan.path_plannner import *
from para_config import *
from traffic_flow.traffic_flow_planner import *
from static_data_process import *
from para_config import *
from settings import *
from equipment.truck import TruckInfo
from equipment.excavator import ExcavatorInfo
from equipment.dump import DumpInfo
from equipment.truck import TruckInfo
......@@ -24,24 +18,11 @@ from equipment.truck import TruckInfo
# 车流规划类
class Traffic_para(WalkManage):
def __init__(self, num_of_load_area, num_of_unload_area, num_of_excavator, num_of_dump):
# 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_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_index_to_unload_area_index_dict = {} # 用于保存卸点与卸载区的绑定关系(id)
# self.excavator_index_to_load_area_index_dict = {} # 用于保存挖机与装载区的绑定关系(id)
self.truck = TruckInfo()
self.num_of_dump = num_of_dump
self.num_of_excavator = num_of_excavator
self.num_of_load_area = num_of_load_area
self.num_of_unload_area = num_of_unload_area
self.empty_speed = empty_speed # 空载矿卡平均时速
self.heavy_speed = heavy_speed # 重载矿卡平均时速
self.walk_time_to_load_area = np.zeros((num_of_unload_area, num_of_load_area)) # 空载运输路线距离
self.walk_time_to_unload_area = np.zeros((num_of_load_area, num_of_unload_area)) # 重载运输路线距离
......@@ -57,7 +38,10 @@ class Traffic_para(WalkManage):
self.truck = TruckInfo()
self.payload = np.mean(self.truck.get_payload())
self.min_throughout = 200 # 最小产量约束
self.empty_speed = sum(self.truck.empty_speed.values()) / self.truck.get_truck_num() # 空载矿卡平均时速
self.heavy_speed = sum(self.truck.heavy_speed.values()) / self.truck.get_truck_num() # 重载矿卡平均时速
self.min_throughout = 1000 # 最小产量约束
self.truck_total_num = 0
self.excavator_strength = np.zeros(num_of_excavator) # 用于保存电铲的工作强度,单位是t/h
......@@ -66,20 +50,22 @@ class Traffic_para(WalkManage):
self.path_planner = PathPlanner()
self.path_planner.walk_cost()
self.excavator = ExcavatorInfo()
self.dump = DumpInfo()
'''
以下参数暂时没用到
'''
self.excavator_priority_coefficient = np.zeros(num_of_excavator) # 每个电铲的优先级系数
self.excavator_priority_coefficient = np.ones(num_of_excavator) # 每个电铲的优先级系数
self.excavator_material_priority = np.ones(num_of_excavator) # 每个电铲的物料优先级系数
self.grade_loading_array = np.zeros(num_of_excavator) # 用于保存电铲挖掘矿石的品位
self.dump_priority_coefficient = np.zeros(num_of_dump) # 每个卸载点的优先级系数
self.dump_priority_coefficient = np.ones(num_of_dump) # 每个卸载点的优先级系数
self.dump_material_priority = np.ones(num_of_excavator) # 每个卸载点的物料优先级系数
# 卸载道路的运输系数:卸载道路上,每运输1吨货物需要一辆卡车运行时长,等于(该卸载道路上车辆平均运行时长/卡车平均实际装载量)
self.goto_unload_area_factor = np.full((num_of_load_area, num_of_unload_area), 10, dtype=float)
# 装载道路的运输系数,装载道路上,每提供1吨的装载能力需要一辆卡车运行时长,等于(该装载道路上车辆平均运行时长/卡车平均装载能力)
self.goto_load_area_factor = np.full((num_of_unload_area, num_of_load_area), 10, dtype=float)
self.goto_dump_factor = np.full((num_of_excavator, num_of_dump), 10, dtype=float) # 逻辑卸载道路的运输系数
self.goto_excavator_factor = np.full((num_of_dump, num_of_excavator), 10, dtype=float) # 逻辑装载道路的运输系数
self.priority_coefficient = np.zeros((num_of_excavator, num_of_dump)) # 卸载道路的优先级系数
self.priority_coefficient_goto_dump = np.ones((num_of_excavator, num_of_dump)) # 卸载道路的优先级系数
self.priority_coefficient_goto_excavator = np.ones((num_of_dump, num_of_excavator)) # 装载道路的优先级系数
self.grade_lower_dump_array = np.zeros(num_of_dump) # 卸载点矿石品位下限
self.grade_upper_dump_array = np.zeros(num_of_dump) # 卸载点矿石品位上限
......@@ -87,42 +73,28 @@ class Traffic_para(WalkManage):
self.load_area_material_type = {}
self.unload_area_material_type = {}
# # 提取卸载点信息并建立映射
# def extract_dump_info(self):
# dump_index = 0
# for dispatch in session_mysql.query(Dispatch).filter_by(isdeleted=0, isauto=1).all():
# unload_area_id = dispatch.unload_area_id
# dump_id = dispatch.dump_id
# if dump_id not in self.dump_uuid_to_unload_area_uuid_dict:
# # dump_uuid <-> dump_id
# self.dump_uuid_to_index_dict[dump_id] = dump_index
# self.dump_index_to_uuid_dict[dump_index] = dump_id
# # dump_uuid -> unload_area_uuid
# self.dump_uuid_to_unload_area_uuid_dict[dump_id] = unload_area_id
# # dump_id -> unload_area_id
# self.dump_index_to_unload_area_index_dict[
# self.dump_uuid_to_index_dict[dump_id]] = \
# unload_area_uuid_to_index_dict[unload_area_id]
#
# self.dump_strength[dump_index] = 300 # 卸载设备最大卸载能力,单位吨/小时
# self.grade_upper_dump_array[dump_index] = 100 # 卸点品位上限
# self.grade_lower_dump_array[dump_index] = 100 # 卸点品位下限
# self.dump_priority_coefficient[dump_index] = 1 # 卸载设备优先级
# dump_index += 1
# 设置卸载点信息
def extract_dump_info(self):
try:
for dump_index in range(dynamic_excavator_num):
unload_area_id = unload_area_index_to_uuid_dict[self.dump_index_to_unload_area_index_dict[dump_index]]
rule3 = session_mysql.query(DispatchRule).filter_by(id=3).first()
if not rule3.disabled:
for dump_index in range(dynamic_excavator_num):
unload_area_id = unload_area_index_to_uuid_dict[self.dump_index_to_unload_area_index_dict[dump_index]]
unload_ability = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().UnloadAbililty
self.dump_strength[dump_index] = unload_ability # 卸载设备最大卸载能力,单位吨/小时
unload_ability = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().UnloadAbililty
self.dump_strength[dump_index] = unload_ability # 卸载设备最大卸载能力,单位吨/小时
if unload_ability < 200:
raise Exception("卸载点卸载能力异常")
else:
self.dump_strength = np.full(self.num_of_dump, 5000)
for dump_index in range(dynamic_excavator_num):
# self.dump_strength[dump_index] = 10000 # 卸载设备最大卸载能力,单位吨/小时
self.grade_upper_dump_array[dump_index] = 100 # 卸点品位上限
self.grade_lower_dump_array[dump_index] = 100 # 卸点品位下限
self.dump_priority_coefficient[dump_index] = 1 # 卸载设备优先级
except Exception as es:
logger.error(es)
logger.error("卸载点信息设置异常")
......@@ -155,14 +127,23 @@ class Traffic_para(WalkManage):
# 设置挖信息
def extract_excavator_info(self):
try:
rule4 = session_mysql.query(DispatchRule).filter_by(id=4).first()
if not rule4.disabled:
for excavator_index in range(len(self.excavator_index_to_uuid_dict)):
load_ability = session_mysql.query(EquipmentSpec.mining_abililty).\
join(Equipment, Equipment.equipment_spec == EquipmentSpec.id).\
filter(Equipment.id == self.excavator_index_to_uuid_dict[excavator_index]).first()
self.excavator_strength[excavator_index] = load_ability.mining_abililty
if load_ability.mining_abililty < 200:
raise Exception("挖机装载能力异常")
else:
self.excavator_strength = np.full(self.num_of_excavator, 5000)
for excavator_index in range(len(self.excavator_index_to_uuid_dict)):
load_ability = session_mysql.query(EquipmentSpec.mining_abililty).\
join(Equipment, Equipment.equipment_spec == EquipmentSpec.id).\
filter(Equipment.id == self.excavator_index_to_uuid_dict[excavator_index]).first()
self.excavator_strength[excavator_index] = load_ability.mining_abililty
# self.excavator_strength[excavator_index] = 1000 # 挖机最大装载能力,单位吨/小时
self.grade_loading_array[excavator_index] = 100 # 挖机装载物料品位
self.excavator_priority_coefficient[excavator_index] = 1 # 挖机优先级
except Exception as es:
logger.error(es)
logger.error("挖机信息设置异常")
......@@ -197,114 +178,119 @@ class Traffic_para(WalkManage):
# # else:
# # logger.info(f'物料类型是煤方')
include_material_type = True
# def extract_excavator_priority(self):
# for excavator_id in dynamic_excavator_set:
# item = session_mysql.query(Equipment).filter_by(id=excavator_id).first()
# self.excavator_priority_coefficient[self.excavator_uuid_to_index_dict[excavator_id]] = item.priority + 1
#
# self.excavator.update_excavator_material()
#
# # 物料优先级控制
# rule = 1
# rule7 = session_mysql.query(DispatchRule).filter_by(id=7).first()
# material_priority_use = rule7.disabled
# if material_priority_use == 0:
# rule = rule7.rule_weight
#
# if rule == 0:
# if self.excavator.excavator_material[excavator_id] == 'c8092d59-7597-44d7-a731-5a568b46060e':
# print("here111")
# self.excavator_material_priority[self.excavator_uuid_to_index_dict[excavator_id]] = 5
# elif rule == 2:
# if self.excavator.excavator_material[excavator_id] == 'c481794b-6ced-45b9-a9c4-c4a388f44418':
# self.excavator_material_priority[self.excavator_uuid_to_index_dict[excavator_id]] = 5
#
# print("挖机优先级")
# print(self.excavator_material_priority)
#
# def extract_dump_priority(self):
# for excavator_id in dynamic_excavator_set:
# item = session_mysql.query(Equipment).filter_by(id=excavator_id).first()
# self.excavator_priority_coefficient[self.excavator_uuid_to_index_dict[excavator_id]] = item.priority + 1
def extract_walk_time_info(self, include_material_type):
# def extract_walk_time_info(self, include_material_type):
#
# # try:
# # 车流规划部分矩阵格式与其余两个模块不同
# cost_to_load_area = self.path_planner.cost_to_load_area
# cost_to_unload_area = self.path_planner.cost_to_unload_area
#
# distance_to_load_area = self.path_planner.distance_to_load_area
# distance_to_unload_area = self.path_planner.distance_to_unload_area
#
# self.load_area_material_type = {}
# self.unload_area_material_type = {}
# for item in session_postgre.query(DiggingWorkArea).all():
# load_area_id = str(item.Id)
# # if load_area_id in load_area_uuid_to_index_dict:
# self.load_area_material_type[load_area_id] = item.Material
#
# for item in session_postgre.query(DumpArea).all():
# unload_area_id = str(item.Id)
# # if unload_area_id in unload_area_uuid_to_index_dict:
# self.unload_area_material_type[unload_area_id] = item.Material
#
#
# # # 物料优先级控制
# # factor = 1
# # rule = 1
# # rule7 = session_mysql.query(DispatchRule).filter_by(id=7).first()
# # material_priority_use = rule7.disabled
# # if material_priority_use == 0:
# # rule = rule7.rule_weight
# #
# # # 路网信息读取
# # for unload_area_index in range(unload_area_num):
# # for load_area_index in range(load_area_num):
# # unload_area_id = unload_area_index_to_uuid_dict[unload_area_index]
# # load_area_id = load_area_index_to_uuid_dict[load_area_index]
# # if unload_area_id in unload_area_uuid_to_index_dict and load_area_id in load_area_uuid_to_index_dict:
# #
# # print(cost_to_load_area[unload_area_index][load_area_index], (empty_speed * 1000), self.payload)
# #
# # if rule == 0:
# # if self.load_area_material_type[load_area_id] == 'c8092d59-7597-44d7-a731-5a568b46060e':
# # self.goto_load_area_factor[unload_area_index][load_area_index] = \
# # 5 * (cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
# # else:
# # self.goto_load_area_factor[unload_area_index][load_area_index] = \
# # (cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
# #
# # elif rule == 1:
# # self.goto_load_area_factor[unload_area_index][load_area_index] = \
# # (cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
# #
# # elif rule == 2:
# # if self.load_area_material_type[load_area_id] == 'c481794b-6ced-45b9-a9c4-c4a388f44418':
# # self.goto_load_area_factor[unload_area_index][load_area_index] = \
# # 5 * (cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
# # else:
# # self.goto_load_area_factor[unload_area_index][load_area_index] = \
# # (cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
# #
# # self.goto_unload_area_factor[load_area_index][unload_area_index] = \
# # (cost_to_unload_area[unload_area_index][load_area_index] / (heavy_speed * 1000)) / self.payload
# try:
# 车流规划部分矩阵格式与其余两个模块不同
cost_to_load_area = self.path_planner.cost_to_load_area
cost_to_unload_area = self.path_planner.cost_to_unload_area
def extract_walk_time_info(self):
try:
# 车流规划部分矩阵格式与其余两个模块不同
cost_to_load_area = self.path_planner.cost_to_load_area
cost_to_unload_area = self.path_planner.cost_to_unload_area
distance_to_load_area = self.path_planner.distance_to_load_area
distance_to_unload_area = self.path_planner.distance_to_unload_area
distance_to_load_area = self.path_planner.distance_to_load_area
distance_to_unload_area = self.path_planner.distance_to_unload_area
self.load_area_material_type = {}
self.unload_area_material_type = {}
for item in session_postgre.query(DiggingWorkArea).all():
load_area_id = str(item.Id)
if load_area_id in load_area_uuid_to_index_dict:
self.load_area_material_type[load_area_id] = item.Material
for item in session_postgre.query(DumpArea).all():
unload_area_id = str(item.Id)
if unload_area_id in unload_area_uuid_to_index_dict:
self.unload_area_material_type[unload_area_id] = item.Material
# 路网信息读取
for unload_area_index in range(unload_area_num):
for load_area_index in range(load_area_num):
# 是否考虑cost
if include_material_type == True:
logger.info(f'考虑物料类型')
unload_area_id = unload_area_index_to_uuid_dict[unload_area_index]
load_area_id = load_area_index_to_uuid_dict[load_area_index]
if unload_area_id in unload_area_uuid_to_index_dict and load_area_id in load_area_uuid_to_index_dict:
if self.unload_area_material_type[unload_area_id] == 'c481794b-6ced-45b9-a9c4-c4a388f44418' \
and self.load_area_material_type[load_area_id] == 'c481794b-6ced-45b9-a9c4-c4a388f44418':
self.goto_load_area_factor[unload_area_index][load_area_index] = \
0.75*(cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
self.goto_unload_area_factor[load_area_index][unload_area_index] = \
0.75*(cost_to_unload_area[unload_area_index][load_area_index] / (heavy_speed * 1000)) / self.payload
else:
self.goto_load_area_factor[unload_area_index][load_area_index] = \
(cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
self.goto_unload_area_factor[load_area_index][unload_area_index] = \
(cost_to_unload_area[unload_area_index][load_area_index] / (heavy_speed * 1000)) / self.payload
# 不考虑物料类型的cost
else:
# 路网信息读取
for unload_area_index in range(unload_area_num):
for load_area_index in range(load_area_num):
self.goto_load_area_factor[unload_area_index][load_area_index] = \
(cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
self.goto_unload_area_factor[load_area_index][unload_area_index] = \
(cost_to_unload_area[unload_area_index][load_area_index] / (heavy_speed * 1000)) / self.payload
# except Exception as es:
# logger.error(es)
# logger.error("车流规划路网信息计算异常")
# def extract_walk_time_info(self):
# try:
# # 车流规划部分矩阵格式与其余两个模块不同
# cost_to_load_area = self.path_planner.cost_to_load_area
# cost_to_unload_area = self.path_planner.cost_to_unload_area
#
# distance_to_load_area = self.path_planner.distance_to_load_area
# distance_to_unload_area = self.path_planner.distance_to_unload_area
#
# # 路网信息读取
# for unload_area_index in range(unload_area_num):
# for load_area_index in range(load_area_num):
# self.goto_load_area_factor[unload_area_index][load_area_index] = \
# (cost_to_load_area[unload_area_index][load_area_index] / (empty_speed * 1000)) / self.payload
#
# self.goto_unload_area_factor[load_area_index][unload_area_index] = \
# (cost_to_unload_area[unload_area_index][load_area_index] / (heavy_speed * 1000)) / self.payload
# except Exception as es:
# logger.error(es)
# logger.error("车流规划信息计算异常")
#
# # for walk_time in session_postgre.query(WalkTime).all():
# # load_area_id = str(walk_time.load_area_id)
# # unload_area_id = str(walk_time.unload_area_id)
# # # 将uuid转为id
# # load_area_index = load_area_uuid_to_index_dict[load_area_id]
# # unload_area_index = unload_area_uuid_to_index_dict[unload_area_id]
# #
# # # # 运输路线距离
# # # self.walk_time_to_load_area[unload_area_index][load_area_index] = walk_time.to_load_distance
# # # self.walk_time_to_unload_area[load_area_index][unload_area_index] = walk_time.to_unload_distance
# #
# # # 卸载道路上,每运输1吨货物需要一辆卡车运行时长,等于(该卸载道路上车辆平均运行时长/卡车平均实际装载量)
# # # 单位为辆小时/吨
# # # i代表第i个电铲,j代表第j个卸载点
# # # walktime_goto_dump单位是秒,需要除以3600,转成小时
# # self.goto_load_area_factor[unload_area_index][load_area_index] = \
# # (60 / 1000 * walk_time.to_load_distance / self.empty_speed) / self.payload
# # # / self.avg_goto_excavator_weight[load_area_index][unload_area_index]
# #
# # # 装载道路上,每提供1吨的装载能力需要一辆卡车运行时长,等于(该装载道路上车辆平均运行时长/卡车平均装载能力)
# # # 单位为辆小时/吨
# # # i代表第i个卸载点,j代表第j个电铲
# # # walktime_goto_excavator单位是秒,需要除以3600,转成小时
# # self.goto_unload_area_factor[load_area_index][unload_area_index] = \
# # (60 / 1000 * walk_time.to_unload_distance / self.heavy_speed) / self.payload
# # # / self.avg_goto_excavator_weight[unload_area_index][load_area_index]
except Exception as es:
logger.error(es)
logger.error("车流规划信息计算异常")
# 初始化车流规划类
......@@ -318,13 +304,11 @@ def Traffic_para_init(num_of_load_area, num_of_unload_area, num_of_excavator, nu
tra_para.period_walk_para_load()
# Traffic_para.extract_walk_time_info(tra_para)
tra_para.extract_excavator_info()
tra_para.extract_dump_info()
tra_para.extract_walk_time_info(True)
tra_para.extract_walk_time_info()
tra_para.truck.update_truck_payload()
......@@ -353,9 +337,28 @@ def Traffic_para_init(num_of_load_area, num_of_unload_area, num_of_excavator, nu
tra_para.goto_dump_factor[i][j] = \
tra_para.goto_unload_area_factor[load_area_index][unload_area_index]
# 每条卸载道路的优先级,等于电铲的优先级乘以卸载点的优先级
tra_para.priority_coefficient[i][j] = tra_para.excavator_priority_coefficient[i] \
* tra_para.dump_priority_coefficient[j]
# # 设备优先级
# if not device_priority_use:
# print("here1")
# # 每条卸载道路的优先级,等于电铲的优先级乘以卸载点的优先级
# tra_para.priority_coefficient_goto_dump[i][j] = tra_para.excavator_priority_coefficient[i] \
# * tra_para.dump_priority_coefficient[j]
#
# # 每条装载道路的优先级,等于电铲的优先级乘以卸载点的优先级
# tra_para.priority_coefficient_goto_excavator[j][i] = tra_para.excavator_priority_coefficient[i] \
# * tra_para.dump_priority_coefficient[j]
# # 物料优先级
# if not material_priority_use:
# print("here2")
# # # 每条卸载道路的优先级,等于电铲的优先级乘以卸载点的优先级
# # tra_para.priority_coefficient_goto_dump[i][j] += tra_para.excavator_material_priority[i] \
# # * tra_para.dump_material_priority[j]
#
# # 每条装载道路的优先级,等于电铲的优先级乘以卸载点的优先级
# print(tra_para.excavator_material_priority[i], tra_para.dump_material_priority)
# tra_para.priority_coefficient_goto_excavator[j][i] = tra_para.excavator_material_priority[i] \
# * tra_para.dump_material_priority[j]
# # 逻辑距离赋值,来自实际道路距离
# tra_para.walk_time_to_excavator[j][i] = \
......@@ -364,6 +367,8 @@ def Traffic_para_init(num_of_load_area, num_of_unload_area, num_of_excavator, nu
# tra_para.walk_time_to_dump[i][j] = \
# tra_para.walk_time_to_unload_area[load_area_index][unload_area_index]
print("cout", tra_para.priority_coefficient_goto_dump, tra_para.priority_coefficient_goto_excavator)
# except Exception as es:
# logger.error(es)
# logger.error("车流规划类比初始化异常")
......
......@@ -19,13 +19,13 @@ from traffic_flow.traffic_flow_info import *
# 解决线性规划问题,生成每条道路的流量
def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
def transportation_problem_slove(coefficient_goto_dump, coefficient_goto_excavator, w_ij, s_ij, b_excavator,
b_dump, grade_loading_array,
max_unload_weigh_alg_flag, truck_total_num,
walk_time_to_excavator, walk_time_to_dump, min_throughout,
grade_lower_array=None, grade_upper_array=None):
row = len(coefficient) # 代表挖机的个数,第i行代表第i台挖机
col = len(coefficient[0]) # 代表卸载设备的个数,第j行代表第j个卸载设备
row = len(coefficient_goto_dump) # 代表挖机的个数,第i行代表第i台挖机
col = len(coefficient_goto_dump[0]) # 代表卸载设备的个数,第j行代表第j个卸载设备
# prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)
# 卸载道路的流量,单位是吨/小时,i代表起点为第i个挖机,j代表终点为第j个卸载设备
......@@ -39,7 +39,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
if max_unload_weigh_alg_flag == True:
prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)
# 得到目标函数,目标函数是使得系统的运输量最大
prob += pulp.lpDot(flatten(var_x), coefficient.flatten())
prob += (pulp.lpDot(flatten(var_y), coefficient_goto_excavator.flatten()))
else:
prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMinimize)
goto_excavator_cost = var_x * walk_time_to_excavator
......@@ -53,6 +53,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
logger.info("road_factor")
logger.info(w_ij)
logger.info(s_ij)
# 矿卡总数约束,在每条道路上的车辆总数要小于矿卡总个数
# 通过矩阵按元素相乘得到每条卸载道路上的车辆个数
......@@ -61,7 +62,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
load_truck_totla_num_array = s_ij * var_y
# 装载的矿卡数和卸载的矿卡数需要小于矿卡总数
prob += (pulp.lpSum(unload_truck_total_num_array) +
pulp.lpSum(load_truck_totla_num_array) <= 2)
pulp.lpSum(load_truck_totla_num_array) <= truck_total_num)
# 最大工作强度约束
# 约束每个挖机的工作强度
......@@ -153,7 +154,8 @@ def traffic_flow_plan():
else:
logger.info(f'最小成本调度模式')
coefficient = traffic_programme_para.priority_coefficient
coefficient_goto_dump = traffic_programme_para.priority_coefficient_goto_dump
coefficient_goto_excavator = traffic_programme_para.priority_coefficient_goto_excavator
w_ij = traffic_programme_para.goto_dump_factor
s_ij = traffic_programme_para.goto_excavator_factor
b_excavator = traffic_programme_para.excavator_strength
......@@ -166,7 +168,9 @@ def traffic_flow_plan():
walk_time_to_dump = traffic_programme_para.walk_time_to_dump
truck_total_num = traffic_programme_para.truck_total_num
res = transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator, b_dump,
print(w_ij, s_ij, b_excavator, b_dump)
res = transportation_problem_slove(coefficient_goto_dump, coefficient_goto_excavator, w_ij, s_ij, b_excavator, b_dump,
grade_loading_array, max_unload_weigh_alg_flag, truck_total_num,
walk_time_to_excavator, walk_time_to_dump, min_throughout,
grade_upper_dump_array, grade_lower_dump_array)
......@@ -180,8 +184,12 @@ def traffic_flow_plan():
print('各变量的取值为:')
logger.info('各变量取值:')
print(dynamic_dump_set)
print(dynamic_excavator_set)
print(np.array(res['var_x']).round(3))
logger.info(f'重运车流:{res["var_x"]} 单位: 吨/时')
print(dynamic_excavator_set)
print(dynamic_dump_set)
print(np.array(res['var_y']).round(3))
logger.info(f'空运车流:{res["var_y"]} 单位: 吨/时')
......@@ -196,7 +204,7 @@ def traffic_flow_plan():
return res["var_x"], res["var_y"]
# traffic_flow_plan()
traffic_flow_plan()
# end = time.time()
# print("used {:.5}s".format(end-start))
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