縦横のラベルの数から図の再現ができないか?の確認ロジック4
■ラベルの数から図を再現するコード。
前回試したコードをより一般化したものが下のもの。ROWとCOLに縦と横の数を入れればその条件に合う図を探す。
import time
import itertools
import numpy
### Data Set: ROW縦、COL横 #############
ROW = [2, 2, 2, 3]
COL = [2, 3, 2, 2]
# 配列のインデックスに対する数の和算
# [[0,1], [1,2]] なら 0+1=1, 1+2=3。
def checkResult(target):
rowlist = ROW
result = True
for b in range(len(rowlist)):
temp = 0
for list in target:
temp = temp + list[b]
if temp > rowlist[b]:
result = False
return result
# 各行ごとにチェック
# 列の総数が条件より少ない場合、再帰的にチェック
def checkline(parent, childrenList, columnlist, depth):
list = parent
if depth == len(columnlist) - 1:
for child in childrenList:
list.append(child)
result = checkResult(list)
if result == True:
showResult(list)
del list[len(list) - 1]
return list
for child in childrenList:
list.append(child)
result = checkResult(list)
if result == True:
depth = depth + 1
checkline(list, makeCombination(len(columnlist), columnlist[depth]), columnlist, depth)
depth = depth - 1
del list[len(list) - 1]
return parent
# 総数に対する組み合わせ数の組を0, 1で表現
def makeCombination(total, combNum):
result = []
list = range(total)
for comb in itertools.combinations(list, combNum):
list2 = numpy.zeros(total)
if len(list) > 0:
for n in comb:
list2[n] = 1
result.append(list2.tolist())
return result
# 結果を図として表示
def showResult(list):
listcopy = list.copy()
del listcopy[0]
for l in listcopy:
temp = ""
for k in l:
if k == 1:
temp = temp + "■"
else:
temp = temp + "□"
print(temp)
start_time = time.time()
columnlist = COL
start = []
list = [0] * len(columnlist)
start.append(list)
d = makeCombination(len(list), columnlist[0])
c = checkline(start, d, columnlist, 0)
end_time = time.time()
print("Time: ", end_time - start_time)
以前から使っていた下の図は、縦と横ともに[0, 7, 2, 5, 5, 5, 2, 7, 0]。
それを入れて実行すると下のような結果となり、1つの図だけが出る。
この例は1つの図だけだけど、下のような図(縦:[7, 7, 6, 3, 7, 2, 5, 5, 5]、横:[4, 7, 5, 3, 7, 2, 7, 6, 6])では、該当するものが何十と出てきて終わる気配がない。
縦横の数と図が一対一になる条件とかある気がするけど、とりあえず再現はできたのでこの内容はこれくらいかな。