/**
* Copyright (C) 2013 Kametic <epo.jemba@kametic.com>
*
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3, 29 June 2007;
* or any later version
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nuunframework.kernel.commons.graph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Graph {
Logger logger = LoggerFactory.getLogger(Graph.class);
private final int MAX_VERTS;
private Vertex vertexList[]; // list of vertices
private int matrix[][]; // adjacency matrix
private int numVerts; // current number of vertices
private char sortedArray[];
public Graph(int maxvert) {
MAX_VERTS =maxvert;
vertexList = new Vertex[MAX_VERTS];
matrix = new int[MAX_VERTS][MAX_VERTS];
numVerts = 0;
for (int i = 0; i < MAX_VERTS; i++)
for (int k = 0; k < MAX_VERTS; k++)
matrix[i][k] = 0;
sortedArray = new char[MAX_VERTS]; // sorted vert labels
}
public int addVertex(char lab) {
vertexList[numVerts] = new Vertex(lab);
return numVerts++;
}
/**
*
* end depends on start
*
* @param start dependee
* @param end dependent
*/
public void addEdge(int start, int end) {
matrix[start][end] = 1;
}
public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}
public char[] topologicalSort() // Topological sort
{
int orig_nVerts = numVerts;
while (numVerts > 0) // while vertices remain,
{
// get a vertex with no successors, or -1
int currentVertex = noSuccessors();
if (currentVertex == -1) // must be a cycle
{
System.out.println("ERROR: Graph has cycles");
return null;
}
// insert vertex label in sorted array (start at end)
sortedArray[numVerts - 1] = vertexList[currentVertex].label;
deleteVertex(currentVertex); // delete vertex
}
// vertices all gone; display sortedArray
// logger.debug("Topologically sorted order: ");
// for (int j = 0; j < orig_nVerts; j++)
// logger.debug("" + sortedArray[j]);
// System.out.println("");
return sortedArray;
}
public int noSuccessors() // returns vert with no successors (or -1 if no
// such verts)
{
boolean isEdge; // edge from row to column in adjMat
for (int row = 0; row < numVerts; row++) {
isEdge = false; // check edges
for (int col = 0; col < numVerts; col++) {
if (matrix[row][col] > 0) // if edge to another,
{
isEdge = true;
break; // this vertex has a successor try another
}
}
if (!isEdge) // if no edges, has no successors
return row;
}
return -1; // no
}
public void deleteVertex(int delVert) {
if (delVert != numVerts - 1) // if not last vertex, delete from
// vertexList
{
for (int j = delVert; j < numVerts - 1; j++)
vertexList[j] = vertexList[j + 1];
for (int row = delVert; row < numVerts - 1; row++)
moveRowUp(row, numVerts);
for (int col = delVert; col < numVerts - 1; col++)
moveColLeft(col, numVerts - 1);
}
numVerts--; // one less vertex
}
private void moveRowUp(int row, int length) {
for (int col = 0; col < length; col++)
matrix[row][col] = matrix[row + 1][col];
}
private void moveColLeft(int col, int length) {
for (int row = 0; row < length; row++)
matrix[row][col] = matrix[row][col + 1];
}
public static void main(String[] args) {
Graph g = new Graph(20);
g.addVertex('A'); // 0
g.addVertex('B'); // 1
g.addVertex('C'); // 2
g.addVertex('D'); // 3
g.addVertex('E'); // 4
g.addVertex('F'); // 5
g.addVertex('G'); // 6
g.addVertex('H'); // 7
g.addEdge(0, 3); // AD - D depends de A
g.addEdge(0, 4); // AE - E depends de A
g.addEdge(1, 4); // BE - E depends de B
g.addEdge(2, 5); // CF - F depends de C
g.addEdge(3, 6); // DG - G depends de D
g.addEdge(4, 6); // EG - G depends de E
g.addEdge(5, 7); // FH - H depends de F
g.addEdge(6, 7); // GH - H depends de G
g.topologicalSort(); // do the sort
}
}