1d array of unique distances between points - java

I'm coding an N-body simulator with planets (points). I've got it working but there are still a lot of possible optimizations, one of them is to calculate distances between points once and store them in an array. I could use a 2d array (needed to be converted to 1d because the GPU doesn't support 2d arrays) but there are two problems:
The simulation would be limited to √2147483647 (max integer value) planets = 46340 planets since the size of the array would be n^2 (n is the number of planets)
A lot of the distances would be repeated (distance between 0 and 1 is the same as distance between 1 and 0)
To get the amount of unique connections the formula is: D = (n*(n-1))/2
But now I've got a problem: how to get an index in the distances array given two planet id-s (x,y). The distance index between planet 0 and 1 is 0, 0-2 -> 1, 1-2 -> 2...

To help visualize what this looks like, here is a table showing which index (in the 1D array) corresponds to each pair of planet ids. To use this table, given a pair of planet ids, find the row that corresponds to the larger of the two ids, and the column that corresponds to the smaller of the two ids, and that will give you the cell with the index of where that distance is stored in your 1D array.
So, now we need a formula that is given two planet ids and computes the 1D index number. For simplicity, we will assume that the larger planet id is given first. (If not, then we can simply swap the two planet ids.)
The first job is to take the larger planet id and determine the first index on its row. In other words, we need to convert 1 to 0, 2 to 1, 3 to 3, 4 to 6, 5 to 10, 6 to 15, etc. Luckily, the pattern 0,1,3,6,10,15 is well known - it is the triangular numbers. The usual formula for the Nth triangular number is (n*(n+1))/2 but in this case we actually want the N-1th triangular number, so the formula we want is (n*(n-1))/2.
Once we have the first index of the row, we can just add the smaller planet id to get the final index.
So, our final formula is:
given A (larger planet id) and B (smaller planet id):
the index of dist(A,B) in the 1D array is ((A * (A-1)) / 2) + B

Related

Optimal Edge Weights

There is a state (territory) which is a tree rooted at node 1. All the cities (numbered from 1 to N+1)
in this state are connected via bidirectional roads. You have to add toll tax on each road. There are N roads which connect the cities of the state. You have to assign toll taxes on the roads so as to maximize the function Toll described below:
for(i=1;i<=number of cities;i++)
{
for(j=i+1;j<=number of cities;j++)
{
toll+=(toll required to pay to travel from i to j)
}
}
You have to maximize the toll tax. Assign the roads by toll taxes from the given array A(using each value exactly once). Find the maximum toll obtained.
Input Format:
First line contains
N and an integer whose value is always 2.
Then,
N roads follow containing 2 integers u and v, denoting the cities
between which the road is.
Next line contains N space separated values denoting elements of array A.
Output Format
Print the maximum toll which can be obtained.
Input Constraints
1≤N≤2∗10^5
1≤A[i]≤1000
1≤u,v≤N+1
Sample Input
2 2
1 3
2 3
5 7
Sample Output
24
Explanation
Assign 5 to edge (1- 3) and 7 to edge (2 - 3). This leads to an maximum toll tax of 24.
First, when you look at your Toll function code and Sample Input, then you'll see that this function counts just paths:
from 1 to 3
from 2 to 3
but not 3 to 1
and not 3 to 2,
because j is always more than i, so this leads us that 24 is incorrect answer (or you have incorrect Toll) function.
Second, according to the task (but I believe it just was described wrong) the answer will be always equal to sum of elements from array A, because the task sounds like : put elements to a symmetric matrix and then calculate a sum above (or below) a diagonal, but it is going to be all of the same elements from array A.
The Question you asked belongs to Graph.
Three cities are given from 1 -> 3. If you randomly assign values from A[] and use that in the toll function you will get the following output:
Assume you assigned 5 to Edge 1-3, and 7 to edge 2-3,
The graph would be like 1------3------2
Then According to the toll function, you will get the following routes:
1-2 === 7 + 5 = 12
1-3 === 5
2-3 === 7
So , the total toll would be = 12+5+7 = 24.
Hence, you need to first construct the graph . then assign the tolls randomly and find toll money for all the possible combinations.
or else,
you can use concept of Minimum Spanning Tree for Graph. You just need to inverse the use of kruskal or Prim's algorithm to find a route with maximum toll
PS: The meaning of bi-directional road is that suppose your first for loop starts from 3 and second for loop starts from 1, then you can also go 3->1 whose toll would be same as you used before for 1->3.
Hope this helps. :)

