所以,我用BackTracking算法创建了一个数独求解器。一切都像魅力一样,但与用java编写的相同解决方案相比,解算器真的很慢。 python真的那么慢,或者我的代码中有一个我错过的主要错误? 这是代码:
rida = 0
veerg = 0
maatriks = []
regioon = True
regioonid = []
abimaatriks = [[],[],[],[],[],[],[],[],[]]
# Loeb failist maatriksi sisse ja teeb temast listide listi.
def looMaatriks(sisendfail, maatriks):
fail = open(sisendfail)
for line in fail:
line = line.strip()
if line != "":
rida = line.split(" ")
for i in range (0, 9):
if rida[i] != "-":
rida[i] = int(rida[i])
else:
rida[i] = 0
maatriks.append(rida)
return maatriks
maatriks = looMaatriks('sisend1.txt', maatriks)
# Loob failist regiooni.
def looRegioon(sisendfail, reg):
fail = open(sisendfail)
for line in fail:
line = line.strip()
if line != "":
rida = line.split(" ")
reg.append(rida)
for i in range(0,9):
rida[i] = int(rida[i])
return reg
regioonid = looRegioon('sisend2.txt', regioonid)
print(regioonid)
# Loob abimaatriksi, kus regioone säilitada.
def looAbiMaatriks(regioon, abimaatriks):
for i in range (0, 9):
for j in range (0, 9):
abi = regioon[i][j]
abimaatriks[abi-1].append((i, j))
looAbiMaatriks(regioonid, abimaatriks)
print(abimaatriks)
# Kontrollib, kas antud ruudukeses on number juba või mitte.
def numberOlemas(maatriks, rida, veerg):
if maatriks[rida][veerg] != 0:
return True
else:
return False
# Kontrollib, kas arv sobib antud ruutu.
def kasSobib(maatriks, rida, veerg, arv):
for i in range (0, 9):
if arv == maatriks[rida][i]:
return False
for i in range (0, 9):
if arv == maatriks[i][veerg]:
return False
if regioon == False:
reaalgus = 3*int(rida/3)
veerualgus = 3*int(veerg/3)
for k in range(reaalgus, reaalgus + 3):
for l in range(veerualgus, veerualgus + 3):
if arv == maatriks[k][l]:
return False
else:
abi = regioonid[rida][veerg]
for i in abimaatriks[abi-1]:
if maatriks[i[0]][i[1]] == arv:
return False
return True
# Prindib maatriksi ilusal kujul välja.
def prindiMaatriks(maatriks):
for i in range (0, 9):
print(maatriks[i])
print("")
# Peafunktsioon, mis lahendab kogu maatriksi rekursiivselt.
def lahendaRuut(maatriks, rida, veerg):
if veerg > 8:
veerg = 0
rida += 1
if rida == 9:
return True
if numberOlemas(maatriks, rida, veerg) == True:
return lahendaRuut(maatriks, rida, veerg+1)
for i in range(1,10):
if kasSobib(maatriks, rida, veerg, i):
maatriks[rida][veerg] = i
if lahendaRuut(maatriks, rida, veerg+1):
return True
else:
maatriks[rida][veerg] = 0
return False
print ("Esialgne maatriks:")
prindiMaatriks(maatriks)
print("Lahendatud maatriks:")
lahendaRuut(maatriks, rida, veerg)
prindiMaatriks(maatriks)
这是sisend1.txt的输入:
- - - - - - - - -
- - - - - - - - -
- - - - - - - - -
- - - - - - - - -
- - - - - - - - -
- - - - - - - - -
- - - - - - - - -
- - - - - - - - -
- - - - - - - - -
这是sisend2.txt的输入:
1 1 1 2 3 3 3 3 3
1 1 1 2 2 2 3 3 3
1 4 4 4 4 2 2 2 3
1 1 4 5 5 5 5 2 2
4 4 4 4 5 6 6 6 6
7 7 5 5 5 5 6 8 8
9 7 7 7 6 6 6 6 8
9 9 9 7 7 7 8 8 8
9 9 9 9 9 7 8 8 8
Input2包含自定义数独的3x3区域。 如果您想在没有区域的情况下进行测试,只需在开头更改regioon = False即可。 输入1只是一个空的数独填充。
答案 0 :(得分:1)
使用列表推导和一些内置函数还有改进的空间。
例如,而不是:
rida = line.split(" ")
for i in range (0, 9):
if rida[i] != "-":
rida[i] = int(rida[i])
else:
rida[i] = 0
您可以使用列表推导并执行:
rida = line.split(" ")
rida = [int(r) if r != "-" else 0 for r in rida]
还消除了一些内置函数的for循环,例如
for i in range(0,9):
rida[i] = int(rida[i])
使用地图:
map(int, rida)
同时删除不必要的for循环。替换:
for i in range (0, 9):
if arv == maatriks[rida][i]:
return False
for i in range (0, 9):
if arv == maatriks[i][veerg]:
return False
使用:
for i in rage(0, 9):
if arv in [maatriks[rida][i], maatriks[i][veerg]]:
return False