Avoid adding duplicates to an array - java

I would to store the distance between 4 clusters, so I took the sum of the distance between cluster x and cluster y and vise versa -since the distance between cluster x and cluster y != cluster y and cluster x- then divide them by 2 so it would be non directional.
The problem I'm facing here is the duplication. How can I end up with only 6 distances and avoid adding duplicates to the array in the first place.
Notes:
I made DistanceBetweenClusterToAnother a two dimensional array with the goal of solving this issue, since I couldn't solve it with one dimensional array.
this.clusterSize() equals 4.
for (int k = 0; k < this.clusterSize(); k++) {
for (int j = 0; j < this.clusterSize(); j++) {
if (k != j) {
DistanceBetweenClusterToAnother[k][j] = GADOfCluster1toCluster2[k][j] + GADOfCluster1toCluster2[j][k];
DistanceBetweenClusterToAnother[k][j]= DistanceBetweenClusterToAnother[k][j]/2;
}
}
}

Start the inner loop after the current position of the outer loop. Also, you can average in one line:
for (int k = 0; k < this.clusterSize(); k++) {
for (int j = k + 1; j < this.clusterSize(); j++) {
DistanceBetweenClusterToAnother[k][j] = (GADOfCluster1toCluster2[k][j] + GADOfCluster1toCluster2[j][k]) / 2;
}
}

Not sure if it would be the optimal way, but you can check the array for an match.
if (valueYouWantToCheck == Array.getIndex(i))
Array.add(valueYouWantToCheck);

Related

Big O for 3 nested for loops?

public int Loop(int[] array1) {
int result = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1.length; j++) {
for (int k = 1; k < array1.length; k = k * 2) {
result += j * j * array1[k] + array1[i] + array1[j];
}
}
}
return result;
}
I'm trying to find the complexity function that counts the number of arithmetic operations here. I know the complexity class would be O(n^3), but I'm having a bit of trouble counting the steps.
My reasoning so far is that I count the number of arithmetic operations which is 8, so would the complexity function just be 8n^3?
Any guidance in the right direction would be very much appreciated, thank you!
The first loop will run n times, the second loop will run n times however the third loop will run log(n) times (base 2). Since you are multiplying k by two each time the inverse operation would be to take the log. Multiplying we have O(n^2 log(n))
If we can agree that the following is one big step:
result += j * j * array1[k] + array1[i] + array1[j]
then let's call that incrementResult.
How many times is incrementResult called here? (log n)
for (int k = 1; k < array1.length; k = k * 2) {
// incrementResult
}
Lets call that loop3. Then how many times is loop3 called here? (n)
for (int j = 0; j < array1.length; j++) {
// loop 3
}
Let's call that loop2. Then, how many times is loop2 called here? (n)
for (int i = 0; i < array1.length; i++) {
// loop 2
}
Multiply all of those and you'll get your answer :)
That depends on the loops. For instance:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
for (int k = 0; k < 10; k++) {
sum += i * j * k;
}
}
}
has complexity O(1), because the number of iterations does not depend on the input at all.
Or this:
for (int i = 0; i < n*n*n*n*n*n; i++) {
sum += i;
}
is O(n^6), even though there is a single loop.
What really matters is how many iterations each loop makes.
In your case, it is easy to see that each iteration of the innermost loop is O(1). How many iterations are there? How many times do you need to double a number until you reach n? If x is the number of iterations, we'd exit the loop at the first x such that k = 2^x > n. Can you solve this for x?
Each iteration of the second loop will do this, so the cost of the second loop is the number of iterations (which are easier to count this time) times the cost of the inner loop.
And each iteration of the first loop will do this, so the cost of the first loop is the number of iterations (which is also easy to count) times the cost of the second loop.
Overall, the runtime is the product of 3 numbers. Can you find them?

How to optimize this piece of code? [Processing inside nested for loops]