Return integer index of 1D array for 2D array of coordinates pairs

After reading 10+ threads about converting an entire array from 2D to 1D and vice versa, I'm wondering if there is a mathematical formula, requiring no iteration to return the index position of a pair of integers for a sorted 2D array.
My "grid" is always square, can be any size (it's 3x3 in this example), and I've got a sorted block of human friendly values from which I need to retrieve what I'm calling "True 1D indices" like this:
"Human-friendly" coordinates| Java 2D Indices | True 1D indices
[1,1],[1,2],[1,3], ==> [0,0],[0,1],[0,2], ==> 0 , 1 , 2
[2,1],[2,2],[2,3], ==> [1,0],[1,1],[1,2], ==> 3 , 4 , 5
[3,1],[3,2],[3,3], ==> [2,0],[2,1],[2,2], ==> 6 , 7 , 8
So I need a method for my class to give me the following results:
I enter 1,1 and get back 0,
I enter 3,2 and get back 7,
I enter 2,3 and get back 5,
etc etc...
I've played around with half a dozen equations where I try things like adding the coordinates to the previous row index squared, and I can never get the right result for every cell in the grid. Is there some special operator or Math function I'm missing?
Thanks.
let the matrix be of 3*3 ,3 rows and 3 column and we have to find the indices of (i,j) then the formula will be.
indices= 3*(i-1)+j;
Note :- here 3*3 and i,j are not it java 2d array format it is in human friendly coordinates.
Example (i,j)=(2,3)
indices=3*(2-1)+3 =6
And since your indices starts from 0 you could simply subtract one from 6 i.e. 5.
If the indices are named [index1,index2],
1DIndex = (rowNumber*index1) + index2
Where rowNumber starts at 1 for the first row, and index1 and index2 are the Java indices.

Algorithm to implement the BINGO game

For those who doesn't know a BINGO game, its played as follows
1)You get a BINGO card in which there is a NXN matrix of numbers randomly printed.Numbers are unique.The max number printed can be greater than N^2. e.g. if you have 5x5 matrix then the max number can be 75 as well.But the range of numbers is pre-decided say 1 to M.
2)A person speaks out numbers randomly in the range 1 to M.
3)If the number is on your card you cross the number.
4)The process of crossing numbers is repeated.When you have crossed a full row or a full column or the two diagonals,then you get your first bingo
The game is still continued as the total BINGOs possible are N+N+2 for N rows,N columns and 2 diagonals.
Now I want to create an algorithm for it.The user will input random numbers and the algorithm will hear them and cross its numbers in the matrix(already provided).As soon as it gets BINGO it declares it.What is the best possible approach
I tried it as maintaining a 2-D matrix for the card
When a number is announced, i search it in O(NxN) time.When I find it ,I make it as 0.
After making it as 0, I search whether it the corresponding row & column has now all zeroes.If it was on the diagonal , I also search for the diagonal.It takes O(3N) time.
Any better approach?
You can form a map for each number that would map to a pair (row, column).
if ( myMap[number] exists ) {
then increment rowCount[ myMap[number].row ];
then increment columnCount[ myMap[number].column ];
}
if ( rowCount[myMap[number].row] == N ) { bingo! }
if ( columnCount[myMap[number].column] == N ) { bingo! }
myMap.erase( number );
Similarly for diagonals.
Use an array to store the numbers on the card and keep it sorted. Upon number being called, search the number using Binary Search (O(logN) time). This should be a quick approach.
Create a class Coordinate that holds x and y position in bingo card.
NxN array of booleans initialized to false to keep track of what gets crossed off on bingo card.
N^2 time to iterate through bingo card and add each number to hash table using the number as the key and a new Coordinate as the value.
n time to iterate through all the numbers that will be called out, retrieve the Coordinate from the hash table, and update the status of the boolean array. In case of duplicate numbers called, you must retrieve and update boolean array until the hash table does not contain the key.
4N time to check each direction on boolean array for first bingo
N^2 + n*4N total runtime

