Using Depth-First Search in JAVA program instead of Breadth-First Search - java

I have a JAVA program where I am creating graphs and I have a Breadth-First Search but I would like to change it to Depth First Search. What changes should I make in a code? Thanks for help in advance.
public class ConnectedComponents
{
static final int MAXV = 100;
static boolean processed[] = new boolean[MAXV];
static boolean discovered[] = new boolean[MAXV];
static int parent[] = new int[MAXV];
static void bfs(CCGraph g, int start)
{
Queue<Integer> q = new LinkedList<Integer>();
int i, v;
q.offer(start);
discovered[start] = true;
while (!q.isEmpty())
{
v = q.remove();
process_vertex(v);
processed[v] = true;
for (i = g.degree[v] - 1; i >= 0; i--)
{
if (!discovered[g.edges[v][i]])
{
q.offer(g.edges[v][i]);
discovered[g.edges[v][i]] = true;
parent[g.edges[v][i]] = v;
}
}
}
}

I think you should understand the difference between depth first search and breadth first search. The code for depth first search goes as follows:
public class ConnectedComponents
{
static final int MAXV = 100;
static boolean processed[] = new boolean[MAXV];
static boolean discovered[] = new boolean[MAXV];
static int parent[] = new int[MAXV];
static void dfs(CCGraph g, int vertex)
{
discovered[vertex] = true;
for (i = g.degree[vertex] - 1; i >= 0; i--)
{
if (!discovered[g.edges[vertex][i]])
{
parent[g.edges[v][i]]=vertex;
dfs(g.edges[v][i]]);
}
}
}
}

The basic difference is the order by which vertexes are tested. While BFS uses queue (FIFO: First In First Out), DFS use stack (LIFO: Last In First Out).
You could implement stack using LinkedList:
LinkedList<Integer> stack = new LinkedList<Integer>();
stack.pop(); //returns the top of the stack
For more information please post mcve including test data.

Full code of the program. The goal is to change bfs to dfs.
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class CCGraph
{
static final int MAXV = 100;
static final int MAXDEGREE = 50;
public int edges[][] = new int[MAXV + 1][MAXDEGREE];
public int degree[] = new int[MAXV + 1];
public int nvertices;
public int nedges;
CCGraph()
{
nvertices = nedges = 0;
for (int i = 1; i <= MAXV; i++)
degree[i] = 0;
}
void read_CCGraph(boolean directed)
{
int x, y;
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of vertices: ");
nvertices = sc.nextInt();
System.out.println("Enter the number of edges: ");
int m = sc.nextInt();
System.out.println("Enter the edges: <from> <to>");
for (int i = 1; i <= m; i++)
{
x = sc.nextInt();
y = sc.nextInt();
insert_edge(x, y, directed);
}
sc.close();
}
void insert_edge(int x, int y, boolean directed)
{
if (degree[x] > MAXDEGREE)
System.out.printf(
"Warning: insertion (%d, %d) exceeds max degree\n", x, y);
edges[x][degree[x]] = y;
degree[x]++;
if (!directed)
insert_edge(y, x, true);
else
nedges++;
}
void print_CCGraph()
{
for (int i = 1; i <= nvertices; i++)
{
System.out.printf("%d: ", i);
for (int j = degree[i] - 1; j >= 0; j--)
System.out.printf(" %d", edges[i][j]);
System.out.printf("\n");
}
}
}
public class ConnectedComponents
{
static final int MAXV = 100;
static boolean processed[] = new boolean[MAXV];
static boolean discovered[] = new boolean[MAXV];
static int parent[] = new int[MAXV];
static void bfs(CCGraph g, int start)
{
LinkedList<Integer> q = new LinkedList<Integer>();
int i, v;
q.offer(start);
discovered[start] = true;
while (!q.isEmpty())
{
v = q.remove();
process_vertex(v);
processed[v] = true;
for (i = g.degree[v] - 1; i >= 0; i--)
{
if (!discovered[g.edges[v][i]])
{
q.offer(g.edges[v][i]);
discovered[g.edges[v][i]] = true;
parent[g.edges[v][i]] = v;
}
}
}
}
static void initialize_search(CCGraph g)
{
for (int i = 1; i <= g.nvertices; i++)
{
processed[i] = discovered[i] = false;
parent[i] = -1;
}
}
static void process_vertex(int v)
{
System.out.printf(" %d", v);
}
static void connected_components(CCGraph g)
{
int c;
initialize_search(g);
c = 0;
for (int i = 1; i <= g.nvertices; i++)
{
if (!discovered[i])
{
c++;
System.out.printf("Component %d:", c);
bfs(g, i);
System.out.printf("\n");
}
}
}
static public void main(String[] args)
{
CCGraph g = new CCGraph();
g.read_CCGraph(false);
g.print_CCGraph();
connected_components(g);
}
}

