我正在尝试使用堆来实现基本的贪婪的“最佳优先搜索”算法,但我很接近但很困难。任何帮助将由衷的感谢。
我有一个图类,可以读取文本文件,其中包含简单矩阵形式的数据,类似于:
~ 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;
}