1 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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
import numpy as np import time
class State: def __init__(self, state, directionFlag=None, parent=None, depth=1): self.state = state self.direction = ['up', 'down', 'right', 'left'] if directionFlag: self.direction.remove(directionFlag) self.parent = parent self.symbol = ' ' self.answer = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, State.symbol]]) self.depth = depth num = 0 for i in range(len(state)): for j in range(len(state)): if self.state[i, j] != ' 'and self.state[i, j] != self.answer[i, j]: num += 1 self.cost = num + self.depth def showPath(self): for i in range(4): for j in range(4): if self.state[i, j] == ' ': print(self.state[i, j], end=' ') elif int(self.state[i, j])>9: print(self.state[i, j], end=' ') else: print(self.state[i, j], end=' ') print("\n") return def getEmptyPos(self): postion = np.where(self.state == self.symbol) return postion def expandStates(self): if not self.direction: return [] subStates = [] row, col = self.getEmptyPos() if 'left' in self.direction and col > 0: s = self.state.copy() temp = s.copy() s[row, col] = s[row, col-1] s[row, col-1] = temp[row, col] news = State(s, directionFlag='right', parent=self, depth=self.depth+1) subStates.append(news) if 'up' in self.direction and row > 0: s = self.state.copy() temp = s.copy() s[row, col] = s[row-1, col] s[row-1, col] = temp[row, col] news = State(s, directionFlag='down', parent=self, depth=self.depth+1) subStates.append(news) if 'down' in self.direction and row < 3: s = self.state.copy() temp = s.copy() s[row, col] = s[row+1, col] s[row+1, col] = temp[row, col] news = State(s, directionFlag='up', parent=self, depth=self.depth+1) subStates.append(news) if self.direction.count('right') and col < 3: s = self.state.copy() temp = s.copy() s[row, col] = s[row, col+1] s[row, col+1] = temp[row, col] news = State(s, directionFlag='left', parent=self, depth=self.depth+1) subStates.append(news) return subStates def IDS(self): for depth in range(10000): path, flag = self.DLS(depth) if flag != -1: return path, flag return None, None
def DLS(self, depth): global amount amount += 1 if (self.state == self.answer).all(): s = self path = [] while s.parent: path.append(s.parent) s = s.parent path.reverse() return path, 1
if depth == 0: return None, -1 cutoff = False subStates = self.expandStates() for s in subStates: result, flag = s.DLS(depth-1) if flag == -1: cutoff = True else: if result != None: return result, flag if cutoff: return None, -1
if __name__ == '__main__': emptySite = ' ' State.symbol = emptySite originState = State(np.array([[1, 2, 7, 3], [5, 6 , 11, 4], [9, 10, 15, 8], [13, 14, 12, emptySite]])) State.answer = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12],[13, 14, 15, State.symbol]]) s1 = State(state=originState.state) start = time.perf_counter_ns() global amount amount = 0 path, flag = s1.IDS() end = time.perf_counter_ns() if path: steps = 0 for node in path: print("Step: ", steps) node.showPath() steps += 1 print("Step: ", steps) for i in range(4): for j in range(4): if State.answer[i, j] == ' ': print(State.answer[i, j], end=' ') elif int(State.answer[i, j])>9: print(State.answer[i, j], end=' ') else: print(State.answer[i, j], end=' ') print("\n") print("Total steps is: ", steps) print("The number of notes expended: ", amount) print("CPU execution time is", (int(end)- int(start))/1000000, "ms")
|