根据题意要求:
深度优先路径遍历问题。从每一个节点出发,按照题设要求的规则进行深度优先搜索,每遍历完一次计数一次。
基本算法流程如下:
就是这么简单粗暴(简洁明了),这就是套路的力量^-^
要点说明:
以上流程没有考虑排除正序列和逆序列重复搜索的问题,因此浪费了一半的时间,所得答案要除以2才是正确答案。目前暂时没有想到如何排除正序列和逆序列重复搜索,暂时就此将就。
# -*- coding: utf-8 -*-
"""
Created on Thu Oct 21 07:32:03 2021
@author: chenxy
"""
import sys
import time
import datetime
import math
# import random
from typing import List
from collections import deque
import itertools as it
import numpy as np
H = 5 # Height, vertical
W = 6 # Width, horizontal
# nodes initialization, with a guard band surrounding the original nodes
# The guard band is initialized to '-1' to simplify the judgement processing.
nodes0 = np.zeros((H+2, W+2))
nodes0[0,:] = -1
nodes0[H+1,:] = -1
nodes0[:,0] = -1
nodes0[:,W+1] = -1
count = 0
def dfs(h,w,nodes):
# print('dfs({0},{1},{2})'.format(h,w,nodes))
global count
if np.all(nodes[1:H+1,1:W+1]):
count = count + 1
return
if nodes[h-1,w] == 0:
nodes[h-1,w] = 1
dfs(h-1,w,nodes)
nodes[h-1,w] = 0
if nodes[h+1,w] == 0:
nodes[h+1,w] = 1
dfs(h+1,w,nodes)
nodes[h+1,w] = 0
if nodes[h,w-1] == 0:
nodes[h,w-1] = 1
dfs(h,w-1,nodes)
nodes[h,w-1] = 0
if nodes[h,w+1] == 0:
nodes[h,w+1] = 1
dfs(h,w+1,nodes)
nodes[h,w+1] = 0
tStart = time.perf_counter()
for h in range(1,H+1):
for w in range(1,W+1):
cur_nodes = nodes0.copy()
cur_nodes[h,w] = 1
dfs(h,w,cur_nodes)
cur_nodes[h,w] = 0
tCost = time.perf_counter() - tStart
print('(H,W)=({0},{1}), count = {2}, tCost = {3:6.3f}(sec)'.format(H,W,count,tCost))
运行结果:
(H,W)=(3,4), count = 124, tCost = 0.017(sec)
(H,W)=(4,5), count = 2012, tCost = 1.176(sec)
(H,W)=(5,6), count = 53992, tCost = 204.012(sec)
如上所述,将以上结果除以2才是正确答案。
以上只考虑了最基本解决方案,甚至连正逆序列重复搜索都没有排除,所以运行效率太低了。需要考虑优化,除了正逆序列重复搜索的排除外,还要进一步从缩小搜索范围或者剪枝(键盘敲出jiezhi变换半天看着不对劲。。。最后回过神来是jianzhi非jiezhi^-^)等角度考虑进一步提高搜索效率。
一般来说,但凡我能有一个哪怕最naive的解,我尽量避免看原书题解。要等我觉得关于这个问题已经想无可想的时候才去看原书题解。反正也不赶时间,只是利用闲暇时刻想一想(脑袋里可能并行地放了多个问题,没事的时候就翻出来想一想,所以也不浪费时间)。真正独立想出解决方案来才能有最大收获,这个也算是物尽其用吧,毕竟碰到一个好问题的机会难得。