同一道谜题,两种方式
我们用第3篇中的8B LoRA(15个周期)把一道简单谜题(35个空格)解了两次。
- 第1次:从数字1到9依次由VLM写出不能填的格子,然后填上只剩一个位置的格子。
- 第2次:方式相同,但每填一个格子,代码就立即填上只剩一个空格的宫、行、列。
第1次:剩2个空格时停住
在16次判定中给出了38手,其中33手正确。剩下2个空格时再也找不到可以填的地方。一个不漏地答对不能填格子的判定,在16次中有9次。
答错的5手,全都是因为把能填的格子误写成了不能填。多划掉一个位置后,错误的格子就成了唯一剩下的位置。演示中没有把错误的着法放到盘面上,只是做了记录。
第2次:10次判定就完成
第2次用10次判定填满了全部35个格子。靠VLM判定填了15格,代码接着填了20格,没有填错的格子。一个不漏地答对的判定在10次中有8次,但漏掉的格子并没有改变答案。
用数字2填了两个格子之后,出现了只剩一个空格的宫、行、列,代码连续填了五个格子。在数字7和第二轮的数字3上,也各自连续填了五个格子。需要判定的事情少了,模型出错的机会也就少了。

前面的答案造就下一个答案
第1篇中的模型是从左上角开始横向填写的,不会把前面填好的答案当作下一个格子的依据。第2次解题则是在盘面上东一处西一处地填,刚刚填好的格子会成为下一个格子的依据。这和人解题的顺序是一样的。

这一步的实际代码
这是第2次解题中在VLM判定之后运行的代码。如果宫、行、列中只剩一个空格,就用缺少的数字填上。
vlm_digit_strategy.py
def _missing_one(values: list[int]) -> int | None:
present = {v for v in values if v != 0}
miss = [d for d in range(1, 10) if d not in present]
return miss[0] if len(miss) == 1 else None
def last_empty_unit_moves(
board: list[list[int]],
) -> list[tuple[int, int, int, str]]:
"""박스·행·열에 빈칸이 정확히 1개면 빠진 숫자로 채움."""
found: dict[tuple[int, int], tuple[int, str]] = {}
def add(r: int, c: int, digit: int, reason: str) -> None:
key = (r, c)
if key not in found:
found[key] = (digit, reason)
elif found[key][0] == digit:
prev = found[key][1]
if reason not in prev:
found[key] = (digit, f"{prev}+{reason}")
for br in range(3):
for bc in range(3):
cells = [
(r, c)
for r in range(br * 3, br * 3 + 3)
for c in range(bc * 3, bc * 3 + 3)
]
empties = [(r, c) for r, c in cells if board[r][c] == 0]
if len(empties) != 1:
continue
digit = _missing_one([board[r][c] for r, c in cells])
if digit is not None:
add(empties[0][0], empties[0][1], digit, "code_last_box")
for r in range(9):
empties = [(r, c) for c in range(9) if board[r][c] == 0]
if len(empties) != 1:
continue
digit = _missing_one([board[r][c] for c in range(9)])
if digit is not None:
add(empties[0][0], empties[0][1], digit, "code_last_row")
for c in range(9):
empties = [(r, c) for r in range(9) if board[r][c] == 0]
if len(empties) != 1:
continue
digit = _missing_one([board[r][c] for r in range(9)])
if digit is not None:
add(empties[0][0], empties[0][1], digit, "code_last_col")
return [
(r, c, digit, reason)
for (r, c), (digit, reason) in sorted(found.items())
]下一篇是“5. 帮助人的 AI”。
COMMENTS · CHAPTER 04
训练前后的解法对比 评论 0
还没有评论。阅读时有疑问或想补充的内容,欢迎留言。
发表评论前,请用 Google 开始并登记昵称和邮箱。
用 Google 开始