Как рассчитать длину алгоритма Path of A *? - PullRequest
0 голосов
/ 11 марта 2020

Я работаю над A_star algorithm, и я реализовал алгоритм, показанный ниже, в программе Python, и я пытаюсь найти the length of the path, который получил. Я искал на многих сайтах, но ничего не понял. Любая помощь, пожалуйста? Как я мог найти путь? Есть ли какие-либо шаги, которые мне нужно добавить в код, пока я не смогу напечатать длину пути?

Мой код показан ниже:

import matplotlib.pyplot as plt

#grid format
# 0 = navigable space
# 1 = occupied space

import time


import random
import math
grid = [[0, 1, 0, 0, 0, 0],
        [0, 1, 1, 1, 0, 0],
        [1, 1, 1, 1, 0, 0],
        [0, 1, 0, 1, 1, 1],
        [0, 0, 0, 0, 1, 0]]

heuristic = [[9, 8, 7, 6, 5, 4],
             [8, 7, 6, 5, 4, 3],
             [7, 6, 5, 4, 3, 2],
             [6, 5, 4, 3, 2, 1],
             [5, 4, 3, 2, 1, 0]]

init = [0,0]                            #Start location is (0,0) which we put it in open list.
goal = [len(grid)-1,len(grid[0])-1]     #Our goal in (4,5) and here are the coordinates of the cell.


plt.plot(0,10)
plt.plot(0,-len(grid)-10)
plt.grid(True)
plt.axis("equal")

plt.plot([-1, len(grid[0])],[[-x/2 for x in range(-1,len(grid)*2+1)], [-y/2 for y in range(-1,len(grid)*2+1)]], ".k")
plt.plot([[x/2 for x in range(-2,len(grid[0])*2+1)],[x/2 for x in range(-2,len(grid[-1])*2+1)]],[1, -len(grid)],".k")

plt.plot(init[1],-init[0],"og")
plt.plot(goal[1],-goal[0],"ob")



#Below the four potential actions to the single field
'''
delta = [[-1 , 0],   #up
         [ 0 ,-1],   #left
         [ 1 , 0],   #down
         [ 0 , 1]]   #right

delta_name = ['^','<','V','>']  #The name of above actions
'''

delta =      [[1, 0, 1],
              [0, 1, 1],
              [-1, 0, 1],
              [0, -1, 1],
              [-1, -1, math.sqrt(2)],
              [-1, 1, math.sqrt(2)],
              [1, -1, math.sqrt(2)],
              [1, 1, math.sqrt(2)]]

delta_name = ['▼','►','▲','◄','◤','◥','◣','◢']

#cost = 1   #Each step costs you one

drone_height = 60

kg = 0.6
ke = 1
kh = 0.8

risk = [i for i in range(50,60)]
penalty1 = 10
penalty2 = 1.5
penalty3 = 0



