Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
I
integrated-scheduling
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张晓彤
integrated-scheduling
Commits
7573aef2
Commit
7573aef2
authored
Sep 04, 2021
by
Allvey
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
挖机/卸点优先级
路网物料禁止 模式切换 锁定禁止规则
parent
d22b9d9f
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
294 additions
and
207 deletions
+294
-207
dump.py
equipment/dump.py
+29
-25
excavator.py
equipment/excavator.py
+29
-23
truck.py
equipment/truck.py
+36
-73
path_plannner.py
path_plan/path_plannner.py
+46
-17
priority_control.py
path_plan/priority_control.py
+67
-0
realtime_dispatch.py
realtime_dispatch.py
+46
-22
schedule_test.py
schedule_test.py
+0
-36
tables.py
tables.py
+22
-1
__init__.py
traffic_flow/__init__.py
+3
-2
traffic_flow_info.py
traffic_flow/traffic_flow_info.py
+0
-0
traffic_flow_planner.py
traffic_flow/traffic_flow_planner.py
+16
-8
No files found.
equipment/dump.py
View file @
7573aef2
...
@@ -42,6 +42,8 @@ class DumpInfo(WalkManage):
...
@@ -42,6 +42,8 @@ class DumpInfo(WalkManage):
self
.
exit_time
=
np
.
zeros
(
self
.
dynamic_dump_num
)
self
.
exit_time
=
np
.
zeros
(
self
.
dynamic_dump_num
)
# 卸载点物料类型
# 卸载点物料类型
self
.
dump_material
=
{}
self
.
dump_material
=
{}
# 卸点优先级
self
.
dump_priority_coefficient
=
np
.
ones
(
self
.
dynamic_dump_num
)
# 初始化读取映射及路网
# 初始化读取映射及路网
self
.
period_map_para_load
()
self
.
period_map_para_load
()
...
@@ -65,6 +67,17 @@ class DumpInfo(WalkManage):
...
@@ -65,6 +67,17 @@ class DumpInfo(WalkManage):
def
get_dynamic_dump_set
(
self
):
def
get_dynamic_dump_set
(
self
):
return
self
.
dynamic_dump_set
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
):
def
update_dump_unloadtime
(
self
):
self
.
unloading_time
=
np
.
zeros
(
self
.
dynamic_dump_num
)
self
.
unloading_time
=
np
.
zeros
(
self
.
dynamic_dump_num
)
...
@@ -121,18 +134,6 @@ class DumpInfo(WalkManage):
...
@@ -121,18 +134,6 @@ class DumpInfo(WalkManage):
self
.
entrance_time
[
self
.
dump_uuid_to_index_dict
[
dump_id
]]
=
0.50
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
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
):
def
update_actual_unload_thoughout
(
self
):
self
.
cur_dump_real_mass
=
np
.
zeros
(
self
.
dynamic_dump_num
)
self
.
cur_dump_real_mass
=
np
.
zeros
(
self
.
dynamic_dump_num
)
...
@@ -156,7 +157,12 @@ class DumpInfo(WalkManage):
...
@@ -156,7 +157,12 @@ class DumpInfo(WalkManage):
for
dump_id
in
dynamic_dump_set
:
for
dump_id
in
dynamic_dump_set
:
unload_area_id
=
session_mysql
.
query
(
Dispatch
)
.
filter_by
(
dump_id
=
dump_id
)
.
first
()
.
unload_area_id
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
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
):
def
para_period_update
(
self
):
...
@@ -169,11 +175,6 @@ class DumpInfo(WalkManage):
...
@@ -169,11 +175,6 @@ class DumpInfo(WalkManage):
self
.
period_walk_para_load
()
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
())
self
.
dynamic_dump_set
=
set
(
update_autodisp_dump
())
...
@@ -182,14 +183,17 @@ class DumpInfo(WalkManage):
...
@@ -182,14 +183,17 @@ class DumpInfo(WalkManage):
# 计算平均卸载时间
# 计算平均卸载时间
self
.
update_dump_unloadtime
()
self
.
update_dump_unloadtime
()
# 计算平均进出场时间
self
.
update_dump_entrance_exit_time
()
# 计算实时卸载量
# 计算实时卸载量
self
.
update_actual_unload_thoughout
()
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()
self
.
dump_target_mass
=
np
.
full
(
self
.
dynamic_dump_num
,
dump_target_mass
)
\ No newline at end of file
\ No newline at end of file
equipment/excavator.py
View file @
7573aef2
...
@@ -42,6 +42,10 @@ class ExcavatorInfo(WalkManage):
...
@@ -42,6 +42,10 @@ class ExcavatorInfo(WalkManage):
self
.
exit_time
=
np
.
zeros
(
self
.
dynamic_excavator_num
)
self
.
exit_time
=
np
.
zeros
(
self
.
dynamic_excavator_num
)
# 挖机对应物料类型
# 挖机对应物料类型
self
.
excavator_material
=
{}
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
()
self
.
period_map_para_load
()
...
@@ -50,22 +54,6 @@ class ExcavatorInfo(WalkManage):
...
@@ -50,22 +54,6 @@ class ExcavatorInfo(WalkManage):
# 参数初始化
# 参数初始化
self
.
para_period_update
()
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
):
def
get_loading_time
(
self
):
return
self
.
loading_time
return
self
.
loading_time
...
@@ -183,6 +171,26 @@ class ExcavatorInfo(WalkManage):
...
@@ -183,6 +171,26 @@ class ExcavatorInfo(WalkManage):
excavator_material_id
=
session_postgre
.
query
(
DiggingWorkArea
)
.
filter_by
(
Id
=
load_area_id
)
.
first
()
.
Material
excavator_material_id
=
session_postgre
.
query
(
DiggingWorkArea
)
.
filter_by
(
Id
=
load_area_id
)
.
first
()
.
Material
self
.
excavator_material
[
excavator_id
]
=
excavator_material_id
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
):
def
para_period_update
(
self
):
# print("Excavator update!")
# print("Excavator update!")
...
@@ -210,13 +218,12 @@ class ExcavatorInfo(WalkManage):
...
@@ -210,13 +218,12 @@ class ExcavatorInfo(WalkManage):
# 计算实时装载量
# 计算实时装载量
self
.
update_actual_load_throughout
()
self
.
update_actual_load_throughout
()
# 更新挖机物料
self
.
update_excavator_material
()
# 更新挖机优先级
# 挖机目标产量
# 挖机目标产量
self
.
excavator_target_mass
=
np
.
full
(
self
.
excavator_target_mass
=
np
.
full
(
self
.
dynamic_excavator_num
,
excavator_target_mass
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
equipment/truck.py
View file @
7573aef2
This diff is collapsed.
Click to expand it.
path_plan/path_plannner.py
View file @
7573aef2
...
@@ -6,12 +6,10 @@
...
@@ -6,12 +6,10 @@
# @File : path_plannner.py
# @File : path_plannner.py
# @Software: PyCharm
# @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
equipment.truck
import
TruckInfo
from
path_plan.priority_control
import
weighted_walk_cost
,
available_walk
from
para_config
import
*
from
tables
import
*
M
=
1000000
M
=
1000000
...
@@ -51,13 +49,27 @@ class PathPlanner(WalkManage):
...
@@ -51,13 +49,27 @@ class PathPlanner(WalkManage):
to_unload_cost
=
0
to_unload_cost
=
0
# 装载道路总成本初始化
# 装载道路总成本初始化
to_load_cost
=
0
to_load_cost
=
0
# 道路权重
weighted_distance
=
weighted_walk_cost
()
# 修正因子
weight
=
10000
# 阻塞成本权重
# 阻塞成本权重
alpha
=
1
0000
alpha
=
1
*
weight
# 距离成本权重
# 距离成本权重
beta
=
1
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
:
try
:
# 备停区处理
# 备停区处理
if
is_park
:
if
is_park
:
# 提取指定道路记录
# 提取指定道路记录
...
@@ -84,7 +96,7 @@ class PathPlanner(WalkManage):
...
@@ -84,7 +96,7 @@ class PathPlanner(WalkManage):
to_unload_cost
=
alpha
*
cost_to_unload_blockage
+
beta
*
path
.
to_unload_distance
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
to_load_cost
=
alpha
*
cost_to_load_blockage
+
beta
*
path
.
to_load_distance
except
Exception
as
es
:
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
)
logger
.
error
(
es
)
return
to_load_cost
,
to_unload_cost
return
to_load_cost
,
to_unload_cost
...
@@ -118,33 +130,48 @@ class PathPlanner(WalkManage):
...
@@ -118,33 +130,48 @@ class PathPlanner(WalkManage):
self
.
period_map_para_load
()
self
.
period_map_para_load
()
try
:
#
try:
# 读取路网成本
# 读取路网成本
for
walk_time
in
session_postgre
.
query
(
WalkTime
)
.
all
():
for
walk_time
in
session_postgre
.
query
(
WalkTime
)
.
all
():
unload_area_index
=
unload_area_uuid_to_index_dict
[
str
(
walk_time
.
unload_area_id
)]
print
(
str
(
walk_time
.
load_area_id
),
str
(
walk_time
.
unload_area_id
))
load_area_index
=
load_area_uuid_to_index_dict
[
str
(
walk_time
.
load_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_load_area
[
unload_area_index
][
load_area_index
],
\
self
.
cost_to_unload_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
)
self
.
path_cost_generate
(
load_area_id
,
unload_area_id
,
False
)
# 读取备停区路网成本
# 读取备停区路网成本
for
walk_time_park
in
session_postgre
.
query
(
WalkTimePark
)
.
all
():
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
)]
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
)]
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
.
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
)
self
.
path_cost_generate
(
str
(
walk_time_park
.
load_area_id
),
str
(
walk_time_park
.
park_area_id
)
,
True
)
except
Exception
as
es
:
#
except Exception as es:
logger
.
error
(
'路网信息计成本计算异常'
)
#
logger.error('路网信息计成本计算异常')
logger
.
error
(
es
)
#
logger.error(es)
cost_to_excavator
=
np
.
zeros_like
(
self
.
distance_to_excavator
)
cost_to_excavator
=
np
.
zeros_like
(
self
.
distance_to_excavator
)
cost_to_dump
=
np
.
zeros_like
(
self
.
distance_to_dump
)
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
i
in
range
(
dynamic_dump_num
):
for
j
in
range
(
dynamic_excavator_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
]]
load_area_index
=
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
]]
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
(
"真实路网距离-驶往挖机:"
)
logger
.
info
(
self
.
distance_to_excavator
)
logger
.
info
(
self
.
distance_to_excavator
)
...
@@ -158,6 +185,8 @@ class PathPlanner(WalkManage):
...
@@ -158,6 +185,8 @@ class PathPlanner(WalkManage):
logger
.
info
(
"阻塞路网距离-驶往卸点:"
)
logger
.
info
(
"阻塞路网距离-驶往卸点:"
)
logger
.
info
(
cost_to_dump
)
logger
.
info
(
cost_to_dump
)
return
cost_to_excavator
,
cost_to_dump
,
walk_weight
,
walk_available
class
LaneInfo
:
class
LaneInfo
:
def
__init__
(
self
):
def
__init__
(
self
):
...
...
path_plan/priority_control.py
0 → 100644
View file @
7573aef2
#!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
realtime_dispatch.py
View file @
7573aef2
...
@@ -10,16 +10,10 @@
...
@@ -10,16 +10,10 @@
# 实时调度模块
# 实时调度模块
from
traffic_flow.traffic_flow_planner
import
*
from
traffic_flow.traffic_flow_planner
import
*
from
static_data_process
import
*
from
para_config
import
*
from
para_config
import
*
from
settings
import
*
from
equipment.truck
import
TruckInfo
from
equipment.truck
import
TruckInfo
from
equipment.excavator
import
ExcavatorInfo
from
equipment.excavator
import
ExcavatorInfo
from
equipment.dump
import
DumpInfo
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
):
class
Dispatcher
(
WalkManage
):
...
@@ -520,6 +514,13 @@ class Dispatcher(WalkManage):
...
@@ -520,6 +514,13 @@ class Dispatcher(WalkManage):
def
truck_schedule
(
self
,
truck_id
):
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
]
truck_index
=
self
.
truck_uuid_to_index_dict
[
truck_id
]
# 矿卡行程
# 矿卡行程
...
@@ -538,11 +539,11 @@ class Dispatcher(WalkManage):
...
@@ -538,11 +539,11 @@ class Dispatcher(WalkManage):
unloading_time
=
self
.
dump
.
get_unloading_time
()
unloading_time
=
self
.
dump
.
get_unloading_time
()
# 路网信息
# 路网信息
walk_time_park_to_excavator
=
walk_manage
.
get_walk_time_park_to_excavator
()
\
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
()
*
\
walk_time_to_dump
=
walk_manage
.
get_walk_time_to_dump
()
*
\
(
heavy_speed
/
self
.
truck
.
heavy_speed
[
truck_id
])
(
heavy_speed
/
self
.
truck
.
heavy_speed
[
truck_id
])
walk_time_to_excavator
=
walk_manage
.
get_walk_time_to_excavator
()
*
\
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
()
loading_task_time
=
self
.
excavator
.
get_loading_task_time
()
...
@@ -563,6 +564,11 @@ class Dispatcher(WalkManage):
...
@@ -563,6 +564,11 @@ class Dispatcher(WalkManage):
target
=
0
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
:
if
task
==
-
2
:
try
:
try
:
logger
.
info
(
"矿卡状态:矿卡启动或故障恢复"
)
logger
.
info
(
"矿卡状态:矿卡启动或故障恢复"
)
...
@@ -587,7 +593,7 @@ class Dispatcher(WalkManage):
...
@@ -587,7 +593,7 @@ class Dispatcher(WalkManage):
self
.
truck
.
truck_excavator_bind
[
truck_id
]
self
.
truck
.
truck_excavator_bind
[
truck_id
]
]
]
else
:
else
:
t
arget
=
np
.
argmax
(
t
ransport_value
=
\
(
(
10
10
*
(
1
-
self
.
sim_excavator_real_mass
/
excavator_target_mass
)
*
(
1
-
self
.
sim_excavator_real_mass
/
excavator_target_mass
)
...
@@ -600,6 +606,8 @@ class Dispatcher(WalkManage):
...
@@ -600,6 +606,8 @@ class Dispatcher(WalkManage):
-
now
-
now
)
)
)
)
target
=
np
.
argmax
(
transport_value
-
self
.
truck
.
excavator_exclude_modify
[
truck_index
]
-
self
.
truck
.
excavator_exclude_modify
[
truck_index
]
-
self
.
truck
.
excavator_material_bind_modify
[
truck_index
]
-
self
.
truck
.
excavator_material_bind_modify
[
truck_index
]
)
)
...
@@ -677,9 +685,18 @@ class Dispatcher(WalkManage):
...
@@ -677,9 +685,18 @@ class Dispatcher(WalkManage):
target
=
key
target
=
key
break
break
else
:
else
:
target
=
np
.
argmin
(
if
rule3
and
rule4
:
(
self
.
actual_goto_dump_traffic_flow
[
int
(
trip
[
1
]),
:]
+
0.001
)
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
)
/
(
self
.
opt_goto_dump_traffic_flow
[
int
(
trip
[
1
]),
:]
+
0.001
)
target
=
np
.
argmin
(
transport_value
+
self
.
truck
.
excavator_exclude_modify
[
truck_index
]
+
self
.
truck
.
excavator_exclude_modify
[
truck_index
]
+
self
.
truck
.
excavator_material_bind_modify
[
truck_index
]
+
self
.
truck
.
excavator_material_bind_modify
[
truck_index
]
)
)
...
@@ -762,9 +779,17 @@ class Dispatcher(WalkManage):
...
@@ -762,9 +779,17 @@ class Dispatcher(WalkManage):
self
.
truck
.
truck_excavator_bind
[
truck_id
]
self
.
truck
.
truck_excavator_bind
[
truck_id
]
]
]
else
:
else
:
target
=
np
.
argmin
(
if
rule3
and
rule4
:
(
self
.
actual_goto_excavator_traffic_flow
[
trip
[
1
],
:]
+
0.001
)
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
)
/
(
self
.
opt_goto_excavator_traffic_flow
[
trip
[
1
],
:]
+
0.001
)
target
=
np
.
argmin
(
transport_value
+
self
.
truck
.
excavator_exclude_modify
[
truck_index
]
+
self
.
truck
.
excavator_exclude_modify
[
truck_index
]
+
self
.
truck
.
excavator_material_bind_modify
[
truck_index
]
+
self
.
truck
.
excavator_material_bind_modify
[
truck_index
]
)
)
...
@@ -781,7 +806,7 @@ class Dispatcher(WalkManage):
...
@@ -781,7 +806,7 @@ class Dispatcher(WalkManage):
def
schedule_construct
(
self
):
def
schedule_construct
(
self
):
try
:
#
try:
# 读取所需信息
# 读取所需信息
trucks
=
self
.
truck
.
get_truck_num
()
trucks
=
self
.
truck
.
get_truck_num
()
...
@@ -802,13 +827,16 @@ class Dispatcher(WalkManage):
...
@@ -802,13 +827,16 @@ class Dispatcher(WalkManage):
Seq
=
[[
truck_current_trip
[
i
][
1
],
-
1
]
for
i
in
range
(
trucks
)]
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
):
for
i
in
range
(
trucks
):
task
=
truck_current_task
[
self
.
truck_index_to_uuid_dict
[
i
]]
task
=
truck_current_task
[
self
.
truck_index_to_uuid_dict
[
i
]]
if
task
==
-
2
:
if
task
==
-
2
:
temp
[
i
]
=
temp
[
i
]
+
M
temp
[
i
]
=
temp
[
i
]
+
M
except
Exception
as
es
:
logger
.
error
(
es
)
index
=
np
.
argsort
(
temp
.
reshape
(
1
,
-
1
))
index
=
np
.
argsort
(
temp
.
reshape
(
1
,
-
1
))
index
=
index
.
flatten
()
index
=
index
.
flatten
()
...
@@ -971,9 +999,9 @@ class Dispatcher(WalkManage):
...
@@ -971,9 +999,9 @@ class Dispatcher(WalkManage):
for
i
in
range
(
trucks
):
for
i
in
range
(
trucks
):
print
(
"dispatch_setting:"
)
print
(
"dispatch_setting:"
)
print
(
redis5
.
get
(
self
.
truck_index_to_uuid_dict
[
i
]))
print
(
redis5
.
get
(
self
.
truck_index_to_uuid_dict
[
i
]))
except
Exception
as
es
:
#
except Exception as es:
logger
.
error
(
"更新不及时"
)
#
logger.error("更新不及时")
logger
.
error
(
es
)
#
logger.error(es)
logger
.
info
(
logger
.
info
(
"#####################################周期更新结束#####################################"
"#####################################周期更新结束#####################################"
...
@@ -1084,10 +1112,6 @@ if __name__ == "__main__":
...
@@ -1084,10 +1112,6 @@ if __name__ == "__main__":
# # 下面三个函数保证程序定期执行,不用管他
# # 下面三个函数保证程序定期执行,不用管他
# def process(dispatcher):
# def process(dispatcher):
#
#
...
...
schedule_test.py
deleted
100644 → 0
View file @
d22b9d9f
#!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
tables.py
View file @
7573aef2
...
@@ -142,7 +142,6 @@ class WalkTime(Base):
...
@@ -142,7 +142,6 @@ class WalkTime(Base):
# self.walktime_load = walktime_load
# self.walktime_load = walktime_load
# self.walktime_unload = walktime_unload
# self.walktime_unload = walktime_unload
# class Truck(Base):
# class Truck(Base):
# __tablename__ = 'truck_status'
# __tablename__ = 'truck_status'
#
#
...
@@ -410,3 +409,25 @@ class DiggingWorkArea(Base):
...
@@ -410,3 +409,25 @@ class DiggingWorkArea(Base):
self
.
Id
=
Id
self
.
Id
=
Id
self
.
Material
=
Material
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
traffic_flow/__init__.py
View file @
7573aef2
#!E:\Pycharm Projects\Waytous
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# @Time : 2021/8/3
10:51
# @Time : 2021/8/3
1 15:17
# @Author : Opfer
# @Author : Opfer
# @Site :
# @Site :
# @File : __init__.py
.py
# @File : __init__.py
# @Software: PyCharm
# @Software: PyCharm
\ No newline at end of file
traffic_flow/traffic_flow_info.py
View file @
7573aef2
This diff is collapsed.
Click to expand it.
traffic_flow/traffic_flow_planner.py
View file @
7573aef2
...
@@ -19,13 +19,13 @@ from traffic_flow.traffic_flow_info import *
...
@@ -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
,
b_dump
,
grade_loading_array
,
max_unload_weigh_alg_flag
,
truck_total_num
,
max_unload_weigh_alg_flag
,
truck_total_num
,
walk_time_to_excavator
,
walk_time_to_dump
,
min_throughout
,
walk_time_to_excavator
,
walk_time_to_dump
,
min_throughout
,
grade_lower_array
=
None
,
grade_upper_array
=
None
):
grade_lower_array
=
None
,
grade_upper_array
=
None
):
row
=
len
(
coefficient
)
# 代表挖机的个数,第i行代表第i台挖机
row
=
len
(
coefficient
_goto_dump
)
# 代表挖机的个数,第i行代表第i台挖机
col
=
len
(
coefficient
[
0
])
# 代表卸载设备的个数,第j行代表第j个卸载设备
col
=
len
(
coefficient
_goto_dump
[
0
])
# 代表卸载设备的个数,第j行代表第j个卸载设备
# prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)
# prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)
# 卸载道路的流量,单位是吨/小时,i代表起点为第i个挖机,j代表终点为第j个卸载设备
# 卸载道路的流量,单位是吨/小时,i代表起点为第i个挖机,j代表终点为第j个卸载设备
...
@@ -39,7 +39,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
...
@@ -39,7 +39,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
if
max_unload_weigh_alg_flag
==
True
:
if
max_unload_weigh_alg_flag
==
True
:
prob
=
pulp
.
LpProblem
(
'Transportation Problem'
,
sense
=
pulp
.
LpMaximize
)
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
:
else
:
prob
=
pulp
.
LpProblem
(
'Transportation Problem'
,
sense
=
pulp
.
LpMinimize
)
prob
=
pulp
.
LpProblem
(
'Transportation Problem'
,
sense
=
pulp
.
LpMinimize
)
goto_excavator_cost
=
var_x
*
walk_time_to_excavator
goto_excavator_cost
=
var_x
*
walk_time_to_excavator
...
@@ -53,6 +53,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
...
@@ -53,6 +53,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
logger
.
info
(
"road_factor"
)
logger
.
info
(
"road_factor"
)
logger
.
info
(
w_ij
)
logger
.
info
(
w_ij
)
logger
.
info
(
s_ij
)
# 矿卡总数约束,在每条道路上的车辆总数要小于矿卡总个数
# 矿卡总数约束,在每条道路上的车辆总数要小于矿卡总个数
# 通过矩阵按元素相乘得到每条卸载道路上的车辆个数
# 通过矩阵按元素相乘得到每条卸载道路上的车辆个数
...
@@ -61,7 +62,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
...
@@ -61,7 +62,7 @@ def transportation_problem_slove(coefficient, w_ij, s_ij, b_excavator,
load_truck_totla_num_array
=
s_ij
*
var_y
load_truck_totla_num_array
=
s_ij
*
var_y
# 装载的矿卡数和卸载的矿卡数需要小于矿卡总数
# 装载的矿卡数和卸载的矿卡数需要小于矿卡总数
prob
+=
(
pulp
.
lpSum
(
unload_truck_total_num_array
)
+
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():
...
@@ -153,7 +154,8 @@ def traffic_flow_plan():
else
:
else
:
logger
.
info
(
f
'最小成本调度模式'
)
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
w_ij
=
traffic_programme_para
.
goto_dump_factor
s_ij
=
traffic_programme_para
.
goto_excavator_factor
s_ij
=
traffic_programme_para
.
goto_excavator_factor
b_excavator
=
traffic_programme_para
.
excavator_strength
b_excavator
=
traffic_programme_para
.
excavator_strength
...
@@ -166,7 +168,9 @@ def traffic_flow_plan():
...
@@ -166,7 +168,9 @@ def traffic_flow_plan():
walk_time_to_dump
=
traffic_programme_para
.
walk_time_to_dump
walk_time_to_dump
=
traffic_programme_para
.
walk_time_to_dump
truck_total_num
=
traffic_programme_para
.
truck_total_num
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
,
grade_loading_array
,
max_unload_weigh_alg_flag
,
truck_total_num
,
walk_time_to_excavator
,
walk_time_to_dump
,
min_throughout
,
walk_time_to_excavator
,
walk_time_to_dump
,
min_throughout
,
grade_upper_dump_array
,
grade_lower_dump_array
)
grade_upper_dump_array
,
grade_lower_dump_array
)
...
@@ -180,8 +184,12 @@ def traffic_flow_plan():
...
@@ -180,8 +184,12 @@ def traffic_flow_plan():
print
(
'各变量的取值为:'
)
print
(
'各变量的取值为:'
)
logger
.
info
(
'各变量取值:'
)
logger
.
info
(
'各变量取值:'
)
print
(
dynamic_dump_set
)
print
(
dynamic_excavator_set
)
print
(
np
.
array
(
res
[
'var_x'
])
.
round
(
3
))
print
(
np
.
array
(
res
[
'var_x'
])
.
round
(
3
))
logger
.
info
(
f
'重运车流:{res["var_x"]} 单位: 吨/时'
)
logger
.
info
(
f
'重运车流:{res["var_x"]} 单位: 吨/时'
)
print
(
dynamic_excavator_set
)
print
(
dynamic_dump_set
)
print
(
np
.
array
(
res
[
'var_y'
])
.
round
(
3
))
print
(
np
.
array
(
res
[
'var_y'
])
.
round
(
3
))
logger
.
info
(
f
'空运车流:{res["var_y"]} 单位: 吨/时'
)
logger
.
info
(
f
'空运车流:{res["var_y"]} 单位: 吨/时'
)
...
@@ -196,7 +204,7 @@ def traffic_flow_plan():
...
@@ -196,7 +204,7 @@ def traffic_flow_plan():
return
res
[
"var_x"
],
res
[
"var_y"
]
return
res
[
"var_x"
],
res
[
"var_y"
]
#
traffic_flow_plan()
traffic_flow_plan
()
# end = time.time()
# end = time.time()
# print("used {:.5}s".format(end-start))
# print("used {:.5}s".format(end-start))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment