
///////////////////////////////////////////////////////////////////////////////////////
//  EXAMPLE of how to write a method for Part 2 of the Final Exam.
//
//  For CS 422 Fall 2002, Northern Michigan University  (instructor:  J. Horn)
///////////////////////////////////////////////////////////////////////////////////////



//  This took me about half an hour to an hour to do.  It would be worth about 30 or
//  35 points for the code, plus more for a run-time analysis, which I did not do.
//  It compiles, but I did not actually test it!
//
//  Note how it uses the method "cliqueQ" to check to see if a particular set of vertices
//  is a clique or not.  This is good modular programming, but cliqueQ is itself a method
//  to be written for points on the final.  So how would I grade the two, if they are
//  so intertwined?  Well, I want code that works, so for the full points on maximize_clique
//  you would have to have a working cliqueQ.  However, to reward modular programming and
//  the re-use of code, I would not take off much (from your credit on maximize_clique) if
//  your code for cliqueQ did not work or even if it were non-existent!  This is an
//  important point to remember, as many of the methods in the code for Part 2 could be
//  written using calls to other methods in Part 2.  In particular, I should point out
//  that one of the other "big" methods, namely "max_clique", could be written using
//  this code below, maximize_clique, by using a greedy, but still exhaustive approach that
//  "grows" the maximum clique from a smaller clique.  But remember that you must find
//  THE MAXIMUM clique for that problem.  So you would have to use this code below in
//  the right way.  If you do, full credit, but there are other approaches to max_clique too!
//


		//  Given as input a list of vertices, input_clique, supposedly representing
		//  a clique within graph G, return the maximal clique of G that entirely
		//  contains input_clique.  Do this by first checking to see if input_clique is
		//  indeed a clique itself, then, if it is, try growing it by adding one vertex
		//  at a time while maintaining clique property.  Return the final vertex list.
		public int [] maximize_clique(int [] input_clique)
		 	{
				int size_so_far = input_clique.length;
				int [] maximal_clique;

				// if input_clique not a clique, then return an empty array.
				if( ! cliqueQ(input_clique, size_so_far ) ) return maximal_clique;
				   else
				     {
					  //  First create a new temporary array, and copy input_clique's
					  //   vertices into it.
					  maximal_clique = new int[num_vertices];
					  for(int i=0; i < size_so_far; i++)
					      maximal_clique[i] = input_clique[i];

					  //  Next, for each vertex i in maximal_clique, go down its row in
					  //  the adjacency matrix and ...
				      for(int i=0; i < size_so_far; i++)
				        //  for each vertex j ...
				      	for(int j=0; j < num_vertices; j++)
				      		{
							  //  if j is adjacent to i AND j is not already in the maximal
							  //  clique array, then ...
							  if(edges[i][j] ==1 && ! element_of(j,maximal_clique))
							    {
									//  add it to the array and then ..
									maximal_clique[size_so_far] = j;
									//  see if the enlarged list of vertices is still a clique
				      	         	if(cliqueQ(maximal_clique, size_so_far+1))
				      	         	    // if it is still a clique, then add j permanently.
				      	      			size_so_far++;
							    }
						     }
					  //  Create a list of vertices (array of ints) to return the maximal clique
					  int [] answer = new int[size_so_far];
					  //  Have to do this because we can't simply return maximal_clique, our
					  //  "working" array, because want an array of exactly the right length
					  //  to return.  That is, answer.length == size of maximal clique ==
					  //  number of vertices in maximal clique.  Note that if we had used
					  //  the built-in Java class "Vector" we could have avoided this cumbersome
					  //  code, since Vector is a dynamically sized array.  Of course, we would
					  //  then have had to do a lot of type casting, as Vector only holds items
					  //  of type "Object".
					  for(int i=0; i<size_so_far; i++)
					  	answer[i] = maximal_clique[i];

					  return answer;
				     }
		    }
		private boolean element_of(int x, int [] array)
				{
					boolean found = false;
					int i=0;
					while(!found && i<array.length)
					     found = (x == array[i++]);
					return found;
			     }



