Search code examples
pythonheuristicssliding-tile-puzzle

How can I speed up my misplaced tiles heuristic for the 8 puzzle problem?


My lists are always of length 8 (7 indices), and always contain numbers 0-8

I currently do this to find the sum of misplaced tiles:

def misplacedTilesHeuristic(stateObj, goal):
    sum = 0

    for elem in range(len(goal)):
        if goal[elem] != stateObj[elem]:
            sum+=1

    return sum

How can I make this faster?

Edit:

misplacedTilesHeuristic((4, 5, 3, 1, 0, 6, 7, 2, 8), (0, 1, 2, 3, 4, 5, 6, 7, 8))

Solution

  • as already mentioned, the one-liner is a good idea, for example like this :

    def comp(stObj,goal):
        sum = 0
        for elem in range(len(goal)):
            if goal[elem] != stObj[elem]:sum +=1
        return sum
    
    def prop1(stObj,goal):
        sum = 0
        for i,j in zip(stObj,goal):
            if i !=j:sum +=1
        return sum
    
    def prop2(stObj,goal):
        return sum([i!=j for i, j in zip(stObj,goal)])
    
    def prop3(stObj,goal):
        return sum([i is not j for i, j in zip(stObj,goal)])
    
    def prop4(stObj,goal):
        return sum(map(lambda x, y: x != y, stObj, goal))
    
    t = (4, 5, 3, 1, 0, 6, 7, 2, 8), (0, 1, 2, 3, 4, 5, 6, 7, 8)
    
    

    Benchmark:

    %timeit comp(*t)
    1.64 µs ± 46.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    %timeit prop1(*t)
    1.22 µs ± 27.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) 
    %timeit prop2(*t)
    1.67 µs ± 86.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    %timeit prop3(*t)
    1.6 µs ± 48.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    %timeit prop4(*t)
    1.79 µs ± 32.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    The prop1() shows the best times for the moment with almost 34.4% better performance, but I think that it could be better :)