Representing a carbon molecule in the form of a matrix

how to generate all possible combinations of a 14x10 matrix containing only 1's and 0's
Hello. While searching for what i wanted i found the above URL to be something useful, but not exactly helpful to my particular problem.
What i'm looking for is a way to find all possible permutations of the numbers 1 and 0 in an n dimensional square matrix. I realise that the number of such matrices will be very large and the computation time will be immense.
Hence, I wish to impose the following restrictions on the matrix.
1) The matrix should be reduced in size to an upper triangular matrix.
2) Each column must have atleast one '1'
3) The number of 1's in the matrix must be equal to or less than n- the dimension of the square matrix.
4)The total 1's in a particular column must be less than or equal to 4.
the reason i'm looking for such a code is so that i can represent a carbon molecule in the form of a matrix with each column representing one atom and each element representing a bond (1) or no bond (0) between the carbon atoms( one in the column and one in the corresponding row)
for example
X 1 0 0;
X X 1 0;
X X X 1;
X X X X
where the X shows that the matrix is now only an upper triangular matrix to avoid redundancies
the rows separated by ';' and each column entry is separated by a space.
the above example shows one particular combination of 0's and 1's. what i'm looking for is a code that will give all possible combinations.
thank you.

Homework in Java. Find the largest product of five consecutive digits

We have started learning Java in school, and we have been given a few homeworks to do. I've managed to do 4 out of 5, but this last one is a real pain.
Basicly: Write a program that finds (in a 1000 places long number) the largest product of five
consecutive digits.
Here's the number http://pastebin.com/PFgL6jcM
Do you have any ideas how to solve this ?
If this are unclear instruction, notify me and will try to explain to you again.
The most naive approach is to just use a sort of "sliding window" over the number. Window is of size 5 and you keep track of the maximum number:
the window starts with the first 5 digits
multiply the 5 digits in the window and compare to the current max. If larger, update the current max, and probably store the index as well if you want to track which numbers were just to retrieve that max
shift the window one digit and start from top
A possible optimization which immediately comes to mind is that you can skip the second step if the window contains a zero. Even better, you can immediately shift the window until the first digit behind the zero.
I'd say an optimized algorithm would look like this:
1) grab first five numbers
2) if current set contains a 0, grab the first five numbers after the 0. Do this until you reach a set that doesn't contain a 0. (if all sets contain a 0 - unlikely - return 0).
3) compute the product of the 5 numbers ( x1, x2, x3, x4, x5 ) like so:
p1 = x5 * x4
p2 = x3 * p1
p3 = x2 * p2
p = x1 * p3
4) if p is greater than the previous p, store it.
5) discard the first number and add the next one (x6).
p = x6 * p3
6) if the new p is greater than the old one, go to step 3)
You're reducing the number of multiplications by a factor of 5, since you won't keep multiplying 5 numbers, but 2.
Remember to discard sequences that contain a 0 and try to optimize the algorithm along these lines.
Assuming that by consecutive, you mean 5 digits out of the large number you've provided.
You will want to loop through each of the characters in the number one at a time, grab the next four digits after it, find the product. If it's higher than the last product, store it and the 5 digit combination, then move to the next digit until you've processed all of the digits.
Convert the number to a String;
Convert the String to an array of characters;
Convert the character array to an integer array;
Set a value to 0;
Loop though each integer until the 5th to last character;
(in loop) Multiply that integer with the next 4 integers in the array;
(in loop) If the result is greater than the value you're holding onto then replace it with the product of the 5 numbers;
(end of the loop)
I'm not writing it out for you... it's your homework ;)

Categories