先把问题抽象化,将各个楼命名为A1到A34,A0、A35分别为机器人A、B的充电站
对应带权无向图
对于对应问题,先用Dijkstra算法算各楼到图书馆的最短路径
各个楼号到图书馆的最短路径
Ai到A14距离为SAi | 距离路径 |
A5-A14=5.2 | 路径为A5->A11->A17->A16->A15->A14 |
A11-A14=4.5 | 路径为A11->A17->A16->A15->A14 |
A4-A14=4.4 | 路径为A4->A3->A2->A8->A14 |
A35-A14=4.4 | 路径为A35->A29->A23->A22->A21->A15->A14 |
A29-A14=4.1 | 路径为A29->A23->A22->A21->A15->A14 |
A34-A14=4.1 | 路径为A34->A33->A32->A26->A20->A14 |
A3-A14=3.9 | 路径为A3->A2->A8->A14 |
A17-A14=3.9 | 路径为A17->A16->A15->A14 |
A10-A14=3.7 | 路径为A10->A9->A15->A14 |
A28-A14=3.7 | 路径为A28->A22->A21->A15->A14 |
A23-A14=3.7 | 路径为A23->A22->A21->A15->A14 |
A33-A14=3.5 | 路径为A33->A32->A26->A20->A14 |
A27-A14=3.4 | 路径为A27->A26->A20->A14 |
A22-A14=3.1 | 路径为A22->A21->A15->A14 |
A9-A14=2.9 | 路径为A9->A15->A14 |
A16-A14=2.9 | 路径为A16->A15->A14 |
A0-A14=2.9 | 路径为A0->A6->A12->A13->A14 |
A31-A14=2.9 | 路径为A31->A25->A19->A20->A14 |
A1-A14=2.8 | 路径为A1->A7->A13->A14 |
A2-A14=2.8 | 路径为A2->A8->A14 |
A30-A14=2.8 | 路径为A30->A24->A25->A19->A20->A14 |
A21-A14=2.6 | 路径为A21->A15->A14 |
A24-A14=2.3 | 路径为A24->A25->A19->A20->A14 |
A6-A14=2.2 | 路径为A6->A12->A13->A14 |
A7-A14=2.2 | 路径为A7->A13->A14 |
A15-A14=2.2 | 路径为A15->A14 |
A32-A14=2.1 | 路径为A32->A26->A20->A14 |
A18-A14=2.0 | 路径为A18->A12->A13->A14 |
A25-A14=2.0 | 路径为A25->A19->A20->A14 |
A12-A14=1.5 | 路径为A12->A13->A14 |
A19-A14=1.4 | 路径为A19->A20->A14 |
A8-A14=1.3 | 路径为A8->A14 |
A26-A14=1.3 | 路径为A26->A20->A14 |
A13-A14=1.1 | 路径为A13->A14 |
A20-A14=1.0 | 路径为A20->A14 |
问题一
首趟A、B从各自驻地出发,先到达到达图书馆,中途先收取所经楼的书本,
首趟如下图
首趟A,B所用时间为回到图书馆最短路径除于对应速度
TA=SA35/speed_A=4.4/8=0.55
TB=SA0/speed_B=2.9/10=0.29
TA-TB=0.26
此时A6,A12楼的书本被B机器人回收,值为0;
A29,A23楼的书本被A机器人回收,值为0,A22被回收2本(因为容量为10本),值为5-2=3;
以B机器人首趟到达图书馆记为0时刻,而配送机器人A则会在0.26小时后出发。然后配送机器人A,B都从图书馆出发。A、B小车从图书馆出发后所用总时间设为T1,T2,(T1=T1+SAi*2/speed_A,T2=T2+SAi*2/speed_B),每趟到达图书馆后都比较T1,T2的大小,用时较少的机器人将再次出发进行下一趟的楼号遍历。直到所有的楼号遍历完毕,即所有的图书都被回收完毕。
A,B按照各个楼到图书馆的最短路径从大到小依次交替选择目标楼,返回途中进行此路径上的图书回收。(此想法可以避免:先回收图书馆附近的,导致最后回收较远楼返回时容量未满)
对于返回途径的每个楼的回收书本过程:
若MAi<=C, 则MAi=0; C=C-MAi; 若该楼书本量小于等于当前容量,则被取走所有的书,该楼书本量设为0(MAi=0),当前容量则为容量减去该楼需要还的书(C=C-MAi),下次选择目标点直接跳过该点。
若MAi>C, 则MAi=MAi-C, C=0; 若无法收取经过点的全部书本(即MAi>C),要把车容量装满(C=0),剩余书本仍存于该点中(MAi=MAi-C)。
C为0时,不用遍历该路径上剩余点,直接返回A14(图书馆),然后进入下一趟选择目标楼号。
举例演示
第一趟B车选择A5 最短路径为SA5=5.2 ,路径为A5->A11->A17->A16->A15->A14,其中MA5<C,MA5=0;C=C-MA5=4;MA11>C,MA11=MA11-C=2,C=0;C为0,剩余路径不再遍历,直接回A14;T2初始为0,T2=T2+SA5*2/speed_B=1.04h ,当前T1=0.26h T2>T1,所以下一趟应该由A出发
第二趟A车选择A11 最短路径为4.5 ,路径为A11->A17->A16->A15->A14,其中MA11<C,MA11=0,C=C-MA11=8; MA17<C,MA17=0,C=C-MA17=6;MA16=C,MA16=0,C=C-MA16=0;C为0,剩余路径不再遍历,直接回A14;
T1初始为0.26,T1=T1+SA11*2/speed_A=1.385h ,当前T2=1.04h T2<T1,所以下一趟应该由B出发
第一问结果
第1趟B车选择A5,最短路径为5.2,路径为A5 -> A11 -> A17 -> A16 -> A15 -> A14
当前T1=0.260h, T2=1.040h
第2趟A车选择A11,最短路径为4.5,路径为A11 -> A17 -> A16 -> A15 -> A14
当前T1=1.385h, T2=1.040h
第3趟B车选择A4,最短路径为4.4,路径为A4 -> A3 -> A2 -> A8 -> A14
当前T1=1.385h, T2=1.920h
第4趟A车选择A34,最短路径为4.1,路径为A34 -> A33 -> A32 -> A26 -> A20 -> A14
当前T1=2.410h, T2=1.920h
第5趟B车选择A29,最短路径为4.1,路径为A29 -> A23 -> A22 -> A21 -> A15 -> A14
当前T1=2.410h, T2=2.740h
第6趟A车选择A17,最短路径为3.9,路径为A17 -> A16 -> A15 -> A14
当前T1=3.385h, T2=2.740h
第7趟B车选择A3,最短路径为3.9,路径为A3 -> A2 -> A8 -> A14
当前T1=3.385h, T2=3.520h
第8趟A车选择A10,最短路径为3.7,路径为A10 -> A9 -> A15 -> A14
当前T1=4.310h, T2=3.520h
第9趟B车选择A23,最短路径为3.7,路径为A23 -> A22 -> A21 -> A15 -> A14
当前T1=4.310h, T2=4.260h
第10趟B车选择A28,最短路径为3.7,路径为A28 -> A22 -> A21 -> A15 -> A14
当前T1=4.310h, T2=5.000h
第11趟A车选择A33,最短路径为3.5,路径为A33 -> A32 -> A26 -> A20 -> A14
当前T1=5.185h, T2=5.000h
第12趟B车选择A27,最短路径为3.4,路径为A27 -> A26 -> A20 -> A14
当前T1=5.185h, T2=5.680h
第13趟A车选择A22,最短路径为3.1,路径为A22 -> A21 -> A15 -> A14
当前T1=5.960h, T2=5.680h
第14趟B车选择A16,最短路径为2.9,路径为A16 -> A15 -> A14
当前T1=5.960h, T2=6.260h
第15趟A车选择A9,最短路径为2.9,路径为A9 -> A15 -> A14
当前T1=6.685h, T2=6.260h
第16趟B车选择A31,最短路径为2.9,路径为A31 -> A25 -> A19 -> A20 -> A14
当前T1=6.685h, T2=6.840h
第17趟A车选择A1,最短路径为2.8,路径为A1 -> A7 -> A13 -> A14
当前T1=7.385h, T2=6.840h
第18趟B车选择A30,最短路径为2.8,路径为A30 -> A24 -> A25 -> A19 -> A20 -> A14
当前T1=7.385h, T2=7.400h
第19趟A车选择A2,最短路径为2.8,路径为A2 -> A8 -> A14
当前T1=8.085h, T2=7.400h
第20趟B车选择A21,最短路径为2.6,路径为A21 -> A15 -> A14
当前T1=8.085h, T2=7.920h
第21趟B车选择A24,最短路径为2.3,路径为A24 -> A25 -> A19 -> A20 -> A14
当前T1=8.085h, T2=8.380h
第22趟A车选择A7,最短路径为2.2,路径为A7 -> A13 -> A14
当前T1=8.635h, T2=8.380h
第23趟B车选择A15,最短路径为2.2,路径为A15 -> A14
当前T1=8.635h, T2=8.820h
第24趟A车选择A6,最短路径为2.2,路径为A6 -> A12 -> A13 -> A14
当前T1=9.185h, T2=8.820h
第25趟B车选择A32,最短路径为2.1,路径为A32 -> A26 -> A20 -> A14
当前T1=9.185h, T2=9.240h
第26趟A车选择A18,最短路径为2.0,路径为A18 -> A12 -> A13 -> A14
当前T1=9.685h, T2=9.240h
分别用时:A机器人10.525小时, B机器人9.820小时
任务完成!总用时:10.525小时
问题二
对于该问题,问题一思路仍然适用,每个楼都有经过,只需在去的时候带上需要借的书即可
其中从驻地到图书馆最短路径上的书,在最后一趟返回驻地充电时,带上需要充的点即可
即B返回驻地途中,A12借3本,A6借2本
问题二结果
第1趟B车选择A5,最短路径为5.2,路径为A5 -> A11 -> A17 -> A16 -> A15 -> A14
第2趟A车选择A11,最短路径为4.5,路径为A11 -> A17 -> A16 -> A15 -> A14
第3趟B车选择A4,最短路径为4.4,路径为A4 -> A3 -> A2 -> A8 -> A14
A2借了1本书
A4借了2本书
第4趟A车选择A34,最短路径为4.1,路径为A34 -> A33 -> A32 -> A26 -> A20 -> A14
A20借了3本书
A32借了2本书
第5趟B车选择A29,最短路径为4.1,路径为A29 -> A23 -> A22 -> A21 -> A15 -> A14
第6趟A车选择A17,最短路径为3.9,路径为A17 -> A16 -> A15 -> A14
第7趟B车选择A3,最短路径为3.9,路径为A3 -> A2 -> A8 -> A14
第8趟A车选择A10,最短路径为3.7,路径为A10 -> A9 -> A15 -> A14
A10借了1本书
第9趟B车选择A23,最短路径为3.7,路径为A23 -> A22 -> A21 -> A15 -> A14
第10趟B车选择A28,最短路径为3.7,路径为A28 -> A22 -> A21 -> A15 -> A14
A28借了2本书
第11趟A车选择A33,最短路径为3.5,路径为A33 -> A32 -> A26 -> A20 -> A14
第12趟B车选择A27,最短路径为3.4,路径为A27 -> A26 -> A20 -> A14
第13趟A车选择A22,最短路径为3.1,路径为A22 -> A21 -> A15 -> A14
第14趟B车选择A16,最短路径为2.9,路径为A16 -> A15 -> A14
第15趟A车选择A9,最短路径为2.9,路径为A9 -> A15 -> A14
第16趟B车选择A31,最短路径为2.9,路径为A31 -> A25 -> A19 -> A20 -> A14
第17趟A车选择A1,最短路径为2.8,路径为A1 -> A7 -> A13 -> A14
第18趟B车选择A30,最短路径为2.8,路径为A30 -> A24 -> A25 -> A19 -> A20 -> A14
A24借了2本书
第19趟A车选择A2,最短路径为2.8,路径为A2 -> A8 -> A14
第20趟B车选择A21,最短路径为2.6,路径为A21 -> A15 -> A14
第21趟B车选择A24,最短路径为2.3,路径为A24 -> A25 -> A19 -> A20 -> A14
第22趟A车选择A7,最短路径为2.2,路径为A7 -> A13 -> A14
第23趟B车选择A15,最短路径为2.2,路径为A15 -> A14
第24趟A车选择A6,最短路径为2.2,路径为A6 -> A12 -> A13 -> A14
第25趟B车选择A32,最短路径为2.1,路径为A32 -> A26 -> A20 -> A14
第26趟A车选择A18,最短路径为2.0,路径为A18 -> A12 -> A13 -> A14
A18借了2本书
分别用时:A机器人10.525小时, B机器人9.820小时
任务完成!总用时:10.525小时
对应代码
图像生成代码
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import networkx as nx
# 设置中文字体,防止中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 创建图
G = nx.Graph()
# 添加边和权重
edges_with_weights = [
('A0', 'A1', 0.6), ('A1', 'A2', 0.3), ('A2', 'A3', 1.1), ('A3', 'A4', 0.5), ('A4', 'A5', 0.8),
('A6', 'A7', 0.5), ('A7', 'A8', 1.2), ('A8', 'A9', 1.8), ('A9', 'A10', 0.8), ('A10', 'A11', 1.0),
('A12', 'A13', 0.4), ('A13', 'A14', 1.1), ('A14', 'A15', 2.2), ('A15', 'A16', 0.7), ('A16', 'A17', 1.0),
('A18', 'A19', 0.9), ('A19', 'A20', 0.4),## (A20, A21, 不通湖泊)
('A21', 'A22', 0.5), ('A22', 'A23', 0.6),
('A24', 'A25', 0.3), ('A25', 'A26', 1.1), ('A26', 'A27', 2.1), ('A27', 'A28', 0.8), ('A28', 'A29', 1.1),
('A30', 'A31', 0.4), ('A31', 'A32', 0.9), ('A32', 'A33', 1.4), ('A33', 'A34', 0.6), ('A34', 'A35', 0.5),
('A0', 'A6', 0.7), ('A1', 'A7', 0.6), ('A2', 'A8', 1.5), ('A3', 'A9', 1.7), ('A4', 'A10', 2.0), ('A5', 'A11', 0.7),
('A6', 'A12', 0.7), ('A7', 'A13', 1.1), ('A8', 'A14', 1.3), ('A9', 'A15', 0.7), ('A10', 'A16', 1.0), ('A11', 'A17', 0.6),
('A12', 'A18', 0.5), ('A13', 'A19', 0.7), ('A14', 'A20', 1.0), ('A15', 'A21', 0.4), ('A16', 'A22', 0.5), ('A17', 'A23', 0.6),
('A18', 'A24', 1.1), ('A19', 'A25', 0.6), ('A20', 'A26', 0.3), ('A21', 'A27', 0.8), ('A22', 'A28', 0.6), ('A23', 'A29', 0.4),
('A24', 'A30', 0.5), ('A25', 'A31', 0.9), ('A26', 'A32', 0.8), ('A27', 'A33', 0.7), ('A28', 'A34', 0.5), ('A29', 'A35', 0.3)
]
G.add_weighted_edges_from(edges_with_weights)
# 按楼号优先纵行排列的节点位置
rows = 6 # 每行的节点数
pos = {f'A{i}': (i // rows, -(i % rows)) for i in range(36)}
# ...之前的代码...
# 设置节点标签,即楼号和楼名的组合
labels = {
'A0': 'A0 充电站robotB',
'A1': 'A1 四美楼',
'A2': 'A2 芳邻楼',
'A3': 'A3 凌云楼',
'A4': 'A4 远山楼',
'A5': 'A5 重霄楼',
'A6': 'A6 北辰楼',
'A7': 'A7 弥津楼',
'A8': 'A8 映雪楼',
'A9': 'A9 高洁楼',
'A10': 'A10 南溟楼',
'A11': 'A11 长洲楼',
'A12': 'A12 秋水楼',
'A13': 'A13 空地1',
'A14': 'A14 图书馆',
'A15': 'A15 临川楼',
'A16': 'A16 景明楼',
'A17': 'A17 清风楼',
'A18': 'A18 皓月楼',
'A19': 'A19 耸翠楼',
'A20': 'A20 朱华楼',
'A21': 'A21 空地2',
'A22': 'A22 绿竹楼',
'A23': 'A23 沉璧楼',
'A24': 'A24 雅望楼',
'A25': 'A25 朝晖楼',
'A26': 'A26 流丹楼',
'A27': 'A27 俊采楼',
'A28': 'A28 汀兰楼',
'A29': 'A29 兰亭楼',
'A30': 'A30 郁青楼',
'A31': 'A31 星耀楼',
'A32': 'A32 万千楼',
'A33': 'A33 东隅楼',
'A34': 'A34 长风楼',
'A35': 'A35 充电站robotA'
}
# 绘制图
plt.figure(figsize=(12, 8))
nx.draw(G, pos, labels=labels, with_labels=True, node_color='lightblue', node_size=500, font_size=10, font_family='SimHei')
# 添加边的权重标签
edge_labels = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=8, font_family='SimHei')
plt.title("加权无向图") # 标题也使用中文
plt.axis('off')
plt.tight_layout()
plt.savefig('学校各建筑与交通路线示意图.png')
plt.show()
各个楼号到图书馆的最短路径Dijkstra
#按最小路径 从高到低排序
import heapq
# 距离图
distances = {
('A0', 'A1'): 0.6, ('A1', 'A2'): 0.3, ('A2', 'A3'): 1.1, ('A3', 'A4'): 0.5,
('A4', 'A5'): 0.8, ('A6', 'A7'): 0.5, ('A7', 'A8'): 1.2, ('A8', 'A9'): 1.8,
('A9', 'A10'): 0.8, ('A10', 'A11'): 1.0, ('A12', 'A13'): 0.4, ('A13', 'A14'): 1.1,
('A14', 'A15'): 2.2, ('A15', 'A16'): 0.7, ('A16', 'A17'): 1.0, ('A18', 'A19'): 0.9,
('A19', 'A20'): 0.4, ('A20', 'A21'): 100, ('A21', 'A22'): 0.5, ('A22', 'A23'): 0.6,
('A24', 'A25'): 0.3, ('A25', 'A26'): 1.1, ('A26', 'A27'): 2.1, ('A27', 'A28'): 0.8,
('A28', 'A29'): 1.1, ('A30', 'A31'): 0.4, ('A31', 'A32'): 0.9, ('A32', 'A33'): 1.4,
('A33', 'A34'): 0.6, ('A34', 'A35'): 0.5, ('A0', 'A6'): 0.7, ('A1', 'A7'): 0.6,
('A2', 'A8'): 1.5, ('A3', 'A9'): 1.7, ('A4', 'A10'): 2.0, ('A5', 'A11'): 0.7,
('A6', 'A12'): 0.7, ('A7', 'A13'): 1.1, ('A8', 'A14'): 1.3, ('A9', 'A15'): 0.7,
('A10', 'A16'): 1.0, ('A11', 'A17'): 0.6, ('A12', 'A18'): 0.5, ('A13', 'A19'): 0.7,
('A14', 'A20'): 1.0, ('A15', 'A21'): 0.4, ('A16', 'A22'): 0.5, ('A17', 'A23'): 0.6,
('A18', 'A24'): 1.1, ('A19', 'A25'): 0.6, ('A20', 'A26'): 0.3, ('A21', 'A27'): 0.8,
('A22', 'A28'): 0.6, ('A23', 'A29'): 0.4, ('A24', 'A30'): 0.5, ('A25', 'A31'): 0.9,
('A26', 'A32'): 0.8, ('A27', 'A33'): 0.7, ('A28', 'A34'): 0.5, ('A29', 'A35'): 0.3
}
# 所有节点
nodes = set()
for (start, end) in distances.keys():
nodes.add(start)
nodes.add(end)
# 创建邻接表
graph = {node: {} for node in nodes}
for (start, end), dist in distances.items():
graph[start][end] = dist
graph[end][start] = dist
def dijkstra(source, target):
dist = {node: float('inf') for node in nodes}
dist[source] = 0
priority_queue = [(0, source)]
path = {node: [] for node in nodes}
while priority_queue:
current_dist, current_node = heapq.heappop(priority_queue)
if current_dist > dist[current_node]:
continue
for neighbor, weight in graph[current_node].items():
distance = current_dist + weight
if distance < dist[neighbor]:
dist[neighbor] = distance
path[neighbor] = path[current_node] + [current_node]
heapq.heappush(priority_queue, (distance, neighbor))
return dist[target], path[target] + [target]
# 计算每个节点到A14的最短路径
shortest_paths = {}
for node in nodes:
if node != 'A14':
shortest_distance, shortest_path = dijkstra(node, 'A14')
shortest_paths[node] = (shortest_distance, shortest_path)
# 按路径从高到低排序
sorted_paths = dict(sorted(shortest_paths.items(), key=lambda item: item[1][0], reverse=True))
# 输出结果
for node, (distance, path) in sorted_paths.items():
print(f'{node}-A14={distance:.1f}, 路径为{"->".join(path)}')
# print(f'{node}最短路径为:{distance:.1f}')
问题一
#第一题
# 初始化数据
Return_book = { #还书量
'A1': 3, 'A2': 4, 'A3': 2, 'A4': 5, 'A5': 6, 'A6': 6, 'A7': 5, 'A8': 2, 'A9': 4, 'A10': 3,
'A11': 6, 'A12': 4, 'A13': 0, 'A14': 0, 'A15': 3, 'A16': 6, 'A17': 2, 'A18': 7, 'A19': 4, 'A20': 2,
'A21': 0, 'A22': 3, #A22被A车拿走两本 A22=5-2=3
'A23': 6, 'A24': 5, 'A25': 3, 'A26': 8, 'A27': 3, 'A28': 6, 'A29': 2, 'A30': 3,
'A31': 4, 'A32': 2, 'A33': 1, 'A34': 5
}
Borrow_books = { #借书
'A2': 1,'A4': 2,'A10': 1,'A18': 2,'A20': 3,'A24': 2,'A28': 2,'A32': 2
}
distances_and_paths = {
'A5': (5.2, ['A5', 'A11', 'A17', 'A16', 'A15', 'A14']),
'A11': (4.5, ['A11', 'A17', 'A16', 'A15', 'A14']),
'A4': (4.4, ['A4', 'A3', 'A2', 'A8', 'A14']),
'A34': (4.1, ['A34', 'A33', 'A32', 'A26', 'A20', 'A14']),
'A29': (4.1, ['A29', 'A23', 'A22', 'A21', 'A15', 'A14']),
'A17': (3.9, ['A17', 'A16', 'A15', 'A14']),
'A3': (3.9, ['A3', 'A2', 'A8', 'A14']),
'A10': (3.7, ['A10', 'A9', 'A15', 'A14']),
'A23': (3.7, ['A23', 'A22', 'A21', 'A15', 'A14']),
'A28': (3.7, ['A28', 'A22', 'A21', 'A15', 'A14']),
'A33': (3.5, ['A33', 'A32', 'A26', 'A20', 'A14']),
'A27': (3.4, ['A27', 'A26', 'A20', 'A14']),
'A22': (3.1, ['A22', 'A21', 'A15', 'A14']),
'A16': (2.9, ['A16', 'A15', 'A14']),
'A9': (2.9, ['A9', 'A15', 'A14']),
'A31': (2.9, ['A31', 'A25', 'A19', 'A20', 'A14']),
'A1': (2.8, ['A1', 'A7', 'A13', 'A14']),
'A30': (2.8, ['A30', 'A24', 'A25', 'A19', 'A20', 'A14']),
'A2': (2.8, ['A2', 'A8', 'A14']),
'A21': (2.6, ['A21', 'A15', 'A14']),
'A24': (2.3, ['A24', 'A25', 'A19', 'A20', 'A14']),
'A7': (2.2, ['A7', 'A13', 'A14']),
'A15': (2.2, ['A15', 'A14']),
'A6': (2.2, ['A6', 'A12', 'A13', 'A14']),
'A32': (2.1, ['A32', 'A26', 'A20', 'A14']),
'A18': (2.0, ['A18', 'A12', 'A13', 'A14']),
'A25': (2.0, ['A25', 'A19', 'A20', 'A14']),
'A12': (1.5, ['A12', 'A13', 'A14']),
'A19': (1.4, ['A19', 'A20', 'A14']),
'A26': (1.3, ['A26', 'A20', 'A14']),
'A8': (1.3, ['A8', 'A14']),
'A13': (1.1, ['A13', 'A14']),
'A20': (1.0, ['A20', 'A14'])
}
speed_A, speed_B = 8, 10
T1, T2 = 0.26, 0
def collect_books(car, target):
global Return_book, T1, T2
C = 10
distance, path = distances_and_paths[target]
print(f"第{trip}趟{car}车选择{target},最短路径为{distance},路径为{' -> '.join(path)}")
for point in path[:-1]: # 不包括A14
if C == 0:
break
if Return_book[point] <= C:
C -= Return_book[point]
# print(f"{point}书本量{Return_book[point]}小于等于当前容量{C+Return_book[point]},被取走所有的书")
Return_book[point] = 0
else:
# print(f"{point}书本量{Return_book[point]}大于当前容量{C},取走{C}本书")
Return_book[point] -= C
C = 0
if car == 'A':
T1 += distance * 2 / speed_A
else:
T2 += distance * 2 / speed_B
print(f"当前T1={T1:.3f}h, T2={T2:.3f}h") #当前时间
# 主循环
trip = 1
for target in distances_and_paths.keys():
if T1 <= T2:
car = 'A'
else:
car = 'B'
collect_books(car, target)
print()
trip += 1
if sum(Return_book.values()) == 0:
break
T1+=0.29+0.55; #把B机器人到达图书馆记为0时刻
T2+=0.29*2;
print(f"分别用时:A机器人{T1:.3f}小时, B机器人{T2:.3f}小时")
print(f"任务完成!总用时:{max(T1, T2):.3f}小时")
问题二
#第二题
# 初始化数据
Return_book = { #还书量
'A1': 3, 'A2': 4, 'A3': 2, 'A4': 5, 'A5': 6, 'A6': 6, 'A7': 5, 'A8': 2, 'A9': 4, 'A10': 3,
'A11': 6, 'A12': 4, 'A13': 0, 'A14': 0, 'A15': 3, 'A16': 6, 'A17': 2, 'A18': 7, 'A19': 4, 'A20': 2,
'A21': 0, 'A22': 3, #A22被A车拿走两本 A22=5-2=3
'A23': 6, 'A24': 5, 'A25': 3, 'A26': 8, 'A27': 3, 'A28': 6, 'A29': 2, 'A30': 3,
'A31': 4, 'A32': 2, 'A33': 1, 'A34': 5
}
Borrow_books = { #借书
'A2': 1,'A4': 2,'A10': 1,'A18': 2,'A20': 3,'A24': 2,'A28': 2,'A32': 2
}
distances_and_paths = {
'A5': (5.2, ['A5', 'A11', 'A17', 'A16', 'A15', 'A14']),
'A11': (4.5, ['A11', 'A17', 'A16', 'A15', 'A14']),
'A4': (4.4, ['A4', 'A3', 'A2', 'A8', 'A14']),
'A34': (4.1, ['A34', 'A33', 'A32', 'A26', 'A20', 'A14']),
'A29': (4.1, ['A29', 'A23', 'A22', 'A21', 'A15', 'A14']),
'A17': (3.9, ['A17', 'A16', 'A15', 'A14']),
'A3': (3.9, ['A3', 'A2', 'A8', 'A14']),
'A10': (3.7, ['A10', 'A9', 'A15', 'A14']),
'A23': (3.7, ['A23', 'A22', 'A21', 'A15', 'A14']),
'A28': (3.7, ['A28', 'A22', 'A21', 'A15', 'A14']),
'A33': (3.5, ['A33', 'A32', 'A26', 'A20', 'A14']),
'A27': (3.4, ['A27', 'A26', 'A20', 'A14']),
'A22': (3.1, ['A22', 'A21', 'A15', 'A14']),
'A16': (2.9, ['A16', 'A15', 'A14']),
'A9': (2.9, ['A9', 'A15', 'A14']),
'A31': (2.9, ['A31', 'A25', 'A19', 'A20', 'A14']),
'A1': (2.8, ['A1', 'A7', 'A13', 'A14']),
'A30': (2.8, ['A30', 'A24', 'A25', 'A19', 'A20', 'A14']),
'A2': (2.8, ['A2', 'A8', 'A14']),
'A21': (2.6, ['A21', 'A15', 'A14']),
'A24': (2.3, ['A24', 'A25', 'A19', 'A20', 'A14']),
'A7': (2.2, ['A7', 'A13', 'A14']),
'A15': (2.2, ['A15', 'A14']),
'A6': (2.2, ['A6', 'A12', 'A13', 'A14']),
'A32': (2.1, ['A32', 'A26', 'A20', 'A14']),
'A18': (2.0, ['A18', 'A12', 'A13', 'A14']),
'A25': (2.0, ['A25', 'A19', 'A20', 'A14']),
'A12': (1.5, ['A12', 'A13', 'A14']),
'A19': (1.4, ['A19', 'A20', 'A14']),
'A26': (1.3, ['A26', 'A20', 'A14']),
'A8': (1.3, ['A8', 'A14']),
'A13': (1.1, ['A13', 'A14']),
'A20': (1.0, ['A20', 'A14'])
}
speed_A, speed_B = 8, 10
T1, T2 = 0.26, 0
# 定义一个全局集合,用于跟踪已经输出过的借书点
outputted_borrowed_points = set()
def collect_books(car, target):
global Return_book, T1, T2, Borrow_books, outputted_borrowed_points
C = 10
distance, path = distances_and_paths[target]
borrowed_points = [] # 存储借书的点和数量
print(f"第{trip}趟{car}车选择{target},最短路径为{distance},路径为{' -> '.join(path)}")
# 收集书本
for point in path[:-1]: # 不包括A14
if C == 0:
break
if point in Borrow_books: # 如果当前点有借书记录
if point not in outputted_borrowed_points: # 检查是否已经输出过
borrowed_points.append((point, Borrow_books[point])) # 记录借书点和数量
outputted_borrowed_points.add(point) # 标记为已输出
if Return_book[point] <= C:
C -= Return_book[point]
Return_book[point] = 0
# print(f"{point}书本量{Return_book[point]}小于等于当前容量{C},被取走所有的书")
else:
C -= Return_book[point]
# print(f"{point}书本量{Return_book[point]}大于当前容量{C},取走{Return_book[point]}本书")
Return_book[point] = C
# 逆序输出借书的点和数量
if borrowed_points:
for point, quantity in reversed(borrowed_points): # 使用 reversed 函数逆序输出
print(f"{point}借了{quantity}本书")
if car == 'A':
T1 += distance * 2 / speed_A
else:
T2 += distance * 2 / speed_B
# print(f"当前T1={T1:.3f}h, T2={T2:.3f}h") # 当前时间
# 主循环
trip = 1
for target in distances_and_paths.keys():
if T1 <= T2:
car = 'A'
else:
car = 'B'
collect_books(car, target)
print()
trip += 1
if sum(Return_book.values()) == 0:
break
T1 += 0.29 + 0.55 # 把B机器人到达图书馆记为0时刻
T2 += 0.29 * 2
print(f"分别用时:A机器人{T1:.3f}小时, B机器人{T2:.3f}小时")
print(f"任务完成!总用时:{max(T1, T2):.3f}小时")