Data Structures, Algorithms, & Applications in Java
Chapter 21, Exercise 11
The structure of the code is quite similar to that of
Program 21.4. The code given below can be improved by using strategy 2
of the text to save better solutions rather than the startegy adopted in
Program 21.10 as well as in the code given below.
public class AdjacencyGraphWithIterativeMaxClique extends AdjacencyGraph
{
// constructors
public AdjacencyGraphWithIterativeMaxClique(int theVertices)
{super(theVertices);}
public AdjacencyGraphWithIterativeMaxClique()
{this(0);}
/** solve max-clique problem using backtracking
* return size of max clique
* param maxClique set maxClique[i] = 1 iff i is in max clique */
public int btMaxClique(int [] maxClique)
{
int [] currentClique = new int [n + 1];
int sizeOfCurrentClique = 0;
int [] maxCliqueSoFar = maxClique;
int sizeOfMaxCliqueSoFar = 0;
// search the tree
int currentLevel = 1; // also gives next vertex to decide on
while (true)
{
// move down and left as far as possible
while (currentLevel <= n)
{
// see if vertex currentLevel is connected to others
// in current clique
boolean connected = true;
for (int j = 1; j < currentLevel; j++)
if (currentClique[j] == 1 && !a[currentLevel][j])
{// vertex currentLevel not connected to vertex j
connected = false;
break;
}
if (connected)
{// move to a left child
// add vertex currentLevel to clique
currentClique[currentLevel] = 1;
sizeOfCurrentClique++;
currentLevel++;
}
else
break;
}
if (currentLevel > n)
{// at leaf, found a larger clique,
// update maxCliqueSoFar and sizeOfMaxCliqueSoFar
for (int j = 1; j <= n; j++)
maxCliqueSoFar[j] = currentClique[j];
sizeOfMaxCliqueSoFar = sizeOfCurrentClique;
currentLevel--;
// currentLevel is now last vertex for which a decision was made
}
else
// move to a right child
currentClique[currentLevel] = 0;
// backup if necessary
while (sizeOfCurrentClique + n - currentLevel <= sizeOfMaxCliqueSoFar)
{// this subtree does not have a better leaf, backup
while (currentLevel > 0 && currentClique[currentLevel] == 0)
// backup from a right child
currentLevel--;
if (currentLevel == 0) return sizeOfMaxCliqueSoFar;
// move to a right child, currentClique[currentLevel] was 1
currentClique[currentLevel] = 0;
sizeOfCurrentClique--;
}
currentLevel++; // next vertex
}
}
}