Week 9 - Greedy Algorithm 3
Week 9 - Greedy Algorithm 3
shortest-path algorithm.
It uses the distpar class and the vertex class,
class.
public void path() {
int starttree =0;
vertexlist[starttree].isintree = true;
ntree = 1;
for(int j=0; j<nverts; j++)
{
int tempdist = adjmat[starttree][j];
spath[j] = new distpar(starttree, tempdist);
}
while(ntree < nverts) {
int indexmin = getmin();
int mindist = spath[indexmin].distance;
if(mindist == infinity) {
System.out.println("There are unreachable vertices");
break;
}
Else {
currentvert = indexmin;
starttocurrent = spath[indexmin].distance;
}
vertexlist[currentvert].isintree =true;
ntree++;
adjust_spath();
}
displaypaths();
ntree =0;
for(int j=0; j<nverts; j++)
vertexlist[j].isintree = false;
}
The starting vertex is always at index 0 of the
vertexlist[ ] array.
Step 1:
The first task in path() is to put this vertex into
the tree.
As the algorithm proceeds, we will be moving
distance.
Put the corresponding vertex in the tree. This
in spath [ ].
If starttofringe is less, it replaces the entry in
spath [ ].
This is the heart of Dijkstra’s algorithm.
It keeps spath [ ] updated with the shortest
distances to all the vertices that are currently
known.
class distpar {
public int distance;
public int parentvert;
public distpar(int pv, int d) {
distance = d;
parentvert = pv;
}
}
class vertex2 {
public char label;
public boolean isintree;
public vertex2(char lab) {
label = lab;
isintree = false;
}
}
class graph2 {
private final int max_verts = 20;
private final int infinity = 10000;
private vertex2 vertexlist[];
private int adjmat[][];
private int nverts;
private int ntree;
private distpar spath[];
private int currentvert;
private int starttocurrent;
public graph2() {
vertexlist = new vertex2[max_verts];
adjmat = new int[max_verts][max_verts];
nverts = 0;
ntree = 0;
for(int j=0; j<max_verts; j++)
for(int k=0; k<max_verts; k++)
adjmat[j][k] = infinity;
spath = new distpar[max_verts];
}
public void addvertex(char lab) {
vertexlist[nverts++] = new vertex2(lab);
}
public void addedge(int start, int end, int weight) {
adjmat[start][end] = weight;
}
public void path() {
int starttree =0;
vertexlist[starttree].isintree = true;
ntree = 1;
for(int j=0; j<nverts; j++) {
int tempdist = adjmat[starttree][j];
spath[j] = new distpar(starttree, tempdist);
}
while(ntree < nverts) {
int indexmin = getmin();
int mindist = spath[indexmin].distance;
if(mindist == infinity) {
System.out.println("There are unreachable vertices");
break;
}
Else {
currentvert = indexmin;
starttocurrent = spath[indexmin].distance;
}
vertexlist[currentvert].isintree =true;
ntree++;
adjust_spath();
}
displaypaths();
ntree =0;
for(int j=0; j<nverts; j++)
vertexlist[j].isintree = false;
}
public int getmin() {
int mindist = infinity;
int indexmin = 0;
for(int j=1; j<nverts; j++) {
if(!vertexlist[j].isintree && spath[j].distance < mindist) {
mindist = spath[j].distance;
indexmin = j;
}}
return indexmin;
}
public void adjust_spath() {
int column = 1;
while(column < nverts) {
if(vertexlist[column].isintree) {
column++;
continue;
}
int currenttofringe = adjmat[currentvert][column];
int starttofringe = starttocurrent + currenttofringe;
int spathdist = spath[column].distance;
if(starttofringe < spathdist) {
spath[column].parentvert = currentvert;
spath[column].distance = starttofringe;
}
column++;
}
}
public void displaypaths() {
for(int j=0; j<nverts; j++) {
System.out.print(vertexlist[j].label + "=");
if(spath[j].distance == infinity)
System.out.print("inf");
else
System.out.print(spath[j].distance);
char parent = vertexlist[spath[j].parentvert].label;
System.out.print("(" + parent + " ) ");
}
System.out.println(" ");
}
}
class pathapp {
public static void main (String[] args) {
graph2 thegraph = new graph2();
thegraph.addvertex('A');
thegraph.addvertex('C');
thegraph.addvertex('B');
thegraph.addvertex('D');
thegraph.addvertex('E');
thegraph.addedge(0,1,50);
thegraph.addedge(0,3,80);
thegraph.addedge(1,2,60);
thegraph.addedge(1,3,90);
thegraph.addedge(2,4,40);
thegraph.addedge(3,2,20);
thegraph.addedge(3,4,70);
thegraph.addedge(4,1,50);
System.out.println("Shotest paths");
thegraph.path();
System.out.println(); } }
Bi-connected Graph
A graph with no articulation points is called bi-
connected or non-separable.
A vertex whose removal, along with its incident
edges, disconnects the remaining vertices is called
an articulated point or a cut-vertex.
If one node and its edges are removed from the
graph, all of the other nodes in the bi-connected
component can still reach any other.
The graph in the next figure shows a connected
graph that has three bi-connected components.
The first bi-connected component has the nodes
labeled A, B, C, and D.
The 2nd has the nodes labeled D, E, F, G, and H.
bi-connected component.
To accomplish this algorithm, we will keep a
count of how many nodes of the graph we have
visited.
Each node will be assigned an index number
indicating when is it visited.
In other words, the first node visited will be
numbered 1, the second will be numbered 2, and
so on. When we reach a dead end, we will look at
all of the adjacent nodes (except for the node we
just came from) and will use the smallest index
number as our back index.
If there is just one adjacent node (the one we just
came from), we will return the dead end node’s
index as our back index.
When we return to a node that is not the root of
the search tree, we will compare the back index
value that was returned.
If that value is greater than or equal to the current
node’s index value, the sub-tree just visited
(minus any previously found bi-connected
components) is a bi-connected component.
Each internal node of the depth-first search tree
will return the smallest value from among the
indices of adjacent nodes and any back indices
returned to it.
How would this process work in graph of the
figure? If we begin at node F, it would be assigned
an index of 1.
We move to node D (index 2), then nodes B (index
3), A (index 4), and C (index 5).
Node C is a dead end, and we have back edges to
nodes A, B, and D. The index on node D is
smallest, so a value of 2 would be returned to
node A as the back index. At node A, because the
value of 2 is less than node A’s index, it is not an
articulation point.
The value of 2 is the smallest so far, and it is also
returned to node B.
This continues until we get back to node D, where
we find that the back index returned is the same as
node D’s index, and so the nodes A, B, C, and D
make up a bi-connected component.
We return to the root of the search tree at node F
and then move off to node E (index 6), followed by
node G (index 7), and node H (index 8). We next
traverse down to node I (index 9), and because it
is a dead end with no adjacent nodes other than H,
we return its index as the back index.
When node H receives a value of 9 from node I,
which is greater than the index of node H, we find
another biconnected component with nodes H and
I.
Node H now considers the values of 1 (the back
edge to F), 9 (returned from node I), and 8 (node
H’s index), returning the smallest of these to node
G and then to node E.
This value is then returned by node E to the root
node, and because all nodes have been visited,
those that remain (nodes D, E, F, G, and H)
comprise the final biconnected component.
In Fig. 6.10 we see the result of this process, and
from this we can see that the articulation points in
the original graph are nodes D and H, which are
the only nodes that appear in two separate
components.
Java Implementation
import java.io.*;
import java.util.*;
import java.util.LinkedList;
class testBut{
private int V;
private LinkedList<Integer> adj[];
int time = 0;
static final int NIL = -1;
testBut(int v){
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i)
adj[i] = new LinkedList();
}
void addEdge(int v, int w){
adj[v].add(w);
adj[w].add(v);
}
boolean isBCUtil(int u, boolean visited[], int disc[],int low[],int parent[])
{
int children = 0;
visited[u] = true;
disc[u] = low[u] = ++time;
Iterator<Integer> i = adj[u].iterator();
while (i.hasNext()){
int v = i.next();
if (!visited[v]){
children++;
parent[v] = u;
if (isBCUtil(v, visited, disc, low, parent))
return true;
low[u]= Math.min(low[u], low[v]);
if (parent[u] == NIL && children > 1)
return true;
if (parent[u] != NIL && low[v] >= disc[u])
return true;
}
else if (v != parent[u])
low[u] = Math.min(low[u], disc[v]);
}
return false;
}
boolean isBC(){
boolean visited[] = new boolean[V];
int disc[] = new int[V];
int low[] = new int[V];
int parent[] = new int[V];
for (int i = 0; i < V; i++){
parent[i] = NIL;
visited[i] = false;
}
if (isBCUtil(0, visited, disc, low, parent) == true)
return false;
for (int i = 0; i < V; i++)
if (visited[i] == false)
return false;
return true;
}
public static void main(String args[]){
testBut g2 =new testBut(5);
g2.addEdge(0, 1);
g2.addEdge(0, 2);
g2.addEdge(2, 1);
g2.addEdge(0, 3);
g2.addEdge(3, 4);
g2.addEdge(2, 4);
if (g2.isBC())
System.out.println("Yes");
else
System.out.println("No");
}
}
End of Chapter 9
Any Question?