How to improve performance of this code?

前端 未结 7 770
一生所求
一生所求 2020-11-21 06:54

Thanks to some help from people here, I was able to get my code for Tasmanian camels puzzle working. However, it is horribly slow (I think. I\'m not sure because this is my

7条回答
  •  孤独总比滥情好
    2020-11-21 07:37

    tkerwin is correct that you should be using a set for closedlist, which speeds things up a lot, but it is still kind of slow for 4 camels on each side. The next problem is that you are allowing a lot of solutions that aren't possible because you are allowing fCamels to go backwards and bCamels to go forward. To fix this, replace the lines,

    if(igap > 0):
        genn(igap, igap-1)
    if(igap > 1):
        genn(igap, igap-2)
    if igap < len(formation) - 1:
        genn(igap, igap+1)
    if igap < len(formation) - 2:
        genn(igap, igap+2)
    

    with

    if(igap > 0 and formation[igap-1] == fCamel):
        genn(igap, igap-1)
    if(igap > 1 and formation[igap-2] == fCamel):
        genn(igap, igap-2)
    if (igap < len(formation) - 1) and formation[igap+1] == bCamel:
        genn(igap, igap+1)
    if (igap < len(formation) - 2) and formation[igap + 2] == bCamel:
        genn(igap, igap+2)
    

    then I get solution to the 4 camels on each side problem in like .05 seconds rather than 10 seconds. I also tried 5 camels on each side and it took 0.09 seconds. I also am using a set for closedlist and heapq rather than Queue.

    Additional speed-up

    You can get an additional speed-up by using your heuristic correctly. Currently, you are using the line

    openlist.put((current.g + heuristicf(neighbor), node(neighbor, current.g + 1, current)))
    

    (or the heapq version of that) but you should change it to

    openlist.put((heuristicf(neighbor), node(neighbor, current.g + 1, current)))
    

    This doesn't factor in the number of moves that has been needed, but that is okay. With this puzzle (and the screening out of moves that move camels in the wrong direction), you don't need to worry about the number of moves it takes - either a move advances you towards the solution or it will come to a dead end. In other words, all possible solutions require the same number of moves. This one change takes the time to find the solution of the 12 camels on each side case from over 13 seconds (even using the heapq, set for closedlist, and the changes to find the neighbors above) to 0.389 seconds. That's not bad.

    By the way, a better way to find if you've found the solution is to check if the index of the first fCamel is equal to the length of the formation/2 + 1(using int division) and that the index before that is equal to the gap.

提交回复
热议问题