for (int i = 0,len=size-2; i < len; i++) {
for (int j = 1,leng = size-1; j < leng; j++) {
for (int k = 2; k < size; k++) {
if (i < j && j < k) {
sum = sum + Math.floor((a[i] + a[j] + a[k]) / (a[i] * a[j] * a[k]));
}
}
}
}
I need this piece of code to run in atleast half of the current running time.Here, the array 'a' is of the type double. I am taking inputs via the reader class. How to achieve a faster run time?
Your nested loops do nothing but iterate unless the condition i < j && j < k is satisfied. But the middle and inner loops start their iterations at the same initial value every time, regardless of the values of the outer loop indexes. For example, when i is 5, the middle loop still starts at 1 and the inner one still starts at 2, even though they can know that they will not perform any useful work for those values.
Start each loop iterating from a more useful point. You will save much useless index arithmetic and many vain index comparisons. In fact, if you do it properly then you shouldn't need to perform any index comparisons at all.
Details, such as they are, are left as an exercise. I've probably offered too much help already.
You can rewrite 1/(x*y*z)as 1*(1/x)*(1/y)*(1/z). Multiplying is faster than dividing. You can precalculate array of reciprocal values as ra[i] = 1/a[i]. There can be further optimizations, but it depends on what values there can be, You did not answer that question.
With this code there will not be any need of an if statement:
x is always inferior to y which is always inferior to z
for (int x = 0; x < size - 2; x++)
for(int y = x + 1; y < size - 1; y++)
for(int z = y + 1; z < size; z++)
sum += Math.floor((a[x] + a[y] + a[z]) / (a[x] * a[y] * a[z]));

Java Method that checks for objects diagonally in 2D array

I am doing an N Queens Program in Java. I was able to print all the solutions where each Queen is on a different row and column. Now I need to keep track of the diagonals for collisions. So there are 2n-1 diagonal lines on a 2D array. The algorithm wants us to there are 2n-1 negative diagonal lines and 2n - 1 positive diagonal lines on the chessboard. There is an array of size 2n-1, called d1, that keeps track of the number of queens, i.e., the number of collisions, on each of the 2n-1 negative diagonal lines. If there are k queens on the mth negative diagonal line, there are k-1 collisions on this diagonal line. The
number k is written into the mth element of the d1 array. Similarly, we choose another array with size 2n-1, called d2, for 2n-1 positive diagonal lines.
Here is my method for D2, but I am completely lost. I know that all the up diagonals are row + col, but that is it.
public void D2(){
int[] upDiag = new int[2*board.length - 1];
int numberOfCollisions = 0;
for(int row = 0; row < board.length; row++){
for(int col = 0; col < board.length; col++){
if(isQueen(row, col)){
upDiag[numberOfCollisions++];
}
}
}
}
I've written a three-part series on the Eight-Queens/N-Queens Problem.
Here's a general outline of the problem, and a recursive solution.
Here's a genetic algorithm solution.
Here's a simulated annealing solution.
For the collision checking itself, something like this works very well:
double assessFitness(Integer[] candidate) {
int collisions = 0;
final int MAXIMUM_COLLISIONS = calculateMaxCollisions();
for (int i = 0; i < GRID_SIZE - 1; i++) {
for (int j = i + 1; j < GRID_SIZE; j++) {
if ((candidate[i].equals(candidate[j])) || j - i == Math.abs(candidate[i] - candidate[j]))
collisions++;
}
}
return (MAXIMUM_COLLISIONS - collisions) / (double) MAXIMUM_COLLISIONS;
}
Note that this is adapted from my genetic algorithm solution. I do explain why I return a value that scales from 0 to 1 in the blog article, but in your case a slight modification would yield the result you're looking for:
int countCollisions(Integer[] candidate) {
int collisions = 0;
final int MAXIMUM_COLLISIONS = calculateMaxCollisions();
for (int i = 0; i < GRID_SIZE - 1; i++) {
for (int j = i + 1; j < GRID_SIZE; j++) {
if ((candidate[i].equals(candidate[j])) || j - i == Math.abs(candidate[i] - candidate[j]))
collisions++;
}
}
return collisions;
}
In order for this to work, you do need to calculate the maximum allowable number of collisions for your N-Queens problem.
private int calculateMaxCollisions() {
int sum = 0;
for (int i = GRID_SIZE - 1; i > 0; i--) {
sum += i;
}
return sum;
}

Java add matrix antidiagonal elements

I want to add a NxN matrix antidiagonal elements using a for loop in a java program.
This code (2 conditions) does not work because it always says when the loop is executed sum2=0.
for (int i=0,j=t-1; i<t && j==0; i++, j--) {
sum2 = sum2 + aNumber[i][j];
}
Instead this one (one condition) works well.
for (int i=0, j=t-1; i<t ; i++, j--) {
sum2 = sum2 + aNumber[i][j];
}
Why does not work the first code?
In your first example the loop ends as soon as j != 0, if t > 1 this means that it will end immediately, making no iterations at all.
Try something like this:
int maxIndex = matrix.length - 1;
int sum = 0;
for (int i = 0; i <= maxIndex; i++) {
sum += matrix[i][maxIndex - i];
}
This relies on the fact that the sum of the indexes of each antidiagonal element is exactly equal to N.

Multiple for loops in java not working properly

I'm a complete newbie when it comes to Java and I've been working on a simple program which creates a grid with multiple slots. Each slot has an X and a Y value and is stored in an ArrayList called "s".
Here's my code:
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
s.add(new Slot(j, i));
}
}
Height and width are user inputed values.
It's a simple loop within a loop and essentially it should work but instead of creating multiple slots with the values 0, 0, 1,0 2, 0 3, 0 and so forth until it should increase the Y axis by one it never increases the Y-value. Instead after doing the first loop it will go back to 0, 0 instead of 0, 1.
Also here's the how it's supposed to print the values:
for (int i = 0; i <= height; i++) {
for (int j = 0; j <= width; j++) {
System.out.print(s.get(j));
}
System.out.println("");
}
Example:
0,0
1,0
2,0
3,0
...
9,0
0,0 (instead of 0,1)
My question is why on earth doesn't my first loop ever increase the value of i? Sorry if I sound like an idiot, I'm a total noob.
You have a problem in your printing function.
I don't know what s is but:
for (int i = 0; i <= height; i++) {
for (int j = 0; j <= width; j++) {
System.out.print(s.get(j));
}
System.out.println("");
}
Get objects based on j value only. You need to get objects based on i and j in order to get all values.
Or you can just iterate over all objects in s (if s is a Collection):
for (Slot sl : s) {
System.out.println(sl);
}
The j value only ranges between 0 and width - 1 so s.get(j) is only going to access the first width items in s. Try this instead:
for (int i = 0; i <= height; i++) {
for (int j = 0; j <= width; j++) {
System.out.print(s.get(i * width + j));
}
System.out.println("");
}
Or you could just iterate over the contents of s and not use nested for loops for the retrieval.
You don't need the nested loop when printing, Just iterate over the ArrayList:
for(Slot slot : s )
{
System.out.println(slot);
}
Your problem is the print function. Just iterate over s and print each slot:
for (Slot slot : s) {
System.out.println(slot);
}
As it is implemented now, you print items in s from indexes 0 -> width over and over again, height times.
Also, learn about the for-each loop, available from Java 5 instead of using get(index):
Oracle Tutorial
The problem is you are storing height * width elements in a one dimensional array - ArrayList but retreiving only width number of elements.
Instead of arraylist of Slot for s, use two dimensional array.
Slot[][] s = new Slot[width][height];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
s[j][i](new Slot(j, i));
}
}
for (int i = 0; i <= height; i++) {
for (int j = 0; j <= width; j++) {
System.out.print(s[j][i]);
}
System.out.println("");
}
you only print j from the same place every time

Categories

Resources