使用堆的最佳优先搜索实现

时间:2018-10-16 20:57:37

标签: java algorithm search heap

我正在尝试使用堆来实现基本的贪婪的“最佳优先搜索”算法,但我很接近但很困难。任何帮助将由衷的感谢。

我有一个图类,可以读取文本文件,其中包含简单矩阵形式的数据,类似于:

~          val   Ab   Cd   Ef   Gh   Ij   Kl   Mn
AB           ~    ~    1    1    ~    ~    ~    ~
CD           ~    1    ~    ~    1    ~    ~    ~
EF           G    4    ~    ~    1    ~    ~    ~
GH           ~    2    2    ~    ~    ~    8    2
IJ           S    ~    2    ~    3    ~    ~    1
KL           ~    ~    ~    2    5    ~    ~    1
MN           ~    ~    ~    ~    3    4    1    ~

文本文件矩阵表示节点的图,其中数字表示连接两个节点的边的距离,字母表示节点是图的起点还是终点。

我的程序在读取此文本文件时输出以下内容:

Node AB, abbrev Ab, value ~
AB has edge to: CD labeled: 1
AB has edge to: EF labeled: 1
AB has edge from: CD labeled: 1
AB has edge from: EF labeled: 4
AB has edge from: GH labeled: 2

Node CD, abbrev Cd, value ~
CD has edge to: AB labeled: 1
CD has edge to: GH labeled: 1
CD has edge from: AB labeled: 1
CD has edge from: GH labeled: 2
CD has edge from: IJ labeled: 2

Node EF, abbrev Ef, value G
EF has edge to: AB labeled: 4
EF has edge to: GH labeled: 1
EF has edge from: AB labeled: 1
EF has edge from: KL labeled: 2

Node GH, abbrev Gh, value ~
GH has edge to: AB labeled: 2
GH has edge to: CD labeled: 2
GH has edge to: KL labeled: 8
GH has edge to: MN labeled: 2
GH has edge from: CD labeled: 1
GH has edge from: EF labeled: 1
GH has edge from: IJ labeled: 3
GH has edge from: KL labeled: 5
GH has edge from: MN labeled: 3

Node IJ, abbrev Ij, value S
IJ has edge to: CD labeled: 2
IJ has edge to: GH labeled: 3
IJ has edge to: MN labeled: 1
IJ has edge from: MN labeled: 4

Node KL, abbrev Kl, value ~
KL has edge to: EF labeled: 2
KL has edge to: GH labeled: 5
KL has edge to: MN labeled: 1
KL has edge from: GH labeled: 8
KL has edge from: MN labeled: 1

Node MN, abbrev Mn, value ~
MN has edge to: GH labeled: 3
MN has edge to: IJ labeled: 4
MN has edge to: KL labeled: 1
MN has edge from: GH labeled: 2
MN has edge from: IJ labeled: 1
MN has edge from: KL labeled: 1

此示例中最佳首次搜索的正确输出应如下所示:

Start node Ij Goal node Ef
Finished Nodes
Ij    0   Ij
Mn    1   Ij-Mn
Cd    2   Ij-Cd
Kl    2   Ij-Mn-Kl
Ab    3   Ij-Cd-Ab
Gh    3   Ij-Gh
Ef    4   Ij-Mn-Kl-Ef

我的输出很接近,我只是不输出序列中的最后一个节点,当然,我得到的是垂直序列而不是水平序列。

Finished Nodes: *********************************

Ij   0
Mn   1 prev: Ij
Ij - 
Cd   2 prev: Ij
Ij - 
Kl   2 prev: Mn
Ij - 
Mn - 
Gh   3 prev: Ij
Ij - 
Gh   3 prev: Ij
Ij - 
Ab   3 prev: Cd
Ij - 
Cd - 
Ab   3 prev: Cd
Ij - 
Cd - 
Ef   4 prev: Kl
Ij - 
Mn - 
Kl -  

我的代码的相关部分如下:

//main array list used with heap methods
    aList = new ArrayList<Node>(25);

    //create a new heap object with input graph and empty array list
    LCFS_heap = new Heap(aList, g); 

    //aList.add(findGoal(g.nodeList));

    //set the starting node's previous node to itself
    findStart(g.nodeList).setPreviousNode(findStart(g.nodeList));
    //set the starting node's distance to itself to zero
    findStart(g.nodeList).setDistance("0");
    //set the starting node's start attribute to true
    findStart(g.nodeList).setStart(true);
    //set the starting node's discovered attribute to true
    findStart(g.nodeList).setDiscovered(true);



    System.out.println("Finished Nodes: *********************************\n");

    //output the starting node
    System.out.println(findStart(g.getNodeList()).toString());

    //begin the lowest cost first search at the designated starting node
    LCFS(findStart(g.nodeList));


    //remove root, then using next heap element as new root, repeat process until goal node is found

    //if the root node is not the goal node recursively call lowest cost first search method 

    while(!aList.get(0).getVal().equalsIgnoreCase("g") && aList.size()>0)
    {
        //if heap contains at least 1 element
        if (LCFS_heap.getHeapSize() > 0)
        {   
            //remove the root of the heap and recursively call lowest cost first search method on the root that was just removed
            LCFS(LCFS_heap.heap_Extract(aList));
        }   
    }

我相信我的堆类中的堆方法是正确的,但作为参考,重要的堆方法如下:

public void Heapify(ArrayList<Node> A, int i)
{
    Node smallest;
    Node temp;
    int index;

    int l = Left(A,i);
    int r = Right(A,i);


    //if (l <= heapSize-1 && Integer.parseInt(A.get(l).getVal()) < Integer.parseInt(A.get(i).getVal()))
    if (l <= heapSize-1 && Integer.parseInt(A.get(l).getDistance()) < Integer.parseInt(A.get(i).getDistance()))
    {   
        //left child is smaller
        smallest = A.get(l);
        index = l;
    }   
    else
    {   
        //parent node is smaller
        smallest = A.get(i);
        index = i;
    }   

    //if (r <= heapSize-2 && Integer.parseInt(A.get(r).getVal()) < Integer.parseInt(smallest.getVal()))
    if (r <= heapSize-2 && Integer.parseInt(A.get(r).getDistance()) < Integer.parseInt(smallest.getDistance()))
    {   
        //right child is smaller
        smallest = A.get(r);
        index = r;
    }

    //if (index != i)
    if (index != i)
    {   
        //if the smallest element is not the parent node
        //swap the smallest child with the parent  
        temp = A.get(i);
        A.set(i, A.get(index));
        A.set(index, temp);

        //recursively call heapify method to check next parent/child relationship
        Heapify(A, index);
    }
}   

//method to construct min heap from unordered arraylist of nodes
public void Build_min_Heap(ArrayList<Node> A)
{
    int i;
    int heapSize = A.size();

    for (i = (heapSize/2); i>=0; i--)
    {
        Heapify(A, i);
    }   

}
//decreases the value of a given node, used with insert method
public void heap_Decrease_Key(ArrayList<Node> A, int i, int key)
{
    Node parent;
    Node child;
    Node temp;

    if (key > i)
    {   
        System.out.println("error key must be less than i");
        //break;
    }

    //change to setDistance
    A.get(i).setVal(Integer.toString(key));
    //change to getDistance
    while(i>0 && Integer.parseInt(A.get(Parent(A,i)).getVal()) > Integer.parseInt(A.get(i).getVal()) ) 
    {
        parent = A.get(Parent(A,i));
        child = A.get(i);

        temp = parent;

        //take the child node and place it in the parent node's place
        A.set(Parent(A,i), child);
        //take the parent node and place it in the child node's place
        A.set(i, temp);
    }
}

//method to sort in descending order, a min heap
public void heap_Sort(ArrayList<Node> A)
{
Node temp;

    Build_min_Heap(A);
    if (A.size() > 0)
    {
        for(int i = A.size()-1; i >= 1; i--)
        {
            //exchange a[0] with a[i]
            temp = A.get(0);
            A.set(0, A.get(i));
            A.set(i, temp);

            heapSize--;
            System.out.println("\n" +this.gr.toString2());

            Heapify(A, 0);
        }
    }
}


public Graph getGr() {
    return gr;
}

public void setGr(Graph gr) {
    this.gr = gr;
}

public Node heap_Extract(ArrayList<Node> A)
{
    Node min = A.get(0);

    //min = A.get(0);
    //if (heapSize>0)
    if (A.size()>0)
    {   
        min = A.get(0);

        //A.set(0, A.get(heapSize-1));
        A.set(0, A.get(A.size()-1));

        //A.remove(heapSize-1);
        A.remove(A.size()-1);
        //decrement heapSize
        heapSize--;
        Heapify(A, 0);  
    }   
    return min;
}

0 个答案:

没有答案