import torch
import pandas as pd
import time
from heapq import heappush, heappop
# 检查GPU可用性
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"使用设备: {device}")
# 读取数据 - 使用GPU张量存储
def load_data_gpu():
# 读取BOSS位置 (10个)
boss_df = pd.read_excel('boss.xls', header=None)
boss_pos = torch.tensor(boss_df.iloc[1:11, 2:4].values, device=device, dtype=torch.float32)
# 读取玩家位置 (10个)
player_df = pd.read_excel('player.xls', header=None)
player_pos = torch.tensor(player_df.iloc[1:11, 2:4].values, device=device, dtype=torch.float32)
# 读取BOSS消灭条件
count_df = pd.read_excel('count.xls', header=None)
conditions = []
for k in range(10):
start_row = 2 + 3*k
conds = count_df.iloc[start_row:start_row+3, 2].tolist()
conditions.append(conds)
kill_conditions = torch.tensor(conditions, device=device, dtype=torch.int32)
return boss_pos, player_pos, kill_conditions
# GPU加速的距离计算
def calc_distance_gpu(players_pos, bosses_pos):
# 使用广播计算所有玩家到所有BOSS的距离矩阵 [10, 10]
diff = players_pos.unsqueeze(1) - bosses_pos.unsqueeze(0)
return torch.norm(diff, dim=2)
# 主模拟函数 - GPU优化版
def simulate_gpu():
# 加载数据到GPU
boss_pos, player_pos, kill_conditions = load_data_gpu()
# 玩家配置 (GPU张量)
player_types = torch.tensor([0]*3 + [1]*3 + [2]*4, device=device)
attack_range = torch.tensor([100, 50, 20], device=device)
move_speed = torch.tensor([50, 30, 20], device=device)
clone_num = torch.tensor([3, 3, 4], device=device)
cooldown = torch.tensor([7, 9, 11], device=device)
# 初始化状态 (保持在GPU)
boss_counts = torch.zeros((10, 3), device=device, dtype=torch.int32)
boss_alive = torch.ones(10, device=device, dtype=torch.bool)
# 预计算距离矩阵 (所有玩家到所有BOSS)
distance_matrix = calc_distance_gpu(player_pos, boss_pos)
# 事件队列 (CPU端,因为heapq不支持GPU)
event_queue = []
# GPU计时器
start_time = time.time()
# 初始化事件
for pid in range(10):
heappush(event_queue, (0.0, 'produce', pid))
# 主循环
while event_queue and torch.any(boss_alive).item():
current_time, event_type, *args = heappop(event_queue)
if event_type == 'produce':
pid = args[0]
ptype = player_types[pid].item()
# 安排下次生产
heappush(event_queue, (current_time + cooldown[ptype].item(), 'produce', pid))
# 获取当前玩家到所有BOSS的距离
player_distances = distance_matrix[pid]
# GPU计算有效目标
in_range = player_distances <= attack_range[ptype]
alive_mask = boss_alive
valid_mask = in_range & alive_mask
# 获取有效目标的索引
valid_targets = torch.nonzero(valid_mask).flatten().tolist()
if valid_targets:
# 为每个分身分配目标 (循环选择)
for i in range(clone_num[ptype].item()):
bid = valid_targets[i % len(valid_targets)]
move_time = player_distances[bid].item() / move_speed[ptype].item()
attack_time = current_time + move_time
heappush(event_queue, (attack_time, 'attack', bid, ptype))
elif event_type == 'attack':
bid, ptype = args
if boss_alive[bid].item():
# GPU上的原子更新
boss_counts[bid, ptype] += 1
# 检查BOSS是否被消灭 (GPU计算)
if torch.any(boss_counts[bid] >= kill_conditions[bid]).item():
boss_alive[bid] = False
print(f"时间 {current_time:.2f}: BOSS {bid+1} 被消灭")
# 输出性能数据
gpu_time = time.time() - start_time
print(f"\nGPU模拟完成 | 耗时: {gpu_time:.4f}秒")
# 检查结果
if torch.any(boss_alive).item():
alive_bosses = torch.nonzero(boss_alive).flatten().tolist()
print(f"剩余未消灭BOSS: {[b+1 for b in alive_bosses]}")
else:
print("所有BOSS已被消灭")
# 运行GPU加速模拟
if __name__ == "__main__":
simulate_gpu()
tensor([[604.3253, 650.9685, 418.0730, 212.8004, 378.7242, 522.2576, 497.6525,
370.1378, 498.7444, 258.2131, 278.1672, 764.1989, 423.3592, 475.1431,
720.3361, 565.1071, 385.5606, 608.8095, 517.3200, 476.3213, 348.9370,
610.4376, 793.3631, 235.5525, 216.0949, 574.6381, 451.3635, 237.8445,
302.2383, 668.1953],
[648.8344, 706.4142, 452.8156, 259.3704, 450.7605, 602.4699, 569.5516,
365.2465, 581.3098, 319.8828, 308.5612, 814.8798, 433.8203, 553.5648,
771.2283, 650.8372, 438.7710, 695.8448, 490.1234, 551.2939, 426.3824,
697.8775, 838.2888, 291.7807, 247.4914, 657.8282, 467.5233, 281.8102,
289.3596, 712.0927],
[612.4549, 652.3956, 432.9307, 226.2918, 370.1297, 504.4016, 488.0594,
401.0112, 478.1318, 260.3113, 297.5987, 768.0234, 448.5187, 459.5182,
724.2155, 539.4089, 390.6930, 580.1181, 553.1148, 464.1228, 335.4892,
580.4291, 800.3605, 242.2003, 237.0844, 552.8879, 474.0517, 251.7816,
336.1547, 676.2995],
[604.8223, 652.0345, 418.0072, 213.0376, 380.6639, 524.8104, 499.6248,
368.3925, 501.4828, 259.4012, 277.7373, 765.0444, 422.2464, 477.5542,
721.1830, 568.1487, 386.3936, 612.0164, 514.9185, 478.4903, 351.2407,
613.7141, 793.9294, 236.3810, 215.5737, 577.4374, 450.5042, 238.0021,
300.1350, 668.6823],
[633.9417, 695.4315, 435.6902, 248.7670, 448.7460, 605.1529, 566.8589,
338.9528, 586.0691, 314.0717, 291.6059, 801.7637, 410.3072, 555.0585,
758.2908, 659.0182, 428.1682, 706.2690, 460.3140, 550.4988, 427.8154,
709.3976, 823.0480, 284.1549, 232.0776, 663.0068, 445.1719, 269.7795,
262.1851, 696.7955],
[606.8492, 636.6326, 439.6021, 237.1181, 343.4312, 463.3724, 458.2194,
433.8905, 433.8029, 252.6599, 314.2388, 755.0397, 471.2282, 421.8080,
711.5511, 488.6686, 383.5101, 526.0342, 594.0413, 430.9768, 302.6450,
525.0381, 791.8839, 242.1570, 258.2789, 506.6932, 492.4409, 261.9637,
375.2026, 670.1791],
[687.4838, 737.0054, 497.0010, 294.9661, 465.2365, 605.1264, 584.0419,
425.8932, 579.5904, 344.6752, 354.1892, 849.3062, 489.5385, 559.2799,
805.4595, 640.8502, 470.7441, 680.4234, 556.0009, 561.9475, 433.9424,
679.9155, 876.8854, 320.8613, 291.8150, 654.5304, 521.0470, 319.3196,
351.6888, 751.2469],
[607.2133, 649.5822, 425.2293, 218.6801, 370.8275, 508.8418, 489.2617,
388.1559, 483.6621, 256.7976, 288.2013, 764.3854, 437.4403, 463.0421,
720.5422, 547.0585, 386.3392, 589.0416, 538.9109, 466.3100, 338.0178,
589.9161, 795.5941, 237.0021, 227.0551, 558.9204, 463.7801, 244.1004,
322.3988, 671.0961],
[590.5396, 617.1710, 428.1600, 229.2597, 321.7266, 438.6172, 435.4698,
433.5366, 408.7077, 237.5416, 307.6508, 736.2201, 466.0869, 397.5739,
692.8781, 463.3897, 367.4412, 501.0998, 597.1465, 407.5709, 279.6086,
500.3699, 774.3726, 229.9761, 254.3325, 481.4489, 485.3792, 253.4285,
378.2274, 653.5817],
[626.5030, 679.2650, 434.3294, 234.2926, 415.9868, 564.3846, 535.0037,
364.5888, 542.2186, 289.0069, 291.0842, 789.9930, 426.3567, 516.2112,
746.1990, 610.4335, 412.0437, 654.9046, 500.8403, 515.4076, 389.3096,
656.7747, 816.0319, 262.9753, 228.8056, 618.4966, 457.5784, 258.1027,
291.8716, 690.1420],
[631.8109, 691.0355, 434.9172, 243.9057, 439.7658, 594.2432, 558.2401,
345.3230, 574.3483, 306.7768, 290.6424, 798.6000, 414.1896, 544.6146,
755.0165, 646.0959, 423.4725, 692.6305, 471.0266, 541.0250, 417.3356,
695.4279, 821.1608, 277.7427, 230.0543, 651.1505, 448.1261, 265.7593,
269.4624, 694.9252],
[643.6909, 698.3159, 449.8111, 252.2400, 437.3843, 586.4213, 556.3677,
371.6140, 564.3093, 309.1812, 305.9444, 808.2258, 436.8112, 538.1542,
764.4769, 632.3488, 430.8364, 676.5117, 502.0488, 537.0819, 411.1958,
678.1777, 833.2419, 282.3969, 244.0492, 640.5825, 469.2398, 275.5449,
297.1346, 707.1973],
[610.1705, 643.0031, 438.9852, 234.4803, 352.6145, 476.9319, 468.5392,
425.2823, 448.2689, 255.7206, 310.2580, 760.6767, 465.8004, 434.3731,
717.0641, 504.9208, 386.9393, 543.1556, 583.0823, 442.2273, 313.5602,
542.4767, 796.2073, 242.8374, 252.6697, 521.7279, 488.3646, 259.6786,
364.5888, 673.7136],
[592.8887, 621.9277, 427.2295, 226.0487, 328.4418, 448.9733, 443.2336,
426.5302, 419.7761, 238.9477, 303.7976, 740.4661, 461.5247, 407.1179,
697.0065, 475.8571, 369.5795, 514.2188, 588.6000, 416.0625, 287.6891,
513.7198, 777.6149, 229.4014, 249.0000, 492.9756, 481.8765, 250.6392,
369.6404, 656.1440],
[672.3585, 714.3116, 489.1237, 282.9364, 432.3482, 563.5690, 550.0446,
440.3237, 535.7621, 321.7530, 350.2713, 829.4390, 495.6006, 519.8019,
785.6036, 592.7470, 451.5086, 630.0000, 582.0662, 525.5521, 396.7896,
628.5801, 860.7834, 302.1854, 288.3609, 609.5392, 523.8110, 308.2483,
370.2283, 736.2445],
[625.9281, 683.1142, 430.4440, 236.1038, 428.1600, 581.1110, 546.8574,
347.9382, 560.6505, 296.6968, 286.2621, 791.7203, 414.1980, 531.8364,
748.0541, 631.6051, 415.4708, 677.7197, 478.0847, 528.9811, 404.5862,
680.3418, 815.4164, 268.4772, 224.9000, 637.3461, 447.1801, 258.6445,
273.1904, 689.2460],
[611.2234, 638.8622, 446.5356, 245.4486, 343.7397, 459.6194, 457.4505,
444.7977, 429.1305, 257.6140, 323.1254, 757.7552, 480.7036, 419.0585,
714.3704, 481.8765, 387.9845, 518.0154, 605.7863, 429.4240, 301.5593,
516.5123, 795.5099, 248.6202, 268.0298, 501.3522, 501.2325, 270.0537,
386.8811, 674.3827],
[616.1859, 665.6876, 426.9860, 223.7320, 397.3965, 543.0994, 516.4203,
368.5458, 520.1327, 273.7480, 285.2034, 777.8046, 425.9589, 495.5290,
733.9591, 587.1917, 399.2606, 631.1204, 510.6545, 495.8488, 368.9783,
632.7922, 805.5315, 249.4253, 222.7847, 596.1854, 455.5403, 248.2781,
298.1677, 679.9802],
[601.8480, 639.3012, 425.4844, 219.3126, 354.3586, 486.4001, 471.8517,
402.3183, 459.7130, 248.3949, 292.8566, 755.6679, 446.2118, 441.9604,
711.9115, 520.4651, 379.3481, 561.0927, 557.8405, 447.3030, 318.5545,
561.4339, 789.1470, 232.1659, 233.5744, 534.2968, 470.3329, 244.7693,
339.8147, 665.6133],
[647.3523, 680.5248, 474.4102, 268.8680, 389.4226, 510.1186, 504.7772,
452.0708, 480.1042, 292.9573, 343.2098, 798.2092, 496.8470, 468.7569,
754.5926, 532.8865, 424.1992, 568.1981, 605.2653, 477.8159, 349.3780,
566.1272, 833.6000, 279.2508, 284.1778, 552.5115, 520.8541, 294.2448,
388.1057, 710.9437]])这个是距离矩阵distance_matrix,但实际上 attack_range = torch.tensor([1000.0, 750.0, 550.0], device=device) # 确保为浮点数,为什么不能完全消灭完,而attack_range = torch.tensor([10000.0, 750.0, 550.0]就可以打完