我正在尝试编写一个Python脚本来确定给定的非图形是否是唯一的。我目前的脚本运行时间太长,所以我想知道是否有人有任何想法。
我知道一般的非图形问题是NP难的。但是,我知道有关我给出的非图形的两条信息:
我最初使用蛮力方法(所以2 ^ 36个案例)。然而,知道(1),我能够将其缩小到n-choose-k(36选择零个数)的情况。然而,当k接近18时,这仍然是~2 ^ 33个案例。需要几天时间。
我有什么想法可以加快速度吗?它甚至可能吗?
同样,我不在乎解决方案是什么 - 我已经拥有它。我想要确定的是,该解决方案是否是唯一的。
编辑: 这不完全是完整的代码,但有一般的想法:
def unique(nonogram):
found = 0
# create all combinations with the same number of 1s and 0s as incoming nonogram
for entry in itertools.combinations(range(len(nonogram)), nonogram.count(1)):
blank = [0]*len(nonogram) # initialize blank nonogram
for element in entry:
blank[element] = 1 # distribute 1s across nonogram
rows = find_rows(blank) # create row headers (like '2 1')
cols = find_cols(blank)
if rows == nonogram_rows and cols == nonogram_cols:
found += 1 # row and col headers same as original nonogram
if found > 1:
break # obviously not unique
if found == 1:
print('Unique nonogram')
答案 0 :(得分:1)
除了解决问题之外,我无法想出一种巧妙的方法来证明唯一性,但6x6足够小,我们基本上可以做一个强力解决方案。为了加快速度,我们可以循环遍历所有令人满意的行,而不是遍历每个可能的非图形。这样的事情(注意:未经测试)应该有效:
from itertools import product, groupby
from collections import defaultdict
def vec_to_spec(v):
return tuple(len(list(g)) for k,g in groupby(v) if k)
def build_specs(n=6):
specs = defaultdict(list)
for v in product([0,1], repeat=n):
specs[vec_to_spec(v)].append(v)
return specs
def check(rowvecs, row_counts, col_counts):
colvecs = zip(*rowvecs)
row_pass = all(vec_to_spec(r) == tuple(rc) for r,rc in zip(rowvecs, row_counts))
col_pass = all(vec_to_spec(r) == tuple(rc) for r,rc in zip(colvecs, col_counts))
return row_pass and col_pass
def nonosolve(row_counts, col_counts):
specs = build_specs(len(row_counts))
possible_rows = [specs[tuple(r)] for r in row_counts]
sols = []
for poss in product(*possible_rows):
if check(poss, row_counts, col_counts):
sols.append(poss)
return sols
我们从中了解到
>>> rows = [[2,2],[4], [1,1,1,], [2], [1,1,1,], [3,1]]
>>> cols = [[1,1,2],[1,1],[1,1],[4,],[2,1,],[3,2]]
>>> nonosolve(rows, cols)
[((1, 1, 0, 0, 1, 1), (0, 0, 1, 1, 1, 1), (1, 0, 0, 1, 0, 1),
(0, 0, 0, 1, 1, 0), (1, 0, 0, 1, 0, 1), (1, 1, 1, 0, 0, 1))]
>>> len(_)
1
是唯一的,但
>>> rows = [[1,1,1],[1,1,1], [1,1,1,], [1,1,1], [1,1,1], [1,1,1]]
>>> cols = rows
>>> nonosolve(rows, cols)
[((0, 1, 0, 1, 0, 1), (1, 0, 1, 0, 1, 0), (0, 1, 0, 1, 0, 1), (1, 0, 1, 0, 1, 0), (0, 1, 0, 1, 0, 1), (1, 0, 1, 0, 1, 0)),
((1, 0, 1, 0, 1, 0), (0, 1, 0, 1, 0, 1), (1, 0, 1, 0, 1, 0), (0, 1, 0, 1, 0, 1), (1, 0, 1, 0, 1, 0), (0, 1, 0, 1, 0, 1))]
>>> len(_)
2
不是
[请注意,对于这个问题,这不是一个非常好的解决方案,因为它丢弃了大部分信息,但它很简单。]