import java.util.Vector;
public class BreadthFirstSearch extends SearchApplet {
public void init() {
// Define a test network before calling the super class 'init':
addNode("0", 0.0f, 0.0f);
addNode("1", 1.0f, 1.0f);
addNode("2", 5.0f, 2.0f);
addNode("3", 2.0f, 5.0f);
addNode("4", 7.0f, 5.0f);
addNode("5", 8.0f, 8.0f);
addNode("6", 10.0f, 5.0f);
addNode("7", 8.0f, 2.0f);
addNode("8", 12.0f, 8.0f);
addNode("9", 13.0f, 5.0f);
addLink(0,1);
addLink(1,2);
addLink(2,3);
addLink(2,4);
addLink(4,5);
addLink(4,6);
addLink(6,8);
addLink(8,9);
addLink(2,7);
addLink(7,9);
// Now that we have defined the network to search, we
// can now call the super class init:
super.init();
}
/** findPath - abstract method in super class */
// Breadth first search algorithm from "Algorithms"
// (Cormen, Leiserson, Rivest) page 460:
public int [] findPath(int node_1, int node_2) { // return an array of node indices
System.out.println("Entered BreadthFirstSearch.findPath(" +
node_1 + ", " + node_2 + ")");
if (node_1 == node_2) {
repaintPath(null, 0);
return null;
}
// data structures for depth first search:
boolean [] visitedFlag = new boolean[numNodes];
float [] distanceToNode = new float[numNodes];
int [] predecessor = new int[numNodes];
Queue queue = new Queue(numNodes + 2);
// data structures for graphical display (only):
int [] display_path = new int[2 * numNodes + 1];
int num_display_path = 0;
for (int i=0; i<numNodes; i++) {
visitedFlag[i] = false;
distanceToNode[i] = 10000000.0f;
predecessor[i] = -1;
}
visitedFlag[node_1] = true;
distanceToNode[node_1] = 0.0f;
queue.enqueue(node_1);
outer: while (queue.isEmpty() == false) {
int head = queue.head();
int [] connected = connected_nodes(head);
if (connected != null) {
for (int i=0; i<connected.length; i++) {
if (visitedFlag[connected[i]] == false) {
distanceToNode[connected[i]] = distanceToNode[head] + 1.0f;
predecessor[connected[i]] = head;
queue.enqueue(connected[i]);
display_path[num_display_path++] = head;
display_path[num_display_path++] = connected[i];
repaintPath(display_path, num_display_path);
if (connected[i] == node_2) break outer; // we are done
}
}
visitedFlag[head] = true;
queue.dequeue(); // ignore return value
}
}
// now calculate the shortest path from the predecessor array:
int [] ret = new int[numNodes + 1];
int count = 0;
ret[count++] = node_2;
for (int i=0; i<numNodes; i++) {
ret[count] = predecessor[ret[count - 1]];
count++;
if (ret[count - 1] == node_1) break; // back to starting node
}
num_display_path = 0;
int [] ret2 = new int[count];
for (int i=0; i<count; i++) {
ret2[i] = ret[count - 1 - i];
if (i > 0) { // re-calculate the plot display points:
display_path[num_display_path++] = ret2[i-1];
display_path[num_display_path++] = ret2[i];
}
}
// now re-calculate the display path points:
repaintPath(display_path, num_display_path);
return ret2;
}
// Queue algorithm from "Algorithms" (Cormen, Leiserson, Rivest) page 202:
protected class Queue {
public Queue(int num) {
queue = new int[num];
head = tail = 0;
len = num;
}
public Queue() {
this(400);
}
private int [] queue;
int tail, head, len;
public void enqueue(int n) {
queue[tail] = n;
if (tail >= (len - 1)) {
tail = 0;
} else {
tail++;
}
}
public int dequeue() {
int ret = queue[head];
if (head >= (len - 1)) {
head = 0;
} else {
head++;
}
return ret;
}
public boolean isEmpty() {
return head == (tail + 1);
}
public int head() {
return queue[head];
}
}
protected int [] connected_nodes(int node) {
int [] ret = new int[SearchApplet.MAX];
int num = 0;
for (int n=0; n<numNodes; n++) {
boolean connected = false;
// See if there is a link between node 'node' and 'n':
for (int i=0; i<numLinks; i++) {
if (link_1[i] == node) {
if (link_2[i] == n) {
connected = true;
break;
}
}
if (link_2[i] == node) {
if (link_1[i] == n) {
connected = true;
break;
}
}
}
if (connected) {
ret[num++] = n;
}
}
if (num == 0) return null;
int [] ret2 = new int[num];
for (int i=0; i<num; i++) {
ret2[i] = ret[i];
}
return ret2;
}
private int [] path = new int[SearchApplet.MAX];
private int num_path = 0;
private int [] copy_path(int [] path, int num_to_copy) {
int [] ret = new int[SearchApplet.MAX];
for (int i=0; i<num_to_copy; i++) {
ret[i] = path[i];
}
return ret;
}
}