dsh-eval-guard 0.2.3 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/README.md +91 -13
  2. package/assets/commit0/instance.json +30 -0
  3. package/assets/commit0/workspace.zip +0 -0
  4. package/assets/featurebench/hidden/test_regression.py +690 -0
  5. package/assets/featurebench/instance.json +16 -0
  6. package/assets/featurebench/workspace.zip +0 -0
  7. package/assets/swe-bench-pro/hidden/test.patch +36 -0
  8. package/assets/swe-bench-pro/instance.json +10 -0
  9. package/assets/swe-bench-pro/workspace.zip +0 -0
  10. package/eval/README.md +18 -0
  11. package/eval/arena/arena/README.md +21 -0
  12. package/eval/arena/arena/bt.py +104 -0
  13. package/eval/arena/arena/clock.py +15 -0
  14. package/eval/arena/arena/core.py +265 -0
  15. package/eval/arena/arena/run.cmd +24 -0
  16. package/eval/arena/arena/run.sh +11 -0
  17. package/eval/arena/arena/schedule.py +79 -0
  18. package/eval/arena/arena/tournament.py +183 -0
  19. package/eval/arena/bomberman/bots/README.md +16 -0
  20. package/eval/arena/bomberman/bots/deepseek-v4.1-flash.cpp +447 -0
  21. package/eval/arena/bomberman/bots/doubao-seed-2.1.cpp +542 -0
  22. package/eval/arena/bomberman/bots/glm-5.3.cpp +406 -0
  23. package/eval/arena/bomberman/bots/gpt-6-astra.cpp +768 -0
  24. package/eval/arena/bomberman/bots/gpt-6-sol.cpp +444 -0
  25. package/eval/arena/bomberman/bots/kimi-k3.cpp +432 -0
  26. package/eval/arena/bomberman/bots/mimo-v2.6-pro.cpp +529 -0
  27. package/eval/arena/bomberman/bots/opus-5.5.cpp +548 -0
  28. package/eval/arena/bomberman/bots/qwen-3.8-max.cpp +836 -0
  29. package/eval/arena/bomberman/tournament/README.md +11 -0
  30. package/eval/arena/bomberman/tournament/bt.py +56 -0
  31. package/eval/arena/bomberman/tournament/evaluate.py +199 -0
  32. package/eval/arena/bomberman/tournament/run.py +79 -0
  33. package/eval/arena/bomberman/tournament/schedule-2to10.json.gz +0 -0
  34. package/eval/arena/bomberman/workspace/MANIFEST.json +13 -0
  35. package/eval/arena/bomberman/workspace/README.md +29 -0
  36. package/eval/arena/bomberman/workspace/RULES.md +100 -0
  37. package/eval/arena/bomberman/workspace/baseline.cpp +240 -0
  38. package/eval/arena/bomberman/workspace/clock.py +25 -0
  39. package/eval/arena/bomberman/workspace/engine/arena.py +198 -0
  40. package/eval/arena/bomberman/workspace/engine/build.py +35 -0
  41. package/eval/arena/bomberman/workspace/engine/engine.py +256 -0
  42. package/eval/arena/bomberman/workspace/engine/verify_replay.py +24 -0
  43. package/eval/arena/bomberman/workspace/run.cmd +28 -0
  44. package/eval/arena/bomberman/workspace/run.sh +16 -0
  45. package/eval/arena/bomberman/workspace/viewer/index.html +42 -0
  46. package/eval/arena/ctf/bots/README.md +18 -0
  47. package/eval/arena/ctf/bots/deepseek-v4.1-flash.cpp +601 -0
  48. package/eval/arena/ctf/bots/doubao-seed-2.1-turbo.cpp +320 -0
  49. package/eval/arena/ctf/bots/fable-5.1.cpp +634 -0
  50. package/eval/arena/ctf/bots/glm-5.3.cpp +689 -0
  51. package/eval/arena/ctf/bots/gpt-6-astra.cpp +657 -0
  52. package/eval/arena/ctf/bots/gpt-6.1-sol.cpp +725 -0
  53. package/eval/arena/ctf/bots/kimi-k3.cpp +667 -0
  54. package/eval/arena/ctf/bots/mimo-v2.6-pro.cpp +533 -0
  55. package/eval/arena/ctf/bots/opus-5.5.cpp +645 -0
  56. package/eval/arena/ctf/bots/qwen-3.8-max.cpp +726 -0
  57. package/eval/arena/ctf/bots/sonnet-5.5.cpp +569 -0
  58. package/eval/arena/ctf/tournament/README.md +15 -0
  59. package/eval/arena/ctf/tournament/formal-2to8.json +31 -0
  60. package/eval/arena/ctf/tournament/formal-9to15.json +31 -0
  61. package/eval/arena/ctf/workspace/README.md +41 -0
  62. package/eval/arena/ctf/workspace/RULES.md +119 -0
  63. package/eval/arena/ctf/workspace/arena.py +186 -0
  64. package/eval/arena/ctf/workspace/baseline.cpp +257 -0
  65. package/eval/arena/ctf/workspace/clock.py +15 -0
  66. package/eval/arena/ctf/workspace/core.py +265 -0
  67. package/eval/arena/ctf/workspace/engine.py +389 -0
  68. package/eval/arena/ctf/workspace/run.cmd +24 -0
  69. package/eval/arena/ctf/workspace/run.sh +11 -0
  70. package/eval/arena/ctf/workspace/viewer.html +71 -0
  71. package/eval/arena/land/bots/README.md +17 -0
  72. package/eval/arena/land/bots/deepseek-4.1f@workbuddy#1/bot.cpp +608 -0
  73. package/eval/arena/land/bots/glm-5.3@workbuddy#1/bot.cpp +521 -0
  74. package/eval/arena/land/bots/gpt-6-astra@codex#1/bot.cpp +373 -0
  75. package/eval/arena/land/bots/gpt-6-sol@codex#1/bot.cpp +341 -0
  76. package/eval/arena/land/bots/kimi-k3@workbuddy#1/bot.cpp +492 -0
  77. package/eval/arena/land/bots/mimo-2.6-pro@zcode#1/bot.cpp +652 -0
  78. package/eval/arena/land/bots/mystery-model@zcode#1/bot.cpp +466 -0
  79. package/eval/arena/land/bots/opus-5.5@claude-code#1/bot.cpp +630 -0
  80. package/eval/arena/land/bots/sonnet-5@claude-code#1/bot.cpp +619 -0
  81. package/eval/arena/land/tournament/make_replay_page.py +17 -0
  82. package/eval/arena/land/tournament/rate.py +290 -0
  83. package/eval/arena/land/tournament/round_robin.py +172 -0
  84. package/eval/arena/land/tournament/sparring.cpp +356 -0
  85. package/eval/arena/land/workspace/RULES.md +114 -0
  86. package/eval/arena/land/workspace/TASK.md +46 -0
  87. package/eval/arena/land/workspace/anchors/.build/greedy_f2e6d2dea5ca +0 -0
  88. package/eval/arena/land/workspace/anchors/greedy.cpp +194 -0
  89. package/eval/arena/land/workspace/anchors/random.cpp +80 -0
  90. package/eval/arena/land/workspace/clock.py +64 -0
  91. package/eval/arena/land/workspace/engine/build.py +33 -0
  92. package/eval/arena/land/workspace/engine/game.py +273 -0
  93. package/eval/arena/land/workspace/engine/referee.py +308 -0
  94. package/eval/arena/land/workspace/starter/.build/bot_be32b45b4699 +0 -0
  95. package/eval/arena/land/workspace/starter/bot.cpp +82 -0
  96. package/eval/arena/land/workspace/viewer/viewer.html +210 -0
  97. package/eval/arena/tank/bots/README.md +24 -0
  98. package/eval/arena/tank/bots/half1/deepseek-v4.1-flash.cpp +367 -0
  99. package/eval/arena/tank/bots/half1/doubao-seed-evolving.cpp +402 -0
  100. package/eval/arena/tank/bots/half1/gemini-4-argon.cpp +1132 -0
  101. package/eval/arena/tank/bots/half1/glm-5.3.cpp +551 -0
  102. package/eval/arena/tank/bots/half1/gpt-6-astra.cpp +233 -0
  103. package/eval/arena/tank/bots/half1/gpt-6.1-sol-ultrafast.cpp +350 -0
  104. package/eval/arena/tank/bots/half1/gpt-6.1-sol.cpp +78 -0
  105. package/eval/arena/tank/bots/half1/grok-4.7.cpp +1099 -0
  106. package/eval/arena/tank/bots/half1/haiku-5.5.cpp +210 -0
  107. package/eval/arena/tank/bots/half1/kimi-k3.cpp +353 -0
  108. package/eval/arena/tank/bots/half1/mimo-v2.6-pro.cpp +336 -0
  109. package/eval/arena/tank/bots/half1/muse-wonder-full.cpp +560 -0
  110. package/eval/arena/tank/bots/half1/opus-5.5.cpp +435 -0
  111. package/eval/arena/tank/bots/half1/qwen-3.8-max.cpp +537 -0
  112. package/eval/arena/tank/bots/half2/deepseek-v4.1-flash.cpp +425 -0
  113. package/eval/arena/tank/bots/half2/doubao-seed-evolving.cpp +308 -0
  114. package/eval/arena/tank/bots/half2/gemini-4-argon.cpp +1390 -0
  115. package/eval/arena/tank/bots/half2/glm-5.3.cpp +651 -0
  116. package/eval/arena/tank/bots/half2/gpt-6-astra.cpp +241 -0
  117. package/eval/arena/tank/bots/half2/gpt-6.1-sol-ultrafast.cpp +356 -0
  118. package/eval/arena/tank/bots/half2/gpt-6.1-sol.cpp +87 -0
  119. package/eval/arena/tank/bots/half2/grok-4.7.cpp +1205 -0
  120. package/eval/arena/tank/bots/half2/haiku-5.5.cpp +210 -0
  121. package/eval/arena/tank/bots/half2/kimi-k3.cpp +487 -0
  122. package/eval/arena/tank/bots/half2/mimo-v2.6-pro.cpp +336 -0
  123. package/eval/arena/tank/bots/half2/muse-wonder-full.cpp +560 -0
  124. package/eval/arena/tank/bots/half2/opus-5.5.cpp +476 -0
  125. package/eval/arena/tank/bots/half2/qwen-3.8-max.cpp +392 -0
  126. package/eval/arena/tank/tournament/README.md +24 -0
  127. package/eval/arena/tank/tournament/bt.py +218 -0
  128. package/eval/arena/tank/tournament/final.json +202 -0
  129. package/eval/arena/tank/tournament/halftime.json +146 -0
  130. package/eval/arena/tank/tournament/progress.json +911 -0
  131. package/eval/arena/tank/tournament/schedule.py +100 -0
  132. package/eval/arena/tank/tournament/sparring.cpp +928 -0
  133. package/eval/arena/tank/tournament/tournament.py +1426 -0
  134. package/eval/arena/tank/workspace/README.md +169 -0
  135. package/eval/arena/tank/workspace/RULES.md +443 -0
  136. package/eval/arena/tank/workspace/arena.py +862 -0
  137. package/eval/arena/tank/workspace/baseline.cpp +259 -0
  138. package/eval/arena/tank/workspace/clock.py +103 -0
  139. package/eval/arena/tank/workspace/core.py +712 -0
  140. package/eval/arena/tank/workspace/engine.py +573 -0
  141. package/eval/arena/tank/workspace/history/.lock +0 -0
  142. package/eval/arena/tank/workspace/history/20261017-193610-08715287f91f-bot.cpp +109 -0
  143. package/eval/arena/tank/workspace/history/20261017-193619-f00b2d5635fa-gpt-6-astra.cpp +241 -0
  144. package/eval/arena/tank/workspace/history/20261017-193643-63319e0a2b1a-gpt-6_1-sol-ultrafast.cpp +356 -0
  145. package/eval/arena/tank/workspace/history/20261017-193647-41c1341d0a8a-gemini-4-argon.cpp +1390 -0
  146. package/eval/arena/tank/workspace/history/20261017-193652-e34c0f45539a-gpt-6_1-sol.cpp +87 -0
  147. package/eval/arena/tank/workspace/history/20261017-193654-c026348ce96e-opus-5_5.cpp +476 -0
  148. package/eval/arena/tank/workspace/history/20261017-193655-4a21366e94d1-muse-wonder-full.cpp +560 -0
  149. package/eval/arena/tank/workspace/history/20261017-193657-dbc4e9969c52-mimo-v2_6-pro.cpp +336 -0
  150. package/eval/arena/tank/workspace/history/20261017-193703-723cd036eb31-grok-4_7.cpp +1205 -0
  151. package/eval/arena/tank/workspace/history/20261017-193707-1ebbb227be68-deepseek-v4_1-flash.cpp +425 -0
  152. package/eval/arena/tank/workspace/history/20261017-193709-aeb0e7202ad5-doubao-seed-evolving.cpp +308 -0
  153. package/eval/arena/tank/workspace/history/20261017-193710-b21ebeb9bc76-kimi-k3.cpp +487 -0
  154. package/eval/arena/tank/workspace/history/20261017-193712-54cd86531905-haiku-5_5.cpp +210 -0
  155. package/eval/arena/tank/workspace/history/20261017-193714-efdb8e35c0bf-qwen-3_8-max.cpp +392 -0
  156. package/eval/arena/tank/workspace/history/20261017-193715-681423c23fdb-glm-5_3.cpp +651 -0
  157. package/eval/arena/tank/workspace/history/20261017-193717-1a8b3c75181d-sparring.cpp +928 -0
  158. package/eval/arena/tank/workspace/history/20261017-193720-1e0803a541e8-baseline.cpp +259 -0
  159. package/eval/arena/tank/workspace/history/log.jsonl +103 -0
  160. package/eval/arena/tank/workspace/judge/cycles.hpp +53 -0
  161. package/eval/arena/tank/workspace/judge/fast.cpp +337 -0
  162. package/eval/arena/tank/workspace/judge/referee.cpp +125 -0
  163. package/eval/arena/tank/workspace/judge/speed.cpp +99 -0
  164. package/eval/arena/tank/workspace/run.cmd +31 -0
  165. package/eval/arena/tank/workspace/run.sh +23 -0
  166. package/eval/arena/tank/workspace/tank.hpp +1762 -0
  167. package/eval/arena/tank/workspace/tank_main.cpp +215 -0
  168. package/eval/arena/tank/workspace/viewer.html +1150 -0
  169. package/eval/arena/warehouse/workspace/SPEC.md +130 -0
  170. package/eval/arena/warehouse/workspace/TASK.md +71 -0
  171. package/eval/arena/warehouse/workspace/baseline/common.h +88 -0
  172. package/eval/arena/warehouse/workspace/baseline/main.cpp +27 -0
  173. package/eval/arena/warehouse/workspace/baseline/old_stuff.cpp +87 -0
  174. package/eval/arena/warehouse/workspace/baseline/sim.cpp +427 -0
  175. package/eval/arena/warehouse/workspace/baseline/util.cpp +220 -0
  176. package/eval/arena/warehouse/workspace/clock.py +42 -0
  177. package/eval/arena/warehouse/workspace/src/common.h +88 -0
  178. package/eval/arena/warehouse/workspace/src/main.cpp +27 -0
  179. package/eval/arena/warehouse/workspace/src/old_stuff.cpp +87 -0
  180. package/eval/arena/warehouse/workspace/src/sim.cpp +427 -0
  181. package/eval/arena/warehouse/workspace/src/util.cpp +220 -0
  182. package/eval/arena/warehouse/workspace/tools/bench.py +119 -0
  183. package/eval/arena/warehouse/workspace/tools/check_input.py +161 -0
  184. package/eval/arena/warehouse/workspace/tools/gen.py +132 -0
  185. package/eval/arena/warehouse/workspace/tools/measure.py +107 -0
  186. package/eval/arena/warehouse/workspace/workloads/public/pub_crowded.in +1420 -0
  187. package/eval/arena/warehouse/workspace/workloads/public/pub_crowded.out +9162 -0
  188. package/eval/arena/warehouse/workspace/workloads/public/pub_dynamic.in +1465 -0
  189. package/eval/arena/warehouse/workspace/workloads/public/pub_dynamic.out +3439 -0
  190. package/eval/arena/warehouse/workspace/workloads/public/pub_flood.in +2757 -0
  191. package/eval/arena/warehouse/workspace/workloads/public/pub_flood.out +3126 -0
  192. package/eval/arena/warehouse/workspace/workloads/public/pub_small.in +731 -0
  193. package/eval/arena/warehouse/workspace/workloads/public/pub_small.out +2578 -0
  194. package/eval/arena/warehouse/workspace/workloads/public/pub_wide.in +528 -0
  195. package/eval/arena/warehouse/workspace/workloads/public/pub_wide.out +2026 -0
  196. package/eval/bomberman.py +20 -0
  197. package/eval/commit0.py +21 -0
  198. package/eval/common.py +61 -0
  199. package/eval/ctf.py +20 -0
  200. package/eval/featurebench.py +25 -0
  201. package/eval/land.py +20 -0
  202. package/eval/legacy/bomberman-prices.json +4 -0
  203. package/eval/legacy/bomberman.py +161 -0
  204. package/eval/legacy/commit0.py +91 -0
  205. package/eval/legacy/ctf-prices.json +4 -0
  206. package/eval/legacy/ctf.py +178 -0
  207. package/eval/legacy/featurebench.py +103 -0
  208. package/eval/legacy/land-prices.json +4 -0
  209. package/eval/legacy/land.py +177 -0
  210. package/eval/legacy/swe_bench_pro.py +116 -0
  211. package/eval/legacy/tank-prices.json +3 -0
  212. package/eval/legacy/tank.py +408 -0
  213. package/eval/legacy/warehouse-prices.json +4 -0
  214. package/eval/legacy/warehouse.py +365 -0
  215. package/eval/swe-bench-pro.py +25 -0
  216. package/eval/tank.py +20 -0
  217. package/eval/warehouse.py +20 -0
  218. package/lib/client/index.js +376 -63
  219. package/lib/client/index.js.map +1 -1
  220. package/lib/index.js +684 -27
  221. package/package.json +2 -1
@@ -0,0 +1,130 @@
1
+ # 仓储机器人调度仿真:行为规格(v2.0,2022 年)
2
+
3
+ > **⚠ 注意:这是 2022 年系统上线时写的文档,之后代码改过很多次,文档没有同步更新。**
4
+ > 文档里的大部分内容仍然准确,但有些地方已经和代码不一致;代码里的注释也可能过时。
5
+ > **一切以 `baseline/` 里基线程序的实际行为为准**:你的程序对任何合法输入,都必须输出与基线程序逐字节相同的内容(行尾的 CRLF 与 LF 视为相同)。
6
+
7
+ ## 1. 输入格式
8
+
9
+ 从标准输入读取,全部为空白分隔的文本:
10
+
11
+ ```
12
+ W H T
13
+ <H 行,每行 W 个字符>
14
+ PARAMS batteryMax chargeRate lowThreshold safetyMargin reportEvery hotRadius
15
+ ROBOTS R
16
+ x y (共 R 行,第 i 行是机器人 i 的初始位置,名字为 "R<i>")
17
+ EVENTS E
18
+ <E 行事件>
19
+ ```
20
+
21
+ - 地图字符:`.` 地面,`#` 墙(货架),`C` 充电桩(也是地面)。
22
+ - 坐标 `(x, y)`:x 为列,y 为行,从 0 开始。
23
+ - 事件行格式为 `tick 类型 参数…`,类型有四种:
24
+ - `ORDER id px py dx dy priority`:新订单,取货点 `(px, py)`,送货点 `(dx, dy)`,优先级(越大越优先);
25
+ - `CANCEL id`:取消订单;
26
+ - `BLOCK x y`:临时封锁格子;
27
+ - `UNBLOCK x y`:解除封锁。
28
+ - 保证:事件按 tick 非递减排列;0 ≤ tick < T;订单编号是互不相同的正整数,没有前导零;初始位置是互不相同的地面格;地图四周是墙。
29
+
30
+ ## 2. 基本概念
31
+
32
+ - **可通行**:在地图内、不是墙、没有被封锁。充电桩可通行(除非被封锁)。
33
+ - **方向顺序**:上 (0,−1)、右 (1,0)、下 (0,1)、左 (−1,0)。所有"按方向"的平局都按这个顺序。
34
+ - **行优先**:先比 y,再比 x。
35
+ - **BFS 距离 `dist(a, b)`**:
36
+ - a == b 时为 0;
37
+ - 否则 b 不可通行时为 INF;
38
+ - 否则从 a 出发做四连通 BFS,**a 本身无论是否可通行都作为起点**,之后只经过可通行格,得到到 b 的步数;到不了为 INF。
39
+ - 注意:a 不可通行时,`dist(a, b)` 与 `dist(b, a)` 可能不同。
40
+ - **机器人状态**:`IDLE` 空闲、`TO_PICKUP` 前往取货、`DELIVERING` 送货中、`TO_CHARGER` 前往充电、`CHARGING` 充电中、`DEAD` 停机。
41
+ - **订单状态**:`PENDING` 待分配、`ASSIGNED` 已分配、`PICKED` 已取货、`DONE` 已送达、`CANCELLED` 已取消、`LOST` 丢失。
42
+ - **占据**:除 `DEAD` 以外的机器人占据它所在的格子。
43
+
44
+ ## 3. 每个 tick 的流程
45
+
46
+ 对 tick = 0, 1, …, T−1,依次执行:
47
+
48
+ ### 3.1 外部事件
49
+
50
+ 按输入顺序处理本 tick 的所有事件:
51
+
52
+ - **ORDER**:取货点或送货点不在地图内或是墙 → 拒绝,输出 `REJECT id`。否则订单进入 `PENDING`,到达时间记为当前 tick。
53
+ - **CANCEL**:
54
+ - 订单不存在,或状态不是 `PENDING`/`ASSIGNED` → 输出 `CANCEL_FAIL id`;
55
+ - `PENDING` → 订单变为 `CANCELLED`,输出 `CANCEL id`;
56
+ - `ASSIGNED` → 负责的机器人立即变为 `IDLE`(清空订单和目标,连续等待次数清零),订单变为 `CANCELLED`,输出 `CANCEL id`。
57
+ - **BLOCK x y**:在地图内且不是墙时封锁(已封锁则无变化)。封锁不影响已经在该格上的机器人。
58
+ - **UNBLOCK x y**:解除封锁(未封锁则无变化)。
59
+
60
+ ### 3.2 救援
61
+
62
+ 按编号顺序检查每个 `DEAD` 机器人:若停机已满 100 个 tick(当前 tick − 停机 tick ≥ 100),且它所在格没有被其他机器人占据,则电量充满,变为 `IDLE`,连续等待次数清零,输出 `RESCUE 名字`。
63
+
64
+ ### 3.3 充电
65
+
66
+ 按编号顺序,每个 `CHARGING` 机器人电量增加 chargeRate(不超过 batteryMax);达到 batteryMax 时变为 `IDLE`,输出 `CHARGED 名字`。
67
+
68
+ ### 3.4 派单
69
+
70
+ 1. 所有 `PENDING` 订单按以下顺序排序:优先级大的在前 → 到达 tick 小的在前 → 编号(按整数)小的在前。
71
+ 2. 依次处理每个订单 o。候选机器人是:状态为 `IDLE` 且电量 ≥ lowThreshold 的机器人(在本 tick 前面的订单中已被分配的不再是候选)。对每个候选 r,计算:
72
+ - `a = dist(r 的位置, 取货点)`
73
+ - `b = dist(取货点, 送货点)`
74
+ - `c = ` 在所有**可通行**的充电桩 q 中,`dist(送货点, q)` 的最小值
75
+ - a、b、c 任一为 INF,或 电量 < a + b + c + safetyMargin,则 r 不合格。
76
+ 3. 在合格者中选 a 最小的,相同取编号小的。选中后:机器人变为 `TO_PICKUP`,目标为取货点,连续等待次数清零;订单变为 `ASSIGNED`;输出 `ASSIGN id 名字 a`。没有合格者则订单保持 `PENDING`。
77
+
78
+ ### 3.5 低电量去充电
79
+
80
+ 按编号顺序,每个电量 < lowThreshold 的 `IDLE` 机器人选择一个充电桩:
81
+
82
+ 1. 按行优先遍历所有可通行的充电桩 q,排除"被占用"的:有**其他**机器人处于 `CHARGING` 且位于 q,或处于 `TO_CHARGER` 且目标是 q。还要排除 `dist(机器人位置, q) + safetyMargin > 电量` 的。在剩下的充电桩中选 `dist` 最小的(相同取行优先靠前的)。
83
+ 2. 若第 1 步没有结果:在所有可通行的充电桩中选 `dist(机器人位置, q)` 最小且不为 INF 的(相同取行优先靠前的),不管是否被占用。
84
+ 3. 若仍没有结果(没有可通行的充电桩,或全都到不了),则不动作。否则机器人变为 `TO_CHARGER`,目标为该充电桩,连续等待次数清零,输出 `GO_CHARGE 名字 x y`。
85
+
86
+ ### 3.6 移动
87
+
88
+ 按编号顺序,处理状态为 `TO_PICKUP`、`DELIVERING`、`TO_CHARGER` 的机器人 r(前面的机器人本 tick 的移动会影响后面机器人看到的占据情况):
89
+
90
+ 1. 若 r 已在目标格,跳到第 6 步(到达)。
91
+ 2. 若电量为 0:**停机**(见 3.8),结束。
92
+ 3. 若目标格不可通行:等待(累计等待次数 +1,连续等待次数不变),结束。
93
+ 4. 计算下一步:在 r 的四个相邻格中,只考虑可通行的,选 `dist(目标, 该格)`(即从目标出发的 BFS 距离)最小的,相同按方向顺序。若最小值为 INF:等待(累计等待 +1,连续等待不变),结束。
94
+ 5. 若下一步格子被其他机器人占据:
95
+ - 若连续等待次数 ≥ 4,且下一步格子**不是** r 的目标格:让路。按方向顺序找第一个可通行且未被占据的相邻格,移动过去(电量 −1,移动步数 +1,连续等待清零),输出 `SIDESTEP 名字`,然后进入第 6 步。找不到这样的格子则按下一条处理。
96
+ - 否则等待:累计等待 +1,连续等待 +1,结束。
97
+
98
+ 若下一步格子没有被占据:移动过去,电量 −1,移动步数 +1,连续等待清零。
99
+ 6. **到达**:若 r 位于目标格,连续等待清零,并按状态处理:
100
+ - `TO_PICKUP`:订单变为 `PICKED`;机器人变为 `DELIVERING`,目标改为送货点;输出 `PICK id 名字`。本 tick 不再移动。
101
+ - `DELIVERING`:订单变为 `DONE`,延迟 = 当前 tick − 订单到达 tick;输出 `DELIVER id 名字 延迟`;机器人变为 `IDLE`,清空订单和目标。
102
+ - `TO_CHARGER`:变为 `CHARGING`,输出 `CHARGE 名字`。
103
+
104
+ ### 3.7 报表
105
+
106
+ 若 (tick + 1) 是 reportEvery 的倍数,输出一行:
107
+
108
+ ```
109
+ REPORT pending=P idle=… to_pickup=… delivering=… to_charger=… charging=… dead=… hot=X,Y,K
110
+ ```
111
+
112
+ - P 为 `PENDING` 订单数,其余为各状态机器人数。
113
+ - **热点**:对每个非墙格子(行优先遍历),统计与它曼哈顿距离 ≤ hotRadius 的**非停机**机器人数;取最大值 K,相同取行优先靠前的格子 (X, Y)。
114
+
115
+ ### 3.8 停机
116
+
117
+ 输出 `DEAD 名字`。若机器人在 `TO_PICKUP`:订单变回 `PENDING`(保留原到达 tick),输出 `REQUEUE id`。若在 `DELIVERING`:订单变为 `LOST`,输出 `LOST id`。机器人变为 `DEAD`,记录停机 tick,清空订单和目标。停机的机器人不再占据格子。
118
+
119
+ ## 4. 输出格式
120
+
121
+ - 事件行格式为 `tick 事件 参数…`,按产生的先后顺序输出。
122
+ - 所有 tick 结束后,输出:
123
+ ```
124
+ SUMMARY delivered=… lost=… rejected=… cancelled=… open=…
125
+ LATENCY sum=… max=… avg=…
126
+ ROBOT 名字 x y 电量 状态 移动步数 累计等待次数 (每个机器人一行,按编号)
127
+ ```
128
+ - open 为状态是 `PENDING`/`ASSIGNED`/`PICKED` 的订单数;
129
+ - avg 为 sum / delivered 的整数除法,delivered 为 0 时是 0。
130
+ - 所有数都是整数,没有浮点运算。
@@ -0,0 +1,71 @@
1
+ # 任务:接手一个老系统——优化仓储机器人调度仿真(主程)
2
+
3
+ 这是一场 AI 编程**团体攻防赛**。每队两人:你是本队的**主程**,队友是**攻手**。
4
+
5
+ `src/` 里是一个仓储机器人调度仿真系统。它已经在线上跑了好几年,经手过好几个人,功能正确,但运行很慢,代码也相当混乱。你的任务:**在输出完全不变的前提下,让它尽可能快。**
6
+
7
+ 你交卷之后会发生两件事:
8
+
9
+ 1. **攻防**:另外 5 支队伍的攻手(都是很强的模型)会拿到你的 `src/`,专门构造合法输入来**击穿**你的代码,也就是让你的输出和基线不一致,或者让程序崩溃。
10
+ 2. **接手**:你的队友会接手你的代码,实现一个保密的需求变更(涉及派单、电量、报表等逻辑),同时修补你被击穿的地方。你们没有其他沟通渠道,**只能通过你写的交接文档**交流。
11
+
12
+ 所以,你交上来的代码不只要快,还要**扛得住攻击**,**队友改得动**。怎么在这几者之间取舍,由你决定。
13
+
14
+ ## 工作目录内容
15
+
16
+ | 路径 | 内容 |
17
+ |---|---|
18
+ | `SPEC.md` | 系统行为规格。**这是 2022 年的旧文档,有些地方已经过时**,与代码不一致时以代码为准 |
19
+ | `src/` | 待优化的源代码,**你只能修改这里** |
20
+ | `baseline/` | 原始代码的只读副本,**它的行为就是标准答案** |
21
+ | `workloads/public/` | 5 组公开负载(`.in`)和对应的标准输出(`.out`) |
22
+ | `tools/bench.py` | 一键编译、运行、比对、计时 |
23
+ | `tools/gen.py` | 负载生成器(只含公开配置),换种子可以生成大量同类输入,用来和基线对拍 |
24
+ | `tools/check_input.py` | 输入合法性检查器:**它定义了什么是合法输入** |
25
+ | `clock.py` | 计时器:`python3 clock.py` 显示已用时间和剩余时间 |
26
+
27
+ ```bash
28
+ python3 tools/bench.py # 编译 src/,跑全部公开负载,检查输出、报告 CPU 时间
29
+ python3 tools/bench.py --baseline # 同时测量基线,报告加速比(基线较慢,需要多等一会儿)
30
+ python3 tools/check_input.py 某个.in --full # 检查一个输入是否合法
31
+ ```
32
+
33
+ (环境里只有 `python` 时,把 `python3` 换成 `python`。)
34
+
35
+ ## 规则
36
+
37
+ 1. **输出必须与基线程序逐字节相同**(`\r\n` 与 `\n` 视为相同),对**任何能通过 `tools/check_input.py --full` 的输入**都是如此,而不只是公开负载。**行为以基线代码为准**:基线里看起来像 bug 的地方,只要会影响输出,就必须原样保留。
38
+ 2. 你可以任意修改 `src/`:改写、重构、增删文件、完全重写都可以。
39
+ 3. 编译命令固定为:`g++ -O2 -std=c++20 src/*.cpp`(Windows 上额外加 `-static`)。不能更改编译参数,只能使用 C++ 标准库。
40
+ 4. 程序只能读标准输入、写标准输出。不得读写任何文件,不得联网,不得在两次运行之间缓存任何信息。
41
+ 5. 内存上限 1 GB。计时使用进程的 **CPU 总时间**(所有线程相加),多线程不会带来加分。
42
+ 6. 不要修改 `baseline/`、`workloads/`、`tools/`;正式评测使用出题方自己的副本。
43
+ 7. **交卷前在 `src/HANDOFF.md` 写一份交接文档**,给接手的队友看。写什么由你决定(比如代码结构、你发现的怪行为、优化思路、哪里有风险、想改某类逻辑该动哪里)。这份文档也会参与可维护性评审。
44
+
45
+ ## 攻防规则(你会被怎么攻击)
46
+
47
+ - 攻手提交的击穿用例必须通过 `python3 tools/check_input.py 用例.in`(不带 `--full`),也就是规模更小的上限:W, H ≤ 60,T ≤ 3000,机器人 ≤ 40,事件 ≤ 20000;其余约定和正式负载相同。
48
+ - 用例在你的程序上输出与基线不一致、程序崩溃或运行超过 60 秒,就算**被击穿**。
49
+ - 攻手能看到你的全部 `src/`(包括 `HANDOFF.md`),也有基线和生成器。
50
+
51
+ ## 评分方式(主程个人部分)
52
+
53
+ - **优化效果**:用若干组**隐藏负载**评测(参数与公开负载不同,规模更大,上限:W, H ≤ 200;机器人 ≤ 300;T ≤ 20000;事件 ≤ 200000)。每组:输出有任何不同、崩溃、超内存或比基线还慢 → 0 分;否则 `100 × ln(加速比) ÷ ln(本期所有主程在这组上的最大加速比)`。取各组平均。
54
+ - **抗击穿**:被越少的攻手击穿越好。但抗击穿分要**乘以你的优化效果分**:完全不改代码虽然打不穿,也拿不到这部分分。
55
+ - **可维护性**:赛后由 3 个裁判模型匿名评审你的 `src/`(含 `HANDOFF.md`),看结构是否清楚、怪行为有没有注明、需求变更好不好改、优化逻辑是否清晰、技术债有没有清理。
56
+ - 团队总分还包括攻手的表现。你的代码质量直接影响队友接手的难度。
57
+
58
+ ## 时间限制
59
+
60
+ - 时间预算约 **30 分钟**,请自己把握进度,做完就可以结束。超过 45 分钟会被强制停止,以当时的 `src/` 为准。
61
+ - **`python3 clock.py` 可以随时查看已经用了多久、还剩多久**(从主办方开赛的时刻算起)。不要重新解压 `workspace.zip`。
62
+ - 工作时只能读写当前 `workspace` 文件夹里的文件,不要访问这个文件夹以外的任何内容。
63
+ - 结束时的 `src/` 就是你的提交。一个"更快但输出有错"的版本在对应负载上是 0 分,还会被攻手轻松击穿。结束前请确认输出与基线完全一致。
64
+
65
+ ## 工作方式
66
+
67
+ - 你可以使用本环境中的所有工具:阅读代码、编译、运行、计时、写测试脚本、做剖析(profiling)等。**不能联网搜索。**
68
+ - 自己的脚本和中间文件请放在当前文件夹里(比如新建 `work/`),不要用 `/tmp` 或系统临时目录:在 Windows 上 bash 和 Python 看到的 `/tmp` 不是同一个地方。
69
+ - 请独立完成,**不要向用户提问**,也不要等待用户确认;遇到不确定的地方,以基线代码的行为为准。
70
+ - 建议:先读基线代码和 `SPEC.md`,弄清楚代码真正的行为(注意文档和注释可能过时),再找出瓶颈、逐步优化;每一步都用 `bench.py` 确认输出仍然完全正确。公开负载只有 5 组,建议用 `tools/gen.py` 换种子、改参数生成更多输入,再自己构造一些边界情况(极小地图、极低电量、频繁封路……),与基线对拍。攻手一定会这么做。
71
+ - 完成后,确认 `python3 tools/bench.py` 显示全部正确、`src/HANDOFF.md` 已写好,然后用几句话总结你做了什么,结束任务。
@@ -0,0 +1,88 @@
1
+ // common.h --- WMS 仓储调度 公共头文件
2
+ // 所有人都 include 这个,别乱改!!! (2022 老王)
3
+ // 2023-03 张: 加了一些全局变量
4
+ // 2023-11 张: 加了 FAST_BFS 开关
5
+ // 2024-06 实习生: 加了注释(部分)
6
+ #ifndef COMMON_H_WMS
7
+ #define COMMON_H_WMS
8
+
9
+ #include <iostream>
10
+ #include <fstream>
11
+ #include <sstream>
12
+ #include <string>
13
+ #include <vector>
14
+ #include <map>
15
+ #include <set>
16
+ #include <list>
17
+ #include <queue>
18
+ #include <algorithm>
19
+ #include <cstdlib>
20
+ #include <cstdio>
21
+ #include <cstring>
22
+ #include <utility>
23
+
24
+ using namespace std;
25
+
26
+ #define BIGNUM 1000000000
27
+ #define MAXR 512
28
+ #define FLAG_FAST_BFS 0 // 缓存版 BFS,见 old_stuff.cpp,线上先别开
29
+ #define FLAG_VERBOSE 0
30
+ #define USE_NEW_DISPATCH 1 // 0 = 用 old_stuff.cpp 里的旧派单
31
+
32
+ // 地图 ===========================================
33
+ extern int W, H, T;
34
+ extern vector<string> MAP; // MAP[y][x]
35
+ extern set<pair<int, int> > BLK; // 封锁的格子 (x,y)
36
+
37
+ // 参数 ===========================================
38
+ extern int PRM[6]; // 0 满电 1 充电速度 2 低电量 3 安全余量 4 报表间隔 5 热点半径
39
+
40
+ // 机器人(老王说 struct 太慢,所以拆成数组) ======
41
+ extern int NR;
42
+ extern vector<int> RX, RY, RB, RTX, RTY, RWS, RDS; // 位置 电量 目标 连续等待 停机时刻
43
+ extern vector<long long> RWT, RTR; // 累计等待 移动步数
44
+ extern vector<string> RST; // 状态
45
+ extern vector<string> ROID; // 订单号
46
+
47
+ // 订单 ===========================================
48
+ // ORD[id] = {px, py, dx, dy, prio, arrival, status, robotName}
49
+ extern map<string, vector<string> > ORD;
50
+ extern vector<string> PEND; // 待派订单
51
+
52
+ // 事件 & 日志 =====================================
53
+ extern vector<string> EVT; // 原始事件行
54
+ extern vector<string> LOGBUF;
55
+
56
+ // 统计 ===========================================
57
+ extern long long CNT[8]; // 0 送达 1 丢失 2 拒绝 3 取消 4 延迟和 5 延迟最大 6,7 没用
58
+
59
+ // util.cpp
60
+ vector<string> SPLIT(const string& s);
61
+ int S2I(const string& s);
62
+ string I2S(long long v);
63
+ string RNAME(int i);
64
+ bool OK(int x, int y); // 能不能走
65
+ bool INMAP(int x, int y);
66
+ bool ISWALL(int x, int y);
67
+ bool OCC(int x, int y, int except);
68
+ vector<vector<int> > BFS(int sx, int sy);
69
+ vector<vector<int> > BFS2(int sx, int sy);
70
+ int DIST(int ax, int ay, int bx, int by);
71
+ int CHG_DIST(int x, int y);
72
+ pair<int, int> CHG_NEAR(int x, int y);
73
+ vector<pair<int, int> > ALL_CHG();
74
+ void writeLog(int t, const string& msg);
75
+ void writeRaw(const string& msg);
76
+ void dumpLog();
77
+ int findRobot(const string& name);
78
+
79
+ // sim.cpp
80
+ void ReadAll(istream& in);
81
+ void RunSim();
82
+ void Finish();
83
+
84
+ // old_stuff.cpp
85
+ vector<vector<int> > bfs_fast_cached(int sx, int sy);
86
+ void oldDispatch(int t);
87
+
88
+ #endif
@@ -0,0 +1,27 @@
1
+ // WMS 仓储机器人调度仿真 v3.2
2
+ // 从标准输入读场景,往标准输出写日志
3
+ #include "common.h"
4
+
5
+ // 全局变量都在这里定义 ===============
6
+ int W = 0, H = 0, T = 0;
7
+ vector<string> MAP;
8
+ set<pair<int, int> > BLK;
9
+ int PRM[6];
10
+ int NR = 0;
11
+ vector<int> RX, RY, RB, RTX, RTY, RWS, RDS;
12
+ vector<long long> RWT, RTR;
13
+ vector<string> RST;
14
+ vector<string> ROID;
15
+ map<string, vector<string> > ORD;
16
+ vector<string> PEND;
17
+ vector<string> EVT;
18
+ vector<string> LOGBUF;
19
+ long long CNT[8] = {0, 0, 0, 0, 0, 0, 0, 0};
20
+
21
+ int main() {
22
+ ReadAll(cin);
23
+ RunSim();
24
+ Finish();
25
+ dumpLog();
26
+ return 0;
27
+ }
@@ -0,0 +1,87 @@
1
+ // old_stuff.cpp
2
+ // 旧代码,先留着,万一要回滚 —— 张 2023-03
3
+ //
4
+ // 2023-11 张:加了 bfs_fast_cached,按起点缓存 BFS 结果,本地测快了十倍!
5
+ // 线上还没开(FLAG_FAST_BFS),等有空再全面测一下
6
+ // 2024-02 李:FIXME 开了之后有个负载结果对不上,没查出来,先关着
7
+ #include "common.h"
8
+
9
+ extern int DX4[4];
10
+ extern int DY4[4];
11
+
12
+ static map<pair<int, int>, vector<vector<int> > > g_bfsCache;
13
+ static int g_cacheHit = 0, g_cacheMiss = 0;
14
+
15
+ vector<vector<int> > bfs_fast_cached(int sx, int sy) {
16
+ pair<int, int> key = make_pair(sx, sy);
17
+ map<pair<int, int>, vector<vector<int> > >::iterator it = g_bfsCache.find(key);
18
+ if (it != g_bfsCache.end()) {
19
+ g_cacheHit++;
20
+ return it->second;
21
+ }
22
+ g_cacheMiss++;
23
+ vector<vector<int> > d(H, vector<int>(W, BIGNUM));
24
+ queue<pair<int, int> > q;
25
+ d[sy][sx] = 0;
26
+ q.push(key);
27
+ while (!q.empty()) {
28
+ pair<int, int> p = q.front();
29
+ q.pop();
30
+ for (int k = 0; k < 4; k++) {
31
+ int nx = p.first + DX4[k], ny = p.second + DY4[k];
32
+ if (!OK(nx, ny)) continue;
33
+ if (d[ny][nx] != BIGNUM) continue;
34
+ d[ny][nx] = d[p.second][p.first] + 1;
35
+ q.push(make_pair(nx, ny));
36
+ }
37
+ }
38
+ if (g_bfsCache.size() > 5000) g_bfsCache.clear(); // 防止内存爆
39
+ g_bfsCache[key] = d;
40
+ return d;
41
+ }
42
+
43
+ // 旧版派单(2022 老王)。新版在 sim.cpp,这个不用了
44
+ // 旧版是按订单到达顺序派的,没有优先级
45
+ void oldDispatch(int t) {
46
+ vector<string> done;
47
+ for (int oi = 0; oi < (int)PEND.size(); oi++) {
48
+ string id = PEND[oi];
49
+ int px = S2I(ORD[id][0]), py = S2I(ORD[id][1]);
50
+ int best = BIGNUM, who = -1;
51
+ for (int i = 0; i < NR; i++) {
52
+ if (RST[i] != "IDLE") continue;
53
+ int a = DIST(RX[i], RY[i], px, py);
54
+ if (a < best) {
55
+ best = a;
56
+ who = i;
57
+ }
58
+ }
59
+ if (who < 0) continue;
60
+ RST[who] = "TO_PICKUP";
61
+ ROID[who] = id;
62
+ RTX[who] = px;
63
+ RTY[who] = py;
64
+ ORD[id][6] = "ASSIGNED";
65
+ ORD[id][7] = RNAME(who);
66
+ done.push_back(id);
67
+ writeLog(t, "ASSIGN " + id + " " + RNAME(who) + " " + I2S(best));
68
+ }
69
+ for (int k = 0; k < (int)done.size(); k++) {
70
+ PEND.erase(find(PEND.begin(), PEND.end(), done[k]));
71
+ }
72
+ }
73
+
74
+ #if 0
75
+ // 想改成按区域派单,没写完
76
+ void zoneDispatch(int t) {
77
+ int zones = 4;
78
+ for (int z = 0; z < zones; z++) {
79
+ // TODO
80
+ }
81
+ }
82
+ #endif
83
+
84
+ // 调试用
85
+ void dumpCacheStat() {
86
+ cerr << "cache hit " << g_cacheHit << " miss " << g_cacheMiss << endl;
87
+ }