Problem with DFS graph algorithm, wrong loops found - algorithm

I want to create an algorithm to understand how many closed areas there are in a graph with the relative points, at the moment the problem is that it finds almost all the loops, using a DFS algorithm. However, a problem arises
This is my actual code,momentarily done on processing for instant video feedback:
import java.util.Iterator;
import java.util.LinkedList;
class Graph {
int white = 0, gray = 1, black = 2;
ArrayList<ArrayList<Integer>> path = new ArrayList<ArrayList<Integer>>();
int V;
LinkedList<Integer>[] adj;
LinkedList<Integer>[] cycles;
LinkedList<PVector> points = new LinkedList<PVector>();
int num_cycles = 0;
Graph(int v) {
V = v;
adj = new LinkedList[V];
cycles = new LinkedList[V];
for (int i = 0; i < V; i++) {
adj[i] = new LinkedList();
cycles[i] = new LinkedList();
}
}
void DFSCycleUtil(int source, int parent, int[] colors, int[] parents) {
if (colors[source] == gray) {
System.out.println("Cycle");
path.add(new ArrayList<Integer>());
int curr_parent = parent;
cycles[num_cycles].add(source);
System.out.println(source);
path.get(num_cycles).add(source);
while (curr_parent != source) {
cycles[num_cycles].add(curr_parent);
path.get(num_cycles).add(curr_parent);
System.out.println(curr_parent);
curr_parent = parents[curr_parent];
}
num_cycles++;
return;
} else if (colors[source] == black) {
return;
}
parents[source] = parent;
colors[source] = gray;
Iterator<Integer> i = adj[source].listIterator();
while (i.hasNext()) {
int n = i.next();
if (n != parent) {
DFSCycleUtil(n, source, colors, parents);
}
}
colors[source] = black;
}
void DFSCycle() {
int colors[] = new int[V];
int parents[] = new int[V];
for (int i = 0; i < V; i++) {
colors[i] = white;
}
for (int i = 0; i < V; i++) {
if (colors[i] == white) {
DFSCycleUtil(i, -1, colors, parents);
}
}
}
void addEdge(int u, int v) {
adj[u].add(v);
adj[v].add(u);
}
void addPoint(int x, int y){
points.add(new PVector(x,y));
}
void drawGraph(){
for(int i = 0; i<points.size();i++){
circle(points.get(i).x,points.get(i).y,10);
text(i+1,points.get(i).x,points.get(i).y-5);
Iterator<Integer> in = adj[i+1].listIterator();
print(i + ": \n");
while (in.hasNext()) {
int t = in.next();
line(points.get(i).x,points.get(i).y,points.get(t-1).x,points.get(t-1).y);
}
}
for(int i = 0; i<path.size();i++){
fill(10,10,random(255));
beginShape();
for(int j = 0; j<path.get(i).size(); j++){
vertex(points.get(path.get(i).get(j)-1).x, points.get(path.get(i).get(j)-1).y);
}
endShape(CLOSE);
}
}
}
void setup(){
size(500,500);
Graph g = new Graph(9);
g.addEdge(1,2);
g.addEdge(1,3);
g.addEdge(3,2);
g.addEdge(3,4);
g.addEdge(5,2);
g.addEdge(5,6);
g.addEdge(4,2);
g.addEdge(4,6);
g.addEdge(4,5);
g.addPoint(100,50);
g.addPoint(150,50);
g.addPoint(100,100);
g.addPoint(150,100);
g.addPoint(200,50);
g.addPoint(200,100);
g.DFSCycle();
g.drawGraph();
}
The problem is that it also finds areas that cover other previously found areas, and I don't know how to avoid it.
I would like to know first if there is a better method than the one I am using, and then how I can solve my need.
Thanks in advance
Example images:
This is my actual result:
And this would be my final result:

Related

Delete leftmost circle on the canvas

I was able to write a code that draws different circles on a canvas and i need to find a way i could delete the leftmost circle when any key is pressed. i've been at this for hours and i feel like i am close to the answer. i am most klikely going to look for the array whenever a key is pressed and delete the array position.
float colour = random(256);
final int DIAM = 20;
final int MAX_NUM = 1000;
int numPointsX = 0;
int numPointsY = 0;
int [] xPos = new int[MAX_NUM];
int [] yPos = new int [MAX_NUM];
boolean start = false;
void setup() {
size (500, 500);
}
void draw() {
background(150);
fill(random(256), random(256), random(256));
for (int i=0; i<numPointsX; i++) {
circle(xPos[i], yPos[i], DIAM);
}
println(xPos[0]);
}
void mouseClicked() {
insertXandY();
}
void insertXandY() {
int x = mouseX;
int y = mouseY;
xPos[numPointsX] = x;
yPos[numPointsY] = y;
numPointsX += 1;
numPointsY += 1;
start = true;
}
void printArrays() {
println("X Positions");
for (int i = 0; i < 20; i++) {
println("\t" + xPos[i]);
}
}
void keyPressed() {
if (key == 'p') {
printArrays();
}
}
You are on the right track.
In broad terms you'd need two steps:
find the smallest X
delete the data associated with the smallest X
The 1st part is trivial:
use a variable to keep track of the currently smallest value (initialised with a bigger than than your data has)
iterate through each value
compare each value with the current smallest:
if it's bigger ignore
if it's smallest: update the currently smallest value (and remember the index)
at the end of the iteration the currently smallest value is the smallest possible value and index can be used to associate between x,y arrays (which are incremented in sync)
Here's a slightly modified version of your code to illustrate this:
float colour = random(256);
final int DIAM = 20;
final int MAX_NUM = 1000;
int numPoints = 0;
int [] xPos = new int[MAX_NUM];
int [] yPos = new int [MAX_NUM];
void setup() {
size (500, 500);
}
void draw() {
background(150);
fill(random(256), random(256), random(256));
for (int i=0; i < numPoints; i++) {
circle(xPos[i], yPos[i], DIAM);
}
}
void mouseClicked() {
insertXandY();
}
void insertXandY() {
int x = mouseX;
int y = mouseY;
xPos[numPoints] = x;
yPos[numPoints] = y;
numPoints++;
}
void deleteLeftMost(){
// find leftmost index
// start with a large X value
int smallestX = width;
int smallestXIndex = -1;
// iterate through each X
for(int i = 0 ; i < numPoints; i++){
// if xPos[i] is smaller than the smallest value so far...
if (xPos[i] < smallestX){
// ...remember it's value and index
smallestX = xPos[i];
smallestXIndex = i;
}
}
// delete the item at this index: fake it for now: move coordinates offscreen (to the right so left search still works)
xPos[smallestXIndex] = width * 2;
}
void printArrays() {
println("X Positions");
for (int i = 0; i < 20; i++) {
println("\t" + xPos[i]);
}
}
void keyPressed() {
if (key == 'p') {
printArrays();
}
if (keyCode == DELETE || keyCode == BACKSPACE){
deleteLeftMost();
}
}
I've made a few of other minor adjustments:
deleted start since it was assigned but not used (when debugging delete anything that isn't necessary)
renamed numPointsX to numPoints and deleted numPointsY: you are using two arrays indeed, however there is only one index for each point that could be re-used to access each array
numPoints++ is shorthand for numPoints = numPoints + 1;
Also, I've used a hacky placeholder for the remove a point just visually.
This means in terms of memory the xPos/yPos for deleted points will still be allocated.
To actually delete the array is a bit tricker since the array datatype does not change size, however you could manually put something together using subset() and concat(). You can achieve a similar effect to deleting an element by concatenating two subset array: from the start to the index to delete and from the index next to the one to delete to the end of the array.
Something like this:
void setup(){
println(deleteIndex(new int[]{1,2,3,4,5,6},-1));
println(deleteIndex(new int[]{1,2,3,4,5,6},2));
println(deleteIndex(new int[]{1,2,3,4,5,6},6));
}
int[] deleteIndex(int[] sourceArray, int indexToDelete){
if(sourceArray == null){
System.err.println("can't process null array");
return null;
}
if(indexToDelete < 0){
System.err.println("invalid index " + indexToDelete + "\nit's < 0");
return null;
}
if(indexToDelete >= sourceArray.length){
System.err.println("invalid index " + indexToDelete + "\nmax index = " + sourceArray.length);
return null;
}
return concat(subset(sourceArray, 0, indexToDelete),
subset(sourceArray, indexToDelete + 1, sourceArray.length - indexToDelete - 1));
}
It's a good idea to check arguments to a method to ensure they are valid and test with at least a few edge cases.
Here's a version of the above sketch using this delete method:
float colour = random(256);
final int DIAM = 20;
final int MAX_NUM = 1000;
int numPoints = 0;
int [] xPos = new int[MAX_NUM];
int [] yPos = new int [MAX_NUM];
void setup() {
size (500, 500);
}
void draw() {
background(150);
fill(random(256), random(256), random(256));
for (int i=0; i < numPoints; i++) {
circle(xPos[i], yPos[i], DIAM);
}
}
void mouseClicked() {
insertXandY();
}
void insertXandY() {
int x = mouseX;
int y = mouseY;
xPos[numPoints] = x;
yPos[numPoints] = y;
numPoints++;
}
void deleteLeftMost(){
// find leftmost index
// start with a large X value
int smallestX = width;
int smallestXIndex = -1;
// iterate through each X
for(int i = 0 ; i < numPoints; i++){
// if xPos[i] is smaller than the smallest value so far...
if (xPos[i] < smallestX){
// ...remember it's value and index
smallestX = xPos[i];
smallestXIndex = i;
}
}
// delete xPos item at this index
xPos = deleteIndex(xPos, smallestXIndex);
// delete yPos as well
yPos = deleteIndex(yPos, smallestXIndex);
// update size counter
numPoints--;
}
int[] deleteIndex(int[] sourceArray, int indexToDelete){
if(sourceArray == null){
System.err.println("can't process null array");
return null;
}
if(indexToDelete < 0){
System.err.println("invalid index " + indexToDelete + "\nit's < 0");
return null;
}
if(indexToDelete >= sourceArray.length){
System.err.println("invalid index " + indexToDelete + "\nmax index = " + sourceArray.length);
return null;
}
return concat(subset(sourceArray, 0, indexToDelete),
subset(sourceArray, indexToDelete + 1, sourceArray.length - indexToDelete - 1));
}
void printArrays() {
println("X Positions");
for (int i = 0; i < xPos.length; i++) {
println("\t" + xPos[i]);
}
}
void keyPressed() {
if (key == 'p') {
printArrays();
}
if (keyCode == DELETE || keyCode == BACKSPACE){
deleteLeftMost();
}
}
If manually deleting an item from an array looks tedious it's because it is :)
Array is meant to be fixed size: deleting an item actually allocates 3 arrays: two subset arrays and one for concatenation.
A better option is to use a dynamic sized array data structure like ArrayList. Speaking of data structures, to represent a point you can use the PVector class (which has x,y properties, but can also do much more).
You might have not encountered ArrayList and PVector yet, but there are plenty of resources out there (including CodingTrain/NatureOfCode videos).
Here's an example using these:
final int DIAM = 20;
final int MAX_NUM = 1000;
ArrayList<PVector> points = new ArrayList<PVector>();
void setup() {
size (500, 500);
}
void draw() {
background(150);
fill(random(256), random(256), random(256));
for (PVector point : points) {
circle(point.x, point.y, DIAM);
}
}
void mouseClicked() {
insertXandY();
}
void insertXandY() {
if(points.size() < MAX_NUM){
points.add(new PVector(mouseX, mouseY));
}
}
void deleteLeftMost(){
// find leftmost index
// start with a large X value
float smallestX = Float.MAX_VALUE;
int smallestXIndex = -1;
// iterate through each X
for(int i = 0 ; i < points.size(); i++){
PVector point = points.get(i);
// if xPos[i] is smaller than the smallest value so far...
if (point.x < smallestX){
// ...remember it's value and index
smallestX = point.x;
smallestXIndex = i;
}
}
// remove item from list
points.remove(smallestXIndex);
}
void keyPressed() {
if (key == 'p') {
println(points);
}
if (keyCode == DELETE || keyCode == BACKSPACE){
deleteLeftMost();
}
}
Hopefully this step by step approach is easy to follow.
Have fun learning !

What is correct solution for this (Benny and Segments) question on Hackerearth?

How do i correctly solve this question Benny and Segments. The solution given for this question is not correct . According to editorial for this question, following is a correct solution.
import java.io.*; import java.util.*;
class Pair{
int a; int b;
public Pair(int a , int b){ this.a = a; this.b = b;}
}
class TestClass {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static void rl() throws Exception{st = new StringTokenizer(br.readLine());}
static int pInt() {return Integer.parseInt(st.nextToken());}
public static void main(String args[] ) throws Exception {
rl();
int T = pInt();
while(T-- > 0){
rl();
int N = pInt();
int L = pInt();
Pair[] p = new Pair[N];
for(int i = 0; i < N; i++){
rl();
int l = pInt();
int r = pInt();
p[i] = new Pair(l, r);
}
Arrays.sort(p, new Comparator<Pair>(){
#Override
public int compare(Pair o1, Pair o2)
{
return o1.a - o2.a;
}
});
boolean possible = false;
for(int i = 0; i < N; i++){
int start = p[i].a;
int curr_max = p[i].b;
int req_max = p[i].a + L;
for(int j = 0; j < N; j++){
if(p[i].a <= p[j].a && p[j].b <= req_max){
curr_max = Math.max(curr_max, p[j].b);
}
}
if(curr_max == req_max ){
System.out.println("Yes");
possible = true;
break;
}
}
if(!possible)
System.out.println("No");
}
}
}
But this will certainly fail for the following testcase. It will give "Yes" when it should have given "No", Because there is no continuous path of length 3.
1
3 3
1 2
3 4
4 5
As suggested by kcsquared. I modified my code.
It runs correctly. I think Question setters had set weak test case for this question.
As your test-case demonstrates, the error is that when adding new segments to extend the current segment, there's no test to check whether the new segment can reach the current segment or would leave a gap. To do so, compare the new segment's left end to your current segment's right end:
for(int j = i + 1; j < N; j++){
if(p[j].a <= curr_max && p[j].b <= req_max){
curr_max = Math.max(curr_max, p[j].b);
}
}

How to write this processing code in an alternative (beginner) way?

How do I write the code (below) in an alternative (beginner) way? I don't wish to use createShape, setFill and addChild. Instead, any other way to perform the same thing?
grid = createShape(GROUP)
for i in range(C*R):
self.cell = createShape(RECT, (i%C)*S, (i//C)*S, S, S)
self.cell.setFill(colors[i] if i in filled else 210)
grid.addChild(self.cell)
Assuming that you're try to create a rectangle grid:
final int _numRows = 5;
final int _numCols = 7;
int l = 20;
int t = 20;
int w = 90;
int h = 60;
int hg = 10;
int vg = 10;
int left;
int top;
void rectGrid() {
for(int k = 0; k < _numRows; k++) {
for(int j = 0; j < _numCols; j++){
left = l + j*(w+vg);
top = t + k*(h+hg);
stroke(255);
strokeWeight(2);
fill(118);
rect( left, top, w, h);
}
}
}
void setup() {
size(800,500);
background(0,0,245);
rectGrid();
}
void draw() {
}
Adds a color array:
/*
Adds color array to rectangle grid.
*/
final int _numRows = 5;
final int _numCols = 7;
int l = 20;
int t = 20;
int w = 90;
int h = 60;
int hg = 10;
int vg = 10;
int left;
int top;
int count = 0;
color[] c;
void colorArray(){
for(int x=0; x< _numRows*_numCols; x++){
c[x] = color(random(255),random(255),random(255))
}
}
void rectGrid() {
for(int k = 0; k < _numRows; k++) {
for(int j = 0; j < _numCols; j++){
left = l + j*(w+vg);
top = t + k*(h+hg);
stroke(255);
strokeWeight(2);
fill(c[count]);
rect( left, top, w, h);
count++;
}
}
}
void setup() {
size(800,500);
background(0,0,245);
c = new color[_numCols*_numRows];
colorArray();
// Make sure the color array is filled first
rectGrid();
}
void draw() {
}

multiplyByConstant method and matrices

public class Matrix{
public double myArray[][];
public Matrix(double a[][]){
this.myArray=a;
}
public Matrix(int b,Vector...vectors) {
double myArray[][] = new double[vectors.length][];
int row = vectors.length;
int column = vectors.length;
for (int i = 0; i < row; i++) {
myArray[i] = new double[column];
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if(b==0)
{
myArray[i][j] = vectors[i].getYourArray()[j];
}
else
{
myArray[j][i] = vectors[i].getYourArray()[j];
}
}
}
}
public Matrix(int a){
double [][] t=new double[a][a];
Matrix z=new Matrix(t);
for(int i=0;i<a;i++){
for(int j=0;j<a;j++){
if(i==j) z.myArray[i][j]=1;
else z.myArray[i][j]=0;
}
}
this.myArray=z.myArray;
}
public Matrix multiplyByConstant(double m){ // here
}
}
multiplyByConstatnt: Multiplication by a constant: taking a double as a multiplication factor and multiply every element of the matrix with that factor and return a new matrix.
I have also vector and test class,but i don't know how to use this method with matrix

MergeSort gives StackOverflow error

this is the code for the mergeSort,this gives an stackoverflow error in line 53 and 54(mergeSort(l,m); and mergeSort(m,h);)
Any help will be regarded so valuable,please help me out,i am clueless,Thank you.
package codejam;
public class vector {
static int[] a;
static int[] b;
public static void main(String[] args) {
int[] a1 = {12,33,2,1};
int[] b1 = {12,333,11,1};
mergeSort(0,a1.length);
a1=b1;
mergeSort(0,b1.length);
for (int i = 0; i < a1.length; i++) {
System.out.println(a[i]);
}
}
public static void merge(int l,int m,int h) {
int n1=m-l+1;
int n2 = h-m+1;
int[] left = new int[n1];
int[] right = new int[n2];
int k=l;
for (int i = 0; i < n1 ; i++) {
left[i] = a[k];
k++;
}
for (int i = 0; i < n2; i++) {
right[i] = a[k];
k++;
}
left[n1] = 100000000;
right[n1] = 10000000;
int i=0,j=0;
for ( k =l ; k < h; k++) {
if(left[i]>=right[j])
{
a[k] = right[j];
j++;
}
else
{
a[k] = left[i];
i++;
}
}
}
public static void mergeSort(int l,int h) {
int m =(l+h)/2;
if(l<h)
{
mergeSort(l,m);
mergeSort(m,h);
merge(l,m,h);;
}
}
}
Following is the recursive iterations table of the mergeSort function with argument l=0 and h=4
when the value of l is 0 and value of h is 1 , expression calculate m value which turn out to be 0 but we are checking condition with h which is still 1 so 0<1 become true , recursive calls of this mergeSort function forms a pattern , this pattern doesn't let the function to terminate , stack runs out of memory , cause stackoverflow error.
import java.lang.*;
import java.util.Random;
public class MergeSort {
public static int[] merge_sort(int[] arr, int low, int high ) {
if (low < high) {
int middle = low + (high-low)/2;
merge_sort(arr,low, middle);
merge_sort(arr,middle+1, high);
arr = merge (arr,low,middle, high);
}
return arr;
}
public static int[] merge(int[] arr, int low, int middle, int high) {
int[] helper = new int[arr.length];
for (int i = 0; i <=high; i++){
helper[i] = arr[i];
}
int i = low;
int j = middle+1;
int k = low;
while ( i <= middle && j <= high) {
if (helper[i] <= helper[j]) {
arr[k++] = helper[i++];
} else {
arr[k++] = helper[j++];
}
}
while ( i <= middle){
arr[k++] = helper[i++];
}
while ( j <= high){
arr[k++] = helper[j++];
}
return arr;
}
public static void printArray(int[] B) {
for (int i = 0; i < B.length ; i++) {
System.out.print(B[i] + " ");
}
System.out.println("");
}
public static int[] populateA(int[] B) {
for (int i = 0; i < B.length; i++) {
Random rand = new Random();
B[i] = rand.nextInt(20);
}
return B;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int A[] = new int[10];
A = populateA(A);
System.out.println("Before sorting");
printArray(A);
A = merge_sort(A,0, A.length -1);
System.out.println("Sorted Array");
printArray(A);
}
}

Resources