Related

Find all connected components and their sizes in a graph

I'm trying to find all connected components and their sizes in a graph. I don't know why, but the size is always 0. Maybe something is wrong in the method.
This is the problem that I am trying to solve. https://www.codechef.com/LRNDSA08/problems/FIRESC
public class B {
static void dfs(int s, int v, boolean[] visited, ArrayList<ArrayList<Integer>> adj) {
s++;
visited[v] = true;
for (int u : adj.get(v)) {
if (!visited[u]) {
dfs(s, u, visited, adj);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
StringBuilder str = new StringBuilder();
int t = sc.nextInt();
for (int xx = 0; xx < t; xx++) {
int n = sc.nextInt();
int m = sc.nextInt();
ArrayList<ArrayList<Integer>> arr = new ArrayList<>();
for (int i = 0; i < n; i++) {
arr.add(new ArrayList<Integer>());
}
boolean[] visited = new boolean[n];
Arrays.fill(visited, false);
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
a--;
b--;
arr.get(a).add(b);
arr.get(b).add(a);
}
long ways = 1;
int groups = 0;
for (int i = 0; i < n; i++) {
if (visited[i])
continue;
int size = 0;
dfs(size, i, visited, arr);
groups++;
ways *= size;
ways %= 1000000007;
}
System.out.println(groups + " " + ways);
}
}
}
You know size is passed as value and not as reference. So it won't get updated after you return from the call. One thing you could do is define a single element array like
int[] size = new int[1];
and modify your dfs like:
static void dfs(int[] s, int v, boolean[] visited, ArrayList<ArrayList<Integer>> adj) {
s[0]++;
visited[v] = true;
for (int u : adj.get(v)) {
if (!visited[u]) {
dfs(s, u, visited, adj);
}
}
}
Then your result will be in size[0] which you can use to update ways like ways *= size[0]
Or you could modify dfs to return size which is a cleaner way to get the size like below:
static int dfs(int v, boolean[] visited, ArrayList<ArrayList<Integer>> adj) {
visited[v] = true;
int sz = 1;
for (int u : adj.get(v)) {
if (!visited[u]) {
sz += dfs(u, visited, adj);
}
}
return sz;
}
And it seems like you have a misconception on how variables in Java work (see). Incrementing an int variable that resides on one lair of the stack would not affect a variable on another stack lair. That's why the size is always 0.
The following solution passes base test on CodeChef:
public class CountComponents {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int testCases = sc.nextInt();
for (int i = 0; i < testCases; i++) {
EmployeeGraph graph = parseGraph(sc);
graph.countComponentsAndComponentSizes();
}
}
public static EmployeeGraph parseGraph(Scanner sc) {
int employeeCount = sc.nextInt();
int connectionsCount = sc.nextInt();
boolean[][] adjacencyMatrix = new boolean[employeeCount][employeeCount];
for (int i = 0; i < connectionsCount; i++) {
int row = sc.nextInt() - 1;
int col = sc.nextInt() - 1;
adjacencyMatrix[row][col] = true;
adjacencyMatrix[col][row] = true;
}
return new EmployeeGraph(adjacencyMatrix);
}
}
class EmployeeGraph {
public static final int BILLION_SEVEN = 1_000_000_007;
private boolean[][] adjacencyMatrix;
public EmployeeGraph(boolean[][] adjacencyMatrix) {
this.adjacencyMatrix = adjacencyMatrix;
}
public void countComponentsAndComponentSizes() {
boolean[] visited = new boolean[adjacencyMatrix.length];
int componentCount = 0;
int waysToChooseCaptain = 1;
for (int row = 0; row < adjacencyMatrix.length; row++) {
if (!visited[row]) {
componentCount++;
waysToChooseCaptain = (waysToChooseCaptain % BILLION_SEVEN) * dfs(visited, row);
}
}
System.out.println(componentCount + " " + waysToChooseCaptain % BILLION_SEVEN);
}
public int dfs(boolean[] visited, int row) {
visited[row] = true; // marking the current employee as visited
int size = 1; // this component consists at least from 1 employee
for (int col = 0; col < adjacencyMatrix.length; col++) {
if (adjacencyMatrix[row][col] && !visited[col]) {
size += dfs(visited, col);
}
}
return size;
}
}

How do i not override an array when i iterate on it the second time

How can I make the second iteration use the first array "poqet" to switch their positions from true to false, but without changing their state when the first iteration made them all true?
public class Dhoma {
public static void main(String[] args) {
boolean poqet[] = new boolean[100];
int njerezit[] = new int[100];
int count = 0;
int nrRendorP = 0;
int nrRendorN = 0;
for (int i = 0; i < njerezit.length; i++) {
nrRendorN++;
for (int k = 0; k < poqet.length; k++) {
nrRendorP++;
if (nrRendorP == 100) {
nrRendorP = 0;
}
poqet[i] = Switch(nrRendorN, nrRendorP);
System.out.println(k + " " + poqet[i]);
}
}
// System.out.println("Jane te ndezura "+ count);
}
private static boolean Switch(int nr, int n) {
if (n % nr == 0) {
return true;
}
return false;
}
}

Java Array Index out of Bounds Error

I'm working on a brute force approach to the traveling salesman problem. I have a certain line that produces the ArrayIndexOutOfBounds exception, however all the arrays used there have more than enough space. The particular line of code:
testCity[0][a] = cities[0][(int) cityList[a]];
This is where I initialize testCity:
int[][] testCity = new int[2][CITIES+10];
cities:
public static int[][] cities = new int[2][CITIES+10];
And, finally, cityList:
Object[] cityList = new Integer[CITIES+10];
This is the entire error message:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at BruteF.permute(BruteF.java:39)
at BruteF.permute(BruteF.java:30)
at BruteF.permute(BruteF.java:30)
at BruteF.permute(BruteF.java:30)
at BruteF.main(BruteF.java:11)
And here is the code:
public class BruteF {
public static final int CITIES = 5;
public static int[][] cities = new int[2][CITIES+10];
public static int[][] bestCity = new int[2][CITIES+10];
public static double bestDistance = 1000;
public static int[][] testCity = new int[2][CITIES+10];
public static Object[] cityList = new Integer[CITIES+10];
public static void main(String[] args)
{
permute(java.util.Arrays.asList(1,2,3,4), 0);
for (int i = 0;i < CITIES;i++)
{
System.out.println(bestCity[0][i] + "," + bestCity[1][i]);
}
}
static void permute(java.util.List<Integer> arr, int k){
cities[0][0] = 1;
cities[1][0] = 1;
cities[0][1] = 2;
cities[1][1] = 5;
cities[0][2] = 3;
cities[1][2] = 2;
cities[0][3] = 4;
cities[1][3] = 3;
int originalX = cities[0][0];
int originalY = cities[1][0];
for(int i = k; i < arr.size(); i++){
java.util.Collections.swap(arr, i, k);
permute(arr, k+1);
java.util.Collections.swap(arr, k, i);
}
if (k == arr.size() -1){
for (int i = 0;i < CITIES;i++)
{
cityList = arr.toArray();
for (int a = 0;a < CITIES;a++)
{
testCity[0][a] = cities[0][(int) cityList[a]];
}
if (distance(testCity,CITIES,originalX, originalY) < bestDistance)
{
bestCity = testCity;
bestDistance = distance(testCity,CITIES, originalX, originalY);
}
}
}
}
static double distance (int[][] cities, int CITIES, int originalX, int originalY)
{
int[][] taken = new int[2][CITIES+1];
int takenCounter = 0;
double distance = 0;
cities[0][CITIES] = cities[0][0];
cities[1][CITIES] = cities[1][0];
for (int i = 0;i <= CITIES;i++)
{
for (int z = 0;z <= CITIES;z++)
{
if (cities[0][i] == taken[0][z] && cities[1][i] == taken[1][z])
{
return CITIES*1000; //possible error here
}
else {
taken[0][takenCounter] = cities[0][i];
taken[1][takenCounter] = cities[1][i];
}
}
if (cities[0][0] != originalX && cities[1][0] != originalY)
{
return CITIES*1000; //POSSIBLE BUG HERE
}
distance = distance + Math.sqrt(Math.pow(cities[0][i+1]-cities[0][i],2) + Math.pow(cities[1][i+1]-cities[1][i],2));
}
return distance;
}
}
Why is this happenening? What can I do to fix it?
It is giving out of bound exception : 4
when you are initializing cityList i.e. cityList = arr.toArray(); your array cityList[] = {1,2,3,4} , i.e of size 4 from 0 to 3.
And you are running a for loop i.e
for (int a = 0;a < CITIES;a++)
from a=0 to CITIES , so as the moment arrive when a=4, it gives out of bound error.

how to delete all the same occurences from an array

So far I have tried to create the method below, but when I run it, the new array leaves zeros for the empty spaces. If a find all method is created to work with this how can it be implemented with a binary search instead of a linear search
package bp;
import java.util.Arrays;
public class SortedList implements IUnsortedList {
/**
* The max size of the List.
*/
public static final int MAX_SIZE = 10000;
/**
* The max value of each occurence.
*/
public static final int MAX_VALUE = 10;
/**
* Flag for the amount of items on the list.
*/
private int sizeOfList = 0;
/**
* Variable to define true or false for duplicates.
*/
private boolean duplicatesAllowed = true;
/**
* Array saves the occurences in the list.
*/
private final int[] listItems = new int[MAX_SIZE];
/**
* Variable for the value to find or delete.
*/
private int searchKey;
/**
* Variable for counter in a loop.
*/
private int f;
#Override
public int getSizeOfList() {
return sizeOfList;
}
#Override
public boolean areDuplicatesAllowed() {
return duplicatesAllowed;
}
#Override
public void setDupliatesAllowed(boolean pDuplicatesAllowed) {
duplicatesAllowed = pDuplicatesAllowed;
}
#Override
public void clear() {
sizeOfList = 0;
}
#Override
public void insert(int pValueToInsert) {
//Loop finds the position of the Item
for (f = 0; f < sizeOfList; f++)
if (listItems[f] > pValueToInsert)
break;
//Loop moves the items after the position up
for (int n = sizeOfList; n > f; n-- )
listItems[n] = listItems[n - 1];
//Insert the Value in the right position
listItems[f] = pValueToInsert;
//Increment List size
sizeOfList++;
}
#Override
public void delete(int pValueToDelete) {
int destroyHAHAHA = find(pValueToDelete);
//If it doesnt find it the item
if (destroyHAHAHA==sizeOfList)
System.out.println("I let you down boss, Can't find "
+ pValueToDelete);
//If it does, kill it with fire
else {
for (int n = destroyHAHAHA; n <sizeOfList; n++)
listItems[n] = listItems[n + 1];
sizeOfList--;
}
}
#Override
public void deleteAll(int pValueToDelete) {
int j = 0;
for(int i = 0; i < listItems.length; i++ )
{
if (listItems[i] != pValueToDelete)
listItems[j++] = listItems[i];
}
int [] newArray = new int[j];
System.arraycopy(listItems, 0, newArray, 0, j );
}
#Override
public void initializeWithRandomData(int pSizeOfList) {
// Loop creates an array with certain number of elements
if (duplicatesAllowed) {
for (int n = 0; n < pSizeOfList; ++n) {
insert(listItems[n] = (int) (Math.random() * MAX_VALUE + 1));
}
} else {
int newvalue=0;
for (int n = 0; n < pSizeOfList; ++n) {
listItems[n] = newvalue++;
++sizeOfList;
}
}
}
#Override
public int find(int pValueToFind) {
searchKey = pValueToFind;
int lowNumber = 0;
int highNumber = sizeOfList - 1;
int result;
while (true) {
result = (lowNumber + highNumber) / 2;
if (listItems[result] == searchKey)
return result;
else if (lowNumber > highNumber)
return sizeOfList;
else {
if (listItems[result] < searchKey)
lowNumber = result + 1;
else
highNumber = result - 1;
}
}
}
#Override
public int[] findAll(int pValueToFind) {
//Array with the location of item
int[] answerArray = new int[sizeOfList];
int searchIndex;
int answerIndex = 0;
for (searchIndex = 0; searchIndex < sizeOfList; searchIndex++) {
if (listItems[searchIndex] == pValueToFind) {
answerArray[answerIndex++] = searchIndex;
}
}
if (answerIndex > 0) {
return Arrays.copyOfRange(answerArray, 0, answerIndex);
} else {
return new int[0];
}
}
#Override
public String toString() {
return Arrays.toString(Arrays.copyOfRange(listItems, 0, sizeOfList));
}
public void bubbleshort(){
int out;
int in;
int middle;
for (out = 0; out < sizeOfList - 1; out++) {
middle = out;
for(in = out +1; in < sizeOfList; in++)
if(listItems[in] < listItems[middle])
middle = in;
selectionSort(out, middle);
}
}
public void selectionSort(int one, int two) {
int temporal = listItems[one];
listItems[one] = listItems[two];
listItems[two] = temporal;
}
}
You can use Common langs ArrayUtils.removeElement() or ArrayUtils.removeAll() method to remove all the elements from the array.
Set contains no duplicates. You can use a Set.
Set<T> mySet = new HashSet<T>(Arrays.asList(someArray));
or
Set<T> mySet = new HashSet<T>();
Collections.addAll(mySet, myArray);

Inheritance problems in Java

I have some problems with getting inheritance to work. In the parent class, the array Coefficients is private. I have some access methods but I still can't get it to work.
import java.util.ArrayList;
public class Poly {
private float[] coefficients;
public static void main (String[] args){
float[] fa = {3, 2, 4};
Poly test = new Poly(fa);
}
public Poly() {
coefficients = new float[1];
coefficients[0] = 0;
}
public Poly(int degree) {
coefficients = new float[degree+1];
for (int i = 0; i <= degree; i++)
coefficients[i] = 0;
}
public Poly(float[] a) {
coefficients = new float[a.length];
for (int i = 0; i < a.length; i++)
coefficients[i] = a[i];
}
public int getDegree() {
return coefficients.length-1;
}
public float getCoefficient(int i) {
return coefficients[i];
}
public void setCoefficient(int i, float value) {
coefficients[i] = value;
}
public Poly add(Poly p) {
int n = getDegree();
int m = p.getDegree();
Poly result = new Poly(Poly.max(n, m));
int i;
for (i = 0; i <= Poly.min(n, m); i++)
result.setCoefficient(i, coefficients[i] + p.getCoefficient(i));
if (i <= n) {
//we have to copy the remaining coefficients from this object
for ( ; i <= n; i++)
result.setCoefficient(i, coefficients[i]);
} else {
// we have to copy the remaining coefficients from p
for ( ; i <= m; i++)
result.setCoefficient(i, p.getCoefficient(i));
}
return result;
}
public void displayPoly () {
for (int i=0; i < coefficients.length; i++)
System.out.print(" "+coefficients[i]);
System.out.println();
}
private static int max (int n, int m) {
if (n > m)
return n;
return m;
}
private static int min (int n, int m) {
if (n > m)
return m;
return n;
}
public Poly multiplyCon (double c){
int n = getDegree();
Poly results = new Poly(n);
for (int i =0; i <= n; i++){ // can work when multiplying only 1 coefficient
results.setCoefficient(i, (float)(coefficients[i] * c)); // errors ArrayIndexOutOfBounds for setCoefficient
}
return results;
}
public Poly multiplyPoly (Poly p){
int n = getDegree();
int m = p.getDegree();
Poly result = null;
for (int i = 0; i <= n; i++){
Poly tmpResult = p.multiByConstantWithDegree(coefficients[i], i); //Calls new method
if (result == null){
result = tmpResult;
} else {
result = result.add(tmpResult);
}
}
return result;
}
public void leadingZero() {
int degree = getDegree();
if ( degree == 0 ) return;
if ( coefficients[degree] != 0 ) return;
// find the last highest degree with non-zero cofficient
int highestDegree = degree;
for ( int i = degree; i <= 0; i--) {
if ( coefficients[i] == 0 ) {
highestDegree = i -1;
} else {
// if the value is non-zero
break;
}
}
float[] newCoefficients = new float[highestDegree + 1];
for ( int i=0; i<= highestDegree; i++ ) {
newCoefficients[i] = coefficients[i];
}
coefficients = newCoefficients;
}
public Poly differentiate(){
int n = getDegree();
Poly newResult = new Poly(n);
if (n>0){ //checking if it has a degree
for (int i = 1; i<= n; i++){
newResult.coefficients[i-1]= coefficients[i] * (i); // shift degree by 1 and multiplies
}
return newResult;
} else {
return new Poly(); //empty
}
}
public Poly multiByConstantWithDegree(double c, int degree){ //used specifically for multiply poly
int oldPolyDegree = this.getDegree();
int newPolyDegree = oldPolyDegree + degree;
Poly newResult = new Poly(newPolyDegree);
//set all coeff to zero
for (int i = 0; i<= newPolyDegree; i++){
newResult.coefficients[i] = 0;
}
//shift by n degree
for (int j = 0; j <= oldPolyDegree; j++){
newResult.coefficients[j+degree] = coefficients[j] * (float)c;
}
return newResult;
}
}
Can anyone help me fix my Second class that inherits from the one above? I cant seem to get my multiply and add methods for the second class to work properly.
public class QuadPoly extends Poly
{
private float [] quadcoefficients;
public QuadPoly() {
super(2);
}
public QuadPoly(int degree) {
super(2);
}
public QuadPoly(float [] f) {
super(f);
if (getDegree() > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
}
public QuadPoly(Poly p){
super(p.coefficients);
for (int i = 0; i < coefficients.length; i++){
if (coefficients[i] < 0){
throw new Exception("Expecting positive coefficients!");
}
}
}
// public QuadPoly(Poly p){
// super(p.coefficients);
//}
public QuadPoly addQuad (QuadPoly p){
return new QuadPoly(super.add(p));
}
public QuadPoly multiplyQuadPoly (QuadPoly f){
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
return new QuadPoly(super.multiplyPoly(f));
}
I would make the coefficients protected or use an accessor method.
I wouldn't throw a plain checked Exception. An IllegalArgumentException would be a better choice.
What is quadcoefficients? They don't appear to be set anywhere.
You put coefficients private. I wouldn't change this but I would add a getter method into Poly class:
public class Poly {
//somecode here
public float[] getCoefficients(){
return this.coefficients;
}
}
Then I would use it by the getter method in other code;
public QuadPoly(Poly p){
super(p.getCoefficients);
//some more code here
}
Even if you make coefficient protected, you are trying to reach coefficients field of another Object, which is a parameter. So it is not related to inheritance and the problem.

Categories