基本的算法是這樣的:
先寫一個函數f1
再寫一個函數f2
n
2
判斷當前是“上下”或“左右”方向:由于某個點尋找目標點時,我引進了行走方向,這樣可以節省一半的計算量。例如:如果當前方向是“上下”,直線找不到時,下一步遞歸對直線上的每個點的尋找,就只需要“左右”方向,不需要上下;
路徑記錄的列表。
以上是基本思路。
我的算法優化方法很簡單,就是在原來基礎上加上一個對應于所有點的數組,用來記錄對應的點在第多少連的情況下仍然沒有找到目標點。例如:假設總共只能n
這樣,大大減少了無效的計算,原來在第6
那個n連看的算法當時用一天寫出來,非常興奮。無奈電腦是內網,要保密,不能把代碼直接傳出來,之前想過有時間要貼出來,一直忘記了。現在在轉到這個新開的blog。
只貼算法有關部分。用的是python語言:
1
class CY_LianlianKan(
..):
2
def __init__(self):
3
self.m_Array=[] #存儲內容的矩陣
4
self.m_LinkCount=0 #需要連的總數
5
self.m_FirstPosition=-1 #記下連的第一點
6
self.MaxWidth=13 #矩陣寬
7
self.MaxHeight=12 #矩陣高
8
#其它初始化內容
9
#----------------------------------
10
def IsTargetXYValid(self,X,Y):
11
#目標坐標是否有效,超過矩陣寬高即無效
12
#----------------------------------
13
def IsTargetXYBlank(self,X,Y):
14
#目標是否空白可以通過
15
#----------------------------------
16
def GetArrayXY(self,X,Y):
17
#獲取矩陣坐標為XY的內容
18
#----------------------------------
19
def IsLineable(self,x1,y1,x2,y2,direction):#判斷兩點是否可以通過某方向直線連接
20
#方向direction:1←2→3↑4↓
21
if direction==1:
22
if y1==y2 and x1>x2:
23
for i in xrange(x2,x1+1):
24
if self.GetArrayXY(i,y1)>0:
25
return False
26
return True
27
elif direction==2:
28
if y1==y2 and x1<x2:
29
for i in xrange(x1,x2+1):
30
if self.GetArrayXY(i,y1)>0:
31
return False
32
return True
33
elif direction==3:
34
if x1==x2 and y1<y2:
35
for i in xrange(y1,y2+1):
36
if self.GetArrayXY(x1,i)>0:
37
return False
38
return True
39
elif direction==4:
40
if x1==x2 and y2<y1:
41
for i in xrange(y2,y1+1):
42
if self.GetArrayXY(x1,i)>0:
43
return False
44
return True
45
return False
46
#---------------------------------------
47
def IsNTurnReachable(self,x1,y1,x2,y2,path,n,LRorUD,hasReachPoint):
48
#path成功時用于記錄路徑 n當前剩下的連數 LRorUD當前方向是上下還是左右
49
#hasReachPoint 一個矩陣,用于記錄矩陣中各個點目前已經經過多少連了還找不到目標點
50
if n<=0:
51
return False
52
if LRorUD: #左右方向
53
for x in xrange(x1-1,-1,-1):#向左
54
if self.GetArrayXY(x,y1)==0 and hasReachPoint[y1*self.MaxWidth+x]<n:
55
if self.IsLineable(x,y1,x2,y2,3) or self.IsLinable(x,y1,x2,y2,4):
56
path+=[x,y1,x2,y2]
57
return path
58
else:#到達不了,上下轉彎,遞歸
59
hasReachPoint[y1*self.MaxWidth+x]+=1
60
p=self.IsNTurnReachable(x,y1,x2,y2,path+[x,y1],n-1,False,hasReachPoint)
61
if p!=False:
62
return p
63
else:
64
break
65
for x in xrange(x1+1,self.MaxWidth):#向右
66
if self.GetArrayXY(x,y1)==0 and hasReachPoint[y1*self.MaxWidth+x]<n:
67
if self.IsLineable(x,y1,x2,y2,3) or self.IsLineable(x,y1,x2,y2,4):
68
path+=[x,y1,x2,y2]
69
return path
70
else:#到達不了,上下轉彎,遞歸
71
hasReachPoint[y1*self.MaxWidth+x]+=1
72
p=self.IsNTurnReachable(x,y1,x2,y2,path+[x,y1],n-1,False,hasReachPoint)
73
if p!=False:
74
return p
75
else:
76
break
77
else:#上下移動
78
for y in xrange(y1-1,-1,-1):#向上
79
if self.GetArrayXY(x1,y)==0 and hasReachPoint[y*self.MaxWidth+x1]<n:
80
if self.IsLineable(x1,y,x2,y2,1) or self.IsLineable(x1,y,x2,y2,2):
81
path+=[x1,y,x2,y2]
82
return path
83
else:#到達不了,左右轉彎,遞歸
84
hasReachPoint[y*self.MaxWidth+x1]+=1
85
p=self.IsNTurnReachable(x1,y,x2,y2,path+[x1,y],n-1,True,hasReachPoint)
86
if p!=False:
87
return p
88
else:
89
break
90
for y in xrange(y1+1,self.MaxHeight):#向下
91
if self.GetArrayXY(x1,y)==0 and hasReachPoint[y*self.MaxWidth+x1]<n:
92
if self.IsLineable(x1,y,x2,y2,1) or self.IsLineable(x1,y,x2,y2,2):
93
path+=[x1,y,x2,y2]
94
return path
95
else:#到達不了,左右轉彎,遞歸
96
hasReachPoint[y*self.MaxWidth+x1]+=1
97
p=self.IsNTurnReachable(x1,y,x2,y2,path+[x1,y],n-1,True,hasReachPoint)
98
if p!=False:
99
return p
100
else:
101
break
102
return False
103
#--------------------------------------------------------
104
def IsLinkAble(self,x1,y1,x2,y2,n):#n連看的計算函數
105
if n<=0:
106
return False
107
hasReachPoint=[0]*(self.MaxWidth*self.MaxHeight)
108
for i in [0,1,2,3]:
109
if self.isLineable(x1,y1,x2,y2,i):
110
path=[x1,y1,x2,y2]
111
return path
112
path=[x1,y1]
113
p=self.IsNTurnReachalbe(x1,y1,x2,y2,path,n-1,False,hasReachPoint)
114
if p:
115
return p
116
p=self.IsNTurnReachalbe(x1,y1,x2,y2,path,n-1,True,hasReachPoint)
117
if p:
118
return p
119
return False


2

3

4

5

6

7

8


9

10

11


12

13

14


15

16

17


18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

當然,現在想到還有可以繼續優化的地方,例如尋路時,從起點和目標點同時出發尋路,而不是只從一個點出發尋路。這樣做或許還可以雙線程優化,不過具體做法就沒有細想了。