def search():
    show_result = True
    t1 = time.time()  
    #open list elements are of the type [g,x,y]

    closed = [[0 for row in range(len(grid[0]))] for col in range(len(grid))]
    action = [[-1 for row in range(len(grid[0]))] for col in range(len(grid))]
    #We initialize the starting location as checked
    closed[init[0]][init[1]] = 1
    expand=[[-1 for row in range(len(grid[0]))] for col in range(len(grid))]

    elevation1 = [[0 for row in range(len(grid[0]))] for col in range(len(grid))]

    for i in range(len(grid)):    
        for j in range(len(grid[0])):
            if grid[i][j] == 1:
                elevation1[i][j] = random.randint(1,100)
                if elevation1[i][j] >= drone_height:
                    plt.plot(j,-i,".k", markersize=10)
                elif elevation1[i][j] in risk:
                    plt.plot(j,-i,".r",markersize=10)                
                else:
                    plt.plot(j,-i,"sm")
            elif elevation1[i][j] == 0 and ([i,j] != init and [i,j] != goal):
                        plt.plot(j,-i,"sm")
            #else:
                #elevation1[i][j] = 0

    elevation2 = [[0 for row in range(len(grid[0]))] for col in range(len(grid))]
    for i in range(len(elevation1)):
        for j in range(len(elevation1[0])):

            if elevation1[i][j] >= drone_height:
                elevation2[i][j] = elevation1[i][j]*penalty1
            elif elevation1[i][j] in risk:
                elevation2[i][j] = elevation1[i][j]*penalty2
            else:
                elevation2[i][j] = elevation1[i][j]*penalty3




    # we assigned the cordinates and g value
    x = init[0]
    y = init[1]
    g = 0
    h = math.sqrt((x - goal[0])**2 + (y - goal[1])**2)
    #e = elevation[x][y]
    e = elevation2[x][y]
    f = kg*g + kh*h + ke*e

    #our open list will contain our initial value
    open = [[f, g, h, x, y]]

    '''
   We are going to use two flags
   1- found and it will be True when the goal position is found.
   2- resign it will be True if we couldn't find the goal position and explore everything.
   '''
    found  = False   #flag that is set when search complete
    resign = False   #Flag set if we can't find expand
    count = 0

    #print('initial open list:')
    #for i in range(len(open)):
            #print('  ', open[i])
    #print('----')
    t1 = time.time() 
    while found is False and resign is False:

        #Check if we still have elements in the open list
        if len(open) == 0:    #If our open list is empty, there is nothing to expand.
            resign = True
            show_result = False
            print('Fail')
            print('############# Search terminated without success')
            print()
        else:
            #if there is still elements on our list
            #remove node from list
            open.sort()             #sort elements in an increasing order from the smallest g value up
            open.reverse()          #reverse the list
            next = open.pop()       #remove the element with the smallest g value from the list
            #print('list item')
            #print('next')

            #Then we assign the three values to x,y and g. Which is our expantion.
            x = next[3]
            y = next[4]
            g = next[1]
            #elvation[x][y] = np.random.randint(100, size=(5,6))
            expand[x][y] = count
            count+=1

            #Check if we are done
            if x == goal[0] and y == goal[1]:
                found = True
                print(next) #The three elements above this "if".
                print('############## Search is success')
                print()

            else:
                #expand winning element and add to new open list
                for i in range(len(delta)):       #going through all our actions the four actions
                    #We apply the actions to x and y with additional delta to construct x2 and y2
                    x2 = x + delta[i][0]
                    y2 = y + delta[i][1]
                    #if x2 and y2 falls into the grid
                    if x2 >= 0 and x2 < len(grid) and y2 >=0 and y2 <= len(grid[0])-1:

                        #if x2 and y2 not checked yet and there is not obstacles
                        #if closed[x2][y2] == 0 and elevation[x2][y2] < drone_height and elevation[x2][y2] not in risk:
                        if  closed[x2][y2] == 0 and elevation2[x2][y2] == 0:
                            g2 = g + delta[i][2]             #we increment the cose

                            h2 = math.sqrt((x2 - goal[0])**2 + (y2 - goal[1])**2)
                            e2 = elevation2[x2][y2]
                            f2 = kg*g2 + kh*h2 + ke*e2

                            open.append([f2,g2,h2,x2,y2])
                            #we add them to our open list
                            plt.plot(y2,-x2,"xc")
                            #print('append list item')
                            #print([g2,x2,y2])
                            #Then we check them to never expand again
                            closed[x2][y2] = 1
                            action[x2][y2] = i
                        plt.pause(0.001)

    t2 = time.time()
    runtime = t2-t1
    print('The elapsed time= ',runtime)
    for i in range(len(expand)):
        print(expand[i])
    print()
    policy=[[' ' for row in range(len(grid[0]))] for col in range(len(grid))]
    x = goal[0]
    y = goal[1]
    policy[x][y]='*'
    visx = [y]
    visy = [-x]
    while x !=init[0] or y !=init[1]:
        x2=x-delta[action[x][y]][0]
        y2=y-delta[action[x][y]][1]
        policy[x2][y2]= delta_name[action[x][y]]
        x=x2
        y=y2
        visx.append(y)
        visy.append(-x)

    for i in range(len(policy)):
        print(policy[i])
    print()

    for i in range(len(elevation1)):
        print(elevation1[i])
    print()

    for i in range(len(elevation2)):
        print(elevation2[i])
    print()


    #plt.plot(visx,visy, "-r")

    if show_result:
        plt.plot(visx,visy, "-r")


        plt.show()




search()
...