I'm implementing a DFS search to run in an adjacency matrix. With this i want to solve de euler path problem.
I already have DFS running with no problems, but now i want to modify it so it will perform backtrack whenever it tries to visit an edge that already has been visited.
Here's my current code:
public class Graph {
private int numVertex;
private int numEdges;
private boolean[][] adj;
public Graph(int numVertex, int numEdges) {
this.numVertex = numVertex;
this.numEdges = numEdges;
this.adj = new boolean[numVertex+1][numVertex+1];
}
public void addEdge(int start, int end){
adj[start][end] = true;
adj[end][start] = true;
}
List<Integer> visited = new ArrayList<Integer>();
public Integer DFS(Graph G, int startVertex){
int i=0;
pilha.push(startVertex);
for(i=0; i<G.numVertex; i++){
if(G.adj[i][startVertex] != false){
System.out.println("i: " + i);
G.adj[i][startVertex] = false;
G.adj[startVertex][i] = false;
DFS(G, i);
pilha.push(i);
G.adj[i][startVertex] = true;
G.adj[startVertex][i] = true;
}
/* else{
pilha.pop();
}*/
if(!pilha.isEmpty()){
int c = pilha.pop();
visited.add(c);
System.out.println("visited: " + visited);
}
}
return -1;
}
Stack<Integer> pilha = new Stack();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numVertices = input.nextInt();
int numLinks = input.nextInt();
int startNode = input.nextInt();
Graph g = new Graph(numVertices, numLinks);
for(int i = 0; i<numLinks; i++){
g.addEdge(input.nextInt(),input.nextInt());
}
g.DFS(g, startNode);
}
}
The problem is, whenever i try to run the pop that is commented, i get an EmptyStackException. Any ideas on how to modify my code so it will backtrack when it tries to visit an edge that already has been visited.
Thx in advance.
That else of yours is getting executed if startvertex is not adjacent to some vertex i.
It really should get that else only if startvertex is not adjacent to any vertex i.
I'd do something like:
bool hasAdjacent = False;
for(i=0; i<G.numVertex; i++){
if(G.adj[i][startVertex] != false){
hasAdjacent = True;
...
}
}
if (!hasAdjacent) {
int c = pilha.pop();
visited.add(c);
}
I'm not giving you a complete solution, but I think this solves your main logic problem.
Related
Can you please help me to put an error tarpping in my code. I have been doing it since yesterday but I think my braincell is already exhausted. Please send help po. And also can we print a graph in blueJ? how to print the graph? kinds of error trapping (i, i) = (0,0) same source destination, not allowed (i, j) = (i, j) existing edge, not allowed (i, j) = (j, i) existing edge, not allowed n (level of vertex) > n = not allowed
*
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class AdjMatrixGraph{
List<List<Integer>> graph;
Scanner input = new Scanner(System.in);
ArrayList<Connection> Links = new ArrayList<Connection>();
boolean visited[];
int nodes;
int vertices;
int matrix[][];
class Node {//stores node information
String name;
boolean visited;
ArrayList<Node> neighbors = new ArrayList<Node>();
Node(String name) {
this.name = name;
visited = false;
}
}
class Connection {//stores edges information
double fare;
Node source, destination;
Connection(Node source, Node destination) {
this.source = source;
this.destination = destination;
}
}
public static void main(String[] args){
Scanner s = new Scanner(System.in);
System.out.println("Enter the number of vertices");
int V = s.nextInt();
AdjMatrixGraph amg = new AdjMatrixGraph(V);
System.out.println("Enter the number of edges");
int E = s.nextInt();
System.out.print("\n");
for(int i=0;i<E;i++){
System.out.println("Enter the endpoints");
int mark = s.nextInt();
int mac = s.nextInt();
if (mark == mac) { //checks if newly input edge is a loop
System.out.println("\nERROR TRAPPED!!\nNo Loops Allowed Here!\nAdd New Edge!");
i--;
continue;
}
amg.addEdge(mark,mac);
amg.addEdge1(mark,mac);
}
amg.printGraph();
System.out.print("\nSize of the graph: " + E);
System.out.print("\nOrder of the graph: " + V);
System.out.println(amg.ifGraphConnected());
}
AdjMatrixGraph(int vertices){
graph = new ArrayList<>();
visited = new boolean[vertices];
this.vertices=vertices;
matrix=new int[vertices][vertices];
for (int i = 0; i < vertices; i++){
graph.add(i, new ArrayList<>());
}
}
public void addEdge(int source,int destination){
matrix[source][destination]= 1;
matrix[destination][source]= 1;
}
public void addEdge1(int a, int b) {
graph.get(a).add(b);
graph.get(b).add(a);
}
public boolean ifGraphConnected() {
int startIndex = 0;
dfs(startIndex);
for(int i = 0; i < visited.length; i++) {
if(!visited[i]) {
System.out.println("\n");
System.out.println("The Graph is not connected!: ");
System.out.print("\nCreate another graph? \n1=Yes or 2=No\n");
String menu = input.nextLine();
if(menu.equals("1")){//goes back to the first menu and resets the list
input.close();
main(null);
}else if(menu.equals("2")){//terminates the program
System.exit(0);
}else{
System.out.println("\nERROR!");
}
return false;
}
}
System.out.println("\n");
System.out.println("The Graph is connected!");
System.out.print("\nCreate another graph? \n1=Yes or 2=No\n");
String menu = input.nextLine();
if(menu.equals("1")){//goes back to the first menu and resets the list
input.close();
main(null);
}else if(menu.equals("2")){//terminates the program
System.exit(0);
}else{
System.out.println("\nERROR!");
}
return true;
}//print true if it's connected
public void dfs(int start){ //the DFS traversal method for determining whether it is connected or not.
Stack<Integer> stack = new Stack<>(); //implement a stack that stores integers and traverse the graph
stack.push(start);
visited[start] = true; //places the vertex's start or address and sets it to true
while(!stack.isEmpty()) { //While the stack is not empty, the arguments in this block will be executed.
Integer vertices = stack.pop(); //the element is inserted into the stack
List<Integer> neighboursList = graph.get(vertices); //This will create a linked list of the graph's vertices
for(Integer neighbour: neighboursList) { //This will scan over all of the vertices that are related to the initial index.
if(!visited[neighbour]) {
stack.push(neighbour); //All the vertices that is related to vertex will be pushed.
visited[neighbour] = true; //Makes the vertex that is related to it true. It will then check to see if the stack is still full. If the loop is not empty, it will pop the visited vertex and proceed.
}
}
}
}
void printGraph(){ //printing Graph
System.out.print("\n");
System.out.println("The Adjacency Matrix is:");
for(int i=0;i<vertices;i++){ //using for loop method
for(int j = 0;j<vertices;j++){
System.out.print(matrix[i][j]+" ");
}
System.out.println();
}
}
}```
I'm trying to find the majority or leader, in a stack that isn't sorted, and i'm having trouble with my tos (top of stack variable). Below is my code with main included. The majority of an array or stack is any element which appears in the array more than half the time (arrSize/2).
public class findLeader {
static class ArrayStack{
private int[] stackArr;
private int tos;//top of stack
public ArrayStack(){
stackArr = new int[10];
tos = -1;
}
public ArrayStack(int size){
stackArr = new int[size];
tos = -1;
}
public ArrayStack(int[] arr, int tos){
stackArr = arr;
this.tos = tos;
}
public boolean isEmpty(){
return(tos == -1);
}
public int peek(){
if(isEmpty()){
return -999;
}
return stackArr[tos];
}
public void push(int x){
if(tos == stackArr.length - 1){
return;
}
stackArr[++tos] = x;
}
public int pop(){
if(isEmpty()){
return -999;
}
int popValue = stackArr[tos];
stackArr[tos] = 0;
--tos;
return popValue;
}
public void print(){
if(isEmpty()){
return;
}
for(int i = 0; i <= tos; ++i){
System.out.print(stackArr[i] + " ");
}
System.out.println();
}
}
public static int leader(ArrayStack myStack){
int initSize = myStack.tos + 1; //gets initial size of stack.
int leader; //initialize leader or majority.
while(!myStack.isEmpty()){
leader = myStack.peek();//set first leader variable to the element at the tos.
System.out.println("leader " + leader); //just for debugging
System.out.println("tos " + myStack.tos); //debugging
//System.out.println(isLeader(myStack, initSize, leader)); //debugging
if(isLeader(myStack, initSize, leader)){
return 1;
}
else{
myStack.pop();
}
System.out.println("after function tos " + myStack.tos); //debugging
}
return -1;
}
public static boolean isLeader(ArrayStack myStack, int initSize, int leader){
ArrayStack as = myStack;
int count = 0;
while(!as.isEmpty()){
if(as.peek() == leader){
as.pop();
++count;
}
else{
as.pop();
}
}
//System.out.println(count);
if(count > initSize / 2)
return true;
else{
return false;
}
}
public static void main(String[] args) {
int[] arr = {2, 5, 6, 2, 8, 2, 8, 2, 2};
ArrayStack stack = new ArrayStack();
stack.push(5);
stack.push(2);
stack.push(6);
stack.push(2);
stack.push(8);
stack.push(2);
stack.push(2);
stack.push(2);
stack.push(5);
System.out.println(leader(stack));
}
Where the problem arises is in the leader, and isLeader methods, after the initial call of isLeader, tos gets returned as tos = -1 as is demonstrated from my output below.
Output:
leader 5
tos 8
after function tos -1
-1
My intent is after every call to isLeader() if false is returned, i want to pop the tos variable from the top and call isLeader() once more with the new smaller stack.
Any help would really be appreciated, and I hope everyone is well!
Thank you
I'd personally add a method public Integer leader() to your ArrayStack that returns the stack's leader or null if the stack has no leader:
public Integer leader() {
final Map<Integer, Integer> counts = new HashMap<>();
final int neededLeaderCount = ((tos + 1) / 2) + 1;
for (int i = 0; i <= tos; ++i) {
int currentElementCount = counts.getOrDefault(stackArr[i], 0) + 1;
if (currentElementCount >= neededLeaderCount) {
return stackArr[i];
}
counts.put(stackArr[i], currentElementCount);
}
return null;
}
Your isLeader function could then be rewritten to:
public static boolean isLeader(ArrayStack myStack, int leader) {
// use Objects.equals as myStack.leader() may be null
return Objects.equals(myStack.leader(), leader);
}
This approach is much cleaner as it does not modify or require any internals of your ArrayStack outside of the class itself.
I was able to get it to work by also tracking a currSize of the stack to pass to the isLeader function. I feel like i am complicating things, if anyone has a simpler solution and would like to share it, I would be open to it. Below is my code if anyone is interested.
public static int leader(ArrayStack myStack){
int currSize = myStack.tos;
int initSize = myStack.tos + 1; //gets initial size of stack.
int leader; //initialize leader or majority.
while(!myStack.isEmpty()){
leader = myStack.peek();//set first leader variable to the element at the tos.
System.out.println("leader " + leader); //just for debugging
System.out.println("tos " + myStack.tos); //debugging
//System.out.println(isLeader(myStack, initSize, leader)); //debugging
if(isLeader(myStack, initSize, leader, currSize)){
return 1;
}
else{
--currSize;
myStack.pop();
}
System.out.println("after function tos " + myStack.tos); //debugging
}
return -1;
}
public static boolean isLeader(ArrayStack myStack, int initSize, int leader, int currSize){
ArrayStack as = myStack;
int count = 0;
while(as.tos > -1){
if(as.peek() == leader){
--as.tos; //Just move tos pointer down stack rather than popping
//to maintain original stack.
++count;
}
else{
--as.tos;
}
}
if(count > initSize / 2)
return true;
else{
as.tos = currSize;//reset the tos pointer back to the currSize of
//stack.
return false;
}
}
im trying to create a B+ tree from a previous B tree implementation I create, but Im really lost here... the only difference from B to B+ im trying to implement, is storing the keys on the leaves instead of removing them.
Example:
Final B Tree
3 6 false
1 2 true
4 5 true
7 8 9 10 true
Final B+ Tree
3 6 false
1 2 true
3 4 5 true
6 7 8 9 10 true
This is what I have for a B Tree (I really didnt want to post the whole code, but explaining all of it will be harder and confusing). I would appreciate at least some ideas...
MAIN
public class BTreeTest{
public static void main(String[] args) {
Random generator = new Random();
BTree T = new BTree(3);
final int INSERTS = 50; // how many elements are inserted
final int VALUE_LIMIT = 1000; // generated integers up to VALUE_LIMIT
int[] values = new int[INSERTS]; // array can be used to print insert order
// or to test other methods
for (int i=0;i<INSERTS;i++){
int val = generator.nextInt(VALUE_LIMIT);
values[i] = val;
T.insert(val);
}
T.printNodes();
}}
B tree NODE
public class BTreeNode{
public int[] key;
public BTreeNode[] c;
boolean isLeaf;
public int n;
private int T; //Each node has at least T-1 and at most 2T-1 keys
public BTreeNode(int t){
T = t;
isLeaf = true;
key = new int[2*T-1];
c = new BTreeNode[2*T];
n=0;
}
public boolean isFull(){
return n==(2*T-1);
}
public void insert(int newKey){
// Insert new key to current node
// We make sure that the current node is not full by checking and
// splitting if necessary before descending to node
//System.out.println("inserting " + newKey); // Debugging code
int i=n-1;
if (isLeaf){
while ((i>=0)&& (newKey<key[i])) {
key[i+1] = key[i];
i--;
}
n++;
key[i+1]=newKey;
}
else{
while ((i>=0)&& (newKey<key[i])) {
i--;
}
int insertChild = i+1; // Subtree where new key must be inserted
if (c[insertChild].isFull()){
// The root of the subtree where new key will be inserted has to be split
// We promote the mediand of that root to the current node and
// update keys and references accordingly
//System.out.println("This is the full node we're going to break ");
// Debugging code
//c[insertChild].printNodes();
//System.out.println("going to promote " + c[insertChild].key[T-1]);
n++;
c[n]=c[n-1];
for(int j = n-1;j>insertChild;j--){
c[j] =c[j-1];
key[j] = key[j-1];
}
key[insertChild]= c[insertChild].key[T-1];
c[insertChild].n = T-1;
BTreeNode newNode = new BTreeNode(T);
for(int k=0;k<T-1;k++){
newNode.c[k] = c[insertChild].c[k+T];
newNode.key[k] = c[insertChild].key[k+T];
}
newNode.c[T-1] = c[insertChild].c[2*T-1];
newNode.n=T-1;
newNode.isLeaf = c[insertChild].isLeaf;
c[insertChild+1]=newNode;
//System.out.println("This is the left side ");
//c[insertChild].printNodes();
//System.out.println("This is the right side ");
//c[insertChild+1].printNodes();
//c[insertChild+1].printNodes();
if (newKey <key[insertChild]){
c[insertChild].insert(newKey); }
else{
c[insertChild+1].insert(newKey); }
}
else
c[insertChild].insert(newKey);
}
}
public void print(){
//Prints all keys in the tree in ascending order
if (isLeaf){
for(int i =0; i<n;i++)
System.out.print(key[i]+" ");
System.out.println();
}
else{
for(int i =0; i<n;i++){
c[i].print();
System.out.print(key[i]+" ");
}
c[n].print();
}
}
public void printNodes(){
//Prints all keys in the tree, node by node, using preorder
//It also prints the indicator of whether a node is a leaf
//Used mostly for debugging purposes
printNode();
if (!isLeaf){
for(int i =0; i<=n;i++){
c[i].printNodes();
}
}
}
public void printNode(){
//Prints all keys in node
for(int i =0; i<n;i++)
System.out.print(key[i]+" ");
System.out.println(isLeaf);
}
}
B Tree
public class BTree{
private BTreeNode root;
private int T; //2T is the maximum number of childen a node can have
private int height;
public BTree(int t){
root = new BTreeNode(t);
T = t;
height = 0;
}
public void printHeight(){
System.out.println("Tree height is "+height);
}
public void insert(int newKey){
if (root.isFull()){//Split root;
split();
height++;
}
root.insert(newKey);
}
public void print(){
// Wrapper for node print method
root.print();
}
public void printNodes(){
// Wrapper for node print method
root.printNodes();
}
public void split(){
// Splits the root into three nodes.
// The median element becomes the only element in the root
// The left subtree contains the elements that are less than the median
// The right subtree contains the elements that are larger than the median
// The height of the tree is increased by one
//System.out.println("Before splitting root");
//root.printNodes(); // Code used for debugging
BTreeNode leftChild = new BTreeNode(T);
BTreeNode rightChild = new BTreeNode(T);
leftChild.isLeaf = root.isLeaf;
rightChild.isLeaf = root.isLeaf;
leftChild.n = T-1;
rightChild.n = T-1;
int median = T-1;
for (int i = 0;i<T-1;i++){
leftChild.c[i] = root.c[i];
leftChild.key[i] = root.key[i];
}
leftChild.c[median]= root.c[median];
for (int i = median+1;i<root.n;i++){
rightChild.c[i-median-1] = root.c[i];
rightChild.key[i-median-1] = root.key[i];
}
rightChild.c[median]=root.c[root.n];
root.key[0]=root.key[median];
root.n = 1;
root.c[0]=leftChild;
root.c[1]=rightChild;
root.isLeaf = false;
//System.out.println("After splitting root");
//root.printNodes();
}}
I'm implementing an algorithm to find all the euler paths in a graph. I'm basing myself, to create the dfs, in the code found here: Find all possible Euler cycles
Here is my current code:
public class Graph {
private int numVertex;
private int numEdges;
private boolean[][] adj;
public Graph(int numVertex, int numEdges) {
this.numVertex = numVertex;
this.numEdges = numEdges;
this.adj = new boolean[numVertex+1][numVertex+1];
}
public void addEdge(int start, int end){
adj[start][end] = true;
adj[end][start] = true;
}
public Integer DFS(Graph G, int startVertex){
int i=0;
pilha.push(startVertex);
for(i=0; i<G.numVertex; i++){
if(G.adj[i][startVertex] != false){
System.out.println("i: " + i);
G.adj[i][startVertex] = false;
G.adj[startVertex][i] = false;
DFS(G, i);
G.adj[i][startVertex] = true;
G.adj[startVertex][i] = true;
}
}
return -1;
}
Stack<Integer> pilha = new Stack();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numVertices = input.nextInt();
int numLinks = input.nextInt();
int startNode = input.nextInt();
Graph g = new Graph(numVertices, numLinks);
for(int i = 0; i<numLinks; i++){
g.addEdge(input.nextInt(),input.nextInt());
}
}
}
Unfortunately i don't get the right results and i can't seem to figure out why. I've tried a lot of thing as storing the results from the dfs in a list and print them, but still i got no paths.
any idea on how can i modify my code so i start getting the euler paths?
What do you expect the result from your program to be? You are pushing the nodes to a temporary stack(pilha). You need to keep that stack because it will in fact determine the order in which you should visit the nodes. Also the DFS method is void but somehow you add the result from its invocation in the list res. Does this code even run successfully?
I'm back with another similar question. I am currently working on a Java program that will check if a graph is 2-colorable, i.e. if it contains no odd cycles (cycles of odd number length). The entire algorithm is supposed to run in O(V+E) time (V being all vertices and E being all edges in the graph). My current algorithm does a Depth First Search, recording all vertices in the path it takes, then looks for a back edge, and then records between which vertices the edge is between. Next it traces a path from one end of the back edge until it hits the other vertex on the other end of the edge, thus retracing the cycle that the back edge completes.
I was under the impression that this kind of traversing could be done in O(V+E) time for all cycles that exist in my graph, but I must be missing something, because my algorithm is running for a ridiculously long time for very large graphs (10k nodes, no idea how many edges).
Is my algorithm completely wrong? And if so, can anyone point me in the right direction for a better way to record these cycles or possibly tell if they have odd numbers of vertices? Thanks for any and all help you guys can give. Code is below if you need it.
Addition: Sorry I forgot, if the graph is not 2-colorable, I need to provide an odd cycle that proves that it is not.
package algorithms311;
import java.util.*;
import java.io.*;
public class CS311 {
public static LinkedList[] DFSIter(Vertex[] v) {
LinkedList[] VOandBE = new LinkedList[2];
VOandBE[0] = new LinkedList();
VOandBE[1] = new LinkedList();
Stack stack = new Stack();
stack.push(v[0]);
v[0].setColor("gray");
while(!stack.empty()) {
Vertex u = (Vertex) stack.peek();
LinkedList adjList = u.getAdjList();
VOandBE[0].add(u.getId());
boolean allVisited = true;
for(int i = 0; i < adjList.size(); i++) {
if(v[(Integer)adjList.get(i)].getColor().equals("white")) {
allVisited = false;
break;
}
else if(v[(Integer)adjList.get(i)].getColor().equals("gray") && u.getPrev() != (Integer)adjList.get(i)) {
int[] edge = new int[2]; //pair of vertices
edge[0] = u.getId(); //from u
edge[1] = (Integer)adjList.get(i); //to v
VOandBE[1].add(edge);
}
}
if(allVisited) {
u.setColor("black");
stack.pop();
}
else {
for(int i = 0; i < adjList.size(); i++) {
if(v[(Integer)adjList.get(i)].getColor().equals("white")) {
stack.push(v[(Integer)adjList.get(i)]);
v[(Integer)adjList.get(i)].setColor("gray");
v[(Integer)adjList.get(i)].setPrev(u.getId());
break;
}
}
}
}
return VOandBE;
}
public static void checkForTwoColor(String g) { //input is a graph formatted as assigned
String graph = g;
try {
// --Read First Line of Input File
// --Find Number of Vertices
FileReader file1 = new FileReader("W:\\Documents\\NetBeansProjects\\algorithms311\\src\\algorithms311\\" + graph);
BufferedReader bReaderNumEdges = new BufferedReader(file1);
String numVertS = bReaderNumEdges.readLine();
int numVert = Integer.parseInt(numVertS);
System.out.println(numVert + " vertices");
// --Make Vertices
Vertex vertex[] = new Vertex[numVert];
for(int k = 0; k <= numVert - 1; k++) {
vertex[k] = new Vertex(k);
}
// --Adj Lists
FileReader file2 = new FileReader("W:\\Documents\\NetBeansProjects\\algorithms311\\src\\algorithms311\\" + graph);
BufferedReader bReaderEdges = new BufferedReader(file2);
bReaderEdges.readLine(); //skip first line, that's how many vertices there are
String edge;
while((edge = bReaderEdges.readLine()) != null) {
StringTokenizer ST = new StringTokenizer(edge);
int vArr[] = new int[2];
for(int j = 0; ST.hasMoreTokens(); j++) {
vArr[j] = Integer.parseInt(ST.nextToken());
}
vertex[vArr[0]-1].addAdj(vArr[1]-1);
vertex[vArr[1]-1].addAdj(vArr[0]-1);
}
LinkedList[] l = new LinkedList[2];
l = DFSIter(vertex);//DFS(vertex);
System.out.println(l[0]);
for(int i = 0; i < l[1].size(); i++) {
int[] j = (int[])l[1].get(i);
System.out.print(" [" + j[0] + ", " + j[1] + "] ");
}
LinkedList oddCycle = new LinkedList();
boolean is2Colorable = true;
//System.out.println("iterate through list of back edges");
for(int i = 0; i < l[1].size(); i++) { //iterate through the list of back edges
//System.out.println(i);
int[] q = (int[])(l[1].get(i)); // q = pair of vertices that make up a back edge
int u = q[0]; // edge (u,v)
int v = q[1];
LinkedList cycle = new LinkedList();
if(l[0].indexOf(u) < l[0].indexOf(v)) { //check if u is before v
for(int z = l[0].indexOf(u); z <= l[0].indexOf(v); z++) { //if it is, look for u first; from u to v
cycle.add(l[0].get(z));
}
}
else if(l[0].indexOf(v) < l[0].indexOf(u)) {
for(int z = l[0].indexOf(v); z <= l[0].indexOf(u); z++) { //if it is, look for u first; from u to v
cycle.add(l[0].get(z));
}
}
if((cycle.size() & 1) != 0) { //if it has an odd cycle, print out the cyclic nodes or write them to a file
is2Colorable = false;
oddCycle = cycle;
break;
}
}
if(!is2Colorable) {
System.out.println("Graph is not 2-colorable, odd cycle exists");
if(oddCycle.size() <= 50) {
System.out.println(oddCycle);
}
else {
try {
BufferedWriter outFile = new BufferedWriter(new FileWriter("W:\\Documents\\NetBeansProjects\\algorithms311\\src\\algorithms311\\" + graph + "OddCycle.txt"));
String cyc = oddCycle.toString();
outFile.write(cyc);
outFile.close();
}
catch (IOException e) {
System.out.println("Could not write file");
}
}
}
}
catch (IOException e) {
System.out.println("Could not open file");
}
System.out.println("Done!");
}
public static void main(String[] args) {
//checkForTwoColor("smallgraph1");
//checkForTwoColor("smallgraph2");
//checkForTwoColor("smallgraph3");
//checkForTwoColor("smallgraph4");
checkForTwoColor("smallgraph5");
//checkForTwoColor("largegraph1");
}
}
Vertex class
package algorithms311;
import java.util.*;
public class Vertex implements Comparable {
public int id;
public LinkedList adjVert = new LinkedList();
public String color = "white";
public int dTime;
public int fTime;
public int prev;
public boolean visited = false;
public Vertex(int idnum) {
id = idnum;
}
public int getId() {
return id;
}
public int compareTo(Object obj) {
Vertex vert = (Vertex) obj;
return id-vert.getId();
}
#Override public String toString(){
return "Vertex # " + id;
}
public void setColor(String newColor) {
color = newColor;
}
public String getColor() {
return color;
}
public void setDTime(int d) {
dTime = d;
}
public void setFTime(int f) {
fTime = f;
}
public int getDTime() {
return dTime;
}
public int getFTime() {
return fTime;
}
public void setPrev(int v) {
prev = v;
}
public int getPrev() {
return prev;
}
public LinkedList getAdjList() {
return adjVert;
}
public void addAdj(int a) { //adds a vertex id to this vertex's adj list
adjVert.add(a);
}
public void visited() {
visited = true;
}
public boolean wasVisited() {
return visited;
}
}
I was under the impression that this kind of traversing could be done in O(V+E) time for all cycles that exist in my graph
There may be much more cycles than O(V+E) in a graph. If you iterate all of them, you will run long.
Back to your original idea, you could just try to implement a straightforward algorithm to color graph in two colors (mark an arbitrary node as black, all neighbors in white, all their neighbors in black, etc; that would be a breadth-first search). That is indeed done in O(V+E) time. If you succeed, then graph is 2-colorable. If you fail, it's not.
Edit: If you need a cycle that proves graph is not 2-colorable, just record for each node the vertex you traversed into it from. When you happen to traverse from black vertex A to black vertex B (thus needing to color black B into white and proving your graph is not 2-colorable), you get the cycle by looking back to parents:
X -> Y -> Z -> U -> V -> P -> Q -> A
\-> D -> E -> B
Then, A-B-E-D-V-P-Q (the paths up to their common ancestor) is the cycle you needed.
Note that in this version you don't have to check all cycles, you just output a first cycle, where back-edge in the tree has both vertexes colored in the same color.
you are describing a bipartite graph. a bipartite graph is 2 colorable and it contains no odd length cycles. You can use BFS to prove that a graph is bipartite or not. Hope this helps.