Static Oneplus 不可控制论

2011/04/02 - by Oneplus • python人工智能实验哗哗的

访问量神马的最喜欢了


当当当~过节给大家发福利啦。
这货就是,神马人工智能啊、a*搜索啊、八数码啊、实验啊、Python啊,你懂的。都是哗哗的啦。
不过伦家写300来行的java风的C++版Python,也挺不容易的啦。乃们表拿了东西也不吭一声就走了,怎么也留个爪神马的。
输入那么浮云的东西,用一个叫eight.in的文件存一下,空格就画个x就好了。

# coding=utf-8
import re
import os
import math

SIZE = 362881
f    = range(0, SIZE, 1)
g    = range(0, SIZE, 1)
path = range(0, SIZE, 1)
step = range(0, SIZE, 1)

sourceNumState = -1
targetNumState = -1
hashedSourceNumState = -1
hashedTargetNumState = -1

distance = [
	[0 for a in range(10)] for b in range(10)
]
adjancy = [
	[1, 3],
	[0, 2, 4], 
	[1, 5], 
	[0, 4, 6], 
	[1, 3, 5, 7], 
	[2, 4, 8], 
	[3, 7], 
	[4, 6, 8], 
	[5, 7]
]
moves = [
	['r', 'd'], 
	['l', 'r', 'd'],
	['l', 'd'], 
	['u', 'r', 'd'],
	['u', 'l', 'r', 'd'], 
	['u', 'l', 'd'],
	['u', 'r'], 
	['u', 'l', 'r'], 
	['u', 'l']
]
location = [
	[0, 0], [0, 1], [0, 2],
	[1, 0], [1, 1], [1, 2],
	[2, 0], [2, 1], [2, 2]
]

class node():
	key   = -1
	value = 10000000000
	
	def __init__(self, key, value):
		self.key   = key
		self.value = value
		
	def lessThan(self, node_t):
		if self.value < node_t.value or (self.value == node_t.value and self.key > node_t.key):
			return True
		else:
			return False
			
	def getKey(self):
		return self.key
		
	def getValue(self):
		return self.value

class hash():
	hashTable = range(0, SIZE, 1)
	
	def __init__(self):
		for i in range(0, SIZE, 1):
			self.hashTable[i] = -1

	def findHashPosition(self, value):
		hashID = value % SIZE
		while self.hashTable[hashID] != -1 and self.hashTable[hashID] != value:
			# print 'in while', self.hashTable[hashID]
			hashID = hashID + 1
			if hashID == SIZE:
				hashID = 0
		return hashID
			
	def findHashValue(self, position):
		if position >= SIZE or position < 0:
			return -1
		else:
			return self.hashTable[position]
			
	def insertHash(self, value):
		position = self.findHashPosition(value)
		# print 'insertHash:: hash position :', position
		self.hashTable[position] = value
		return position
		
class priority_queue():
	last = 0
	queue = []
	# queue save hash id

	def __init__(self):
		self.last = 0
		self.queue = [ node(10000000000, 10000000000) ] * SIZE
		# print type( self.queue[100000] )
	
	def empty(self):
		if self.last == 0:
			return True
		else:
			return False

	def top(self):
		return self.queue[1]

	def pop(self):
		self.queue[ 1 ] = self.queue[ self.last ]
		self.last = self.last - 1
		self.siftDown( 1 )
	
	def push( self, value ):
		self.last = self.last + 1
		self.queue[ self.last ] = value
		self.queue[ 0 ] = value
		self.siftUp( self.last )
	
	def getF( self, p ):
		# print self.queue[ p ]
		return f[ hashTable.findHashPosition(self.queue[ p ]) ]
	
	def siftUp( self, p ):
		i = p / 2
		j = p
		tmp = self.queue[ p ]
		# print type( tmp )
		
		while tmp.lessThan(self.queue[ i ]):
			# print i
			self.queue[ j ] = self.queue[ i ]
			j = i
			i = j / 2
		self.queue[ j ] = tmp

	def siftDown( self, p ):
		i = p * 2
		j = p
		tmp = self.queue[ p ]
		
		while i <= self.last:
			if i < self.last and self.queue[ i + 1 ].lessThan(self.queue[ i ]):
				i = i + 1
			if self.queue[ i ].lessThan( tmp ) == False:
				break
			else:
				self.queue[ j ] = self.queue[ i ]
				j = i
				i = j * 2
		self.queue[ j ] = tmp

openTable = priority_queue()
hashTable = hash()
closeTable = range(0, SIZE, 1)
		
def convertToNum( arrayState ):
	ret = 0
	for i in range(0, 9, 1):
		ret = ret * 10
		ret = ret + int(arrayState[i])
	return ret
	
def convertToArray( numState ):
	ret = range(0, 9, 1)
	for i in range(8, -1, -1):
		ret[i]   = numState % 10
		numState = numState / 10
	return ret
	
def isSolvable(sourceState, targetState):
	odd = 0
	eve = 0
	for i in range(0, 9, 1):
		for j in range(0, 9, 1):
			if sourceState[i] > sourceState[j] and sourceState[i] > 0 and sourceState[j] > 0:
				odd = odd + 1
			if targetState[i] > targetState[j] and targetState[i] > 0 and targetState[j] > 0:
				eve = eve + 1
	if odd % 2 == eve % 2:
		return True
	else:
		return False

def getSourceState():
	fp  = open('eight.in', 'r')
	sourceState = re.split('\n| ', fp.read())
	fp.close()
	
	for i in range(0, 9, 1):
		if sourceState[i] == 'x':
			sourceState[i] = '0'
	return sourceState
	
def getTargetState():
	targetState = []
	for i in range(0, 8, 1):
		targetState.append( str(i + 1) )
	targetState.append('0')
	
	return targetState

def getEmptyPositionInArray( arrayState ):
	for i in range(0, 9, 1):
		if arrayState[i] == 0:
			return i
			
def getEstimateValue( numState ):
	ret = 0
	for i in range(0, 9, 1):
		# print i, numState[i]
		ret = ret + distance[(i + 1) % 9][ int(numState[i]) ]
	return ret

def solve(srcArrayState, tagArrayState):
	for i in range(0, SIZE, 1):
		closeTable[i] = 0
	
	for i in range(0, 9, 1):
		for j in range(0, 9, 1):
			distance[(i + 1) % 9][(j + 1) % 9] = abs(location[i][0] - location[j][0]) + abs(location[i][1] - location[j][1])
			
	sourceNumState = convertToNum(srcArrayState)
	targetNumState = convertToNum(tagArrayState)
	hashedSourceNumState = hashTable.insertHash(sourceNumState)
	hashedTargetNumState = hashTable.insertHash(targetNumState)
	
	# print 'sourceNumState :', sourceNumState, hashedSourceNumState
	g[ hashedSourceNumState ] = 0;
	f[ hashedSourceNumState ] = getEstimateValue(srcArrayState)
	f[ hashedTargetNumState ] = -1;
	openTable.push( node(sourceNumState, f[ hashedSourceNumState ]) )
	
	while True:
		currentNumState = openTable.top().key
		currentArrayState = convertToArray( currentNumState )
		hashedCurrentNumState = hashTable.insertHash( currentNumState )
		openTable.pop()
		# print 'currentNumState :', currentNumState, hashedCurrentNumState
		# raw_input("Press ENTER to exit")
		
		if currentNumState == targetNumState:
			stack = []
			traceNumState = currentNumState
			hashedTraceNumState = hashTable.insertHash(traceNumState)
			while hashedTraceNumState != hashedSourceNumState:
				stack.append( step[ hashedTraceNumState ] )
				hashedTraceNumState = path[ hashedTraceNumState ]

			for move in reversed( stack ):
				print move
			break
		
		closeTable[ hashedCurrentNumState ] = 2
		emptyPosition = getEmptyPositionInArray( currentArrayState )
		
		for nextPosition in adjancy[ emptyPosition ]:
			nextArrayState = []
			for ii in currentArrayState:
				nextArrayState.append(str(ii))
			
			nextArrayState[ emptyPosition ] = currentArrayState[ nextPosition ]
			nextArrayState[ nextPosition ]  = '0'
			
			# print 'nextArrayState :', nextArrayState
			nextNumState = convertToNum( nextArrayState )
			
			hashedNextNumState = hashTable.insertHash( nextNumState );
			
			if closeTable[ hashedNextNumState ] == 0:
				closeTable[ hashedNextNumState ] = 1;
				g[ hashedNextNumState ] = g[ hashedCurrentNumState ] + 1
				f[ hashedNextNumState ] = g[ hashedNextNumState ] + getEstimateValue( currentArrayState )
				path[ hashedNextNumState ] = hashedCurrentNumState
				step[ hashedNextNumState ] = moves[ emptyPosition ][ adjancy[ emptyPosition ].index( nextPosition ) ]
				openTable.push( node(nextNumState, f[hashedNextNumState]) )
			elif closeTable[ hashedNextNumState ] == 1 and g[ hashedCurrentNumState ] + 1 < g[ hashedNextNumState ]:
				g[ hashedNextNumState ] = g[ hashedCurrentNumState ] + 1
				f[ hashedNextNumState ] = g[ hashedNextNumState ] + getEstimateValue( currentArrayState )
				path[ hashedNextNumState ] = hashedCurrentNumState
				step[ hashedNextNumState ] = moves[ emptyPosition ][ adjancy[ emptyPosition ].index( nextPosition ) ]
				openTable.pop()
	
def main():
	sourceArrayState = getSourceState()
	targetArrayState = getTargetState()
	sourceNumState = convertToNum(sourceArrayState)
	targetNumState = convertToNum(targetArrayState)
	print sourceNumState, targetNumState
	
	if isSolvable(sourceArrayState, targetArrayState) == False:
		print 'What the Hell!'
	else:
		solve(sourceArrayState, targetArrayState)
		
if __name__ == '__main__':
	main()

blog comments powered by Disqus