Faster way to find the closest pair of points - performance

I'm trying to compare all elements of an array to each other. I can do it with nested loops but it's a very inefficient algorithm and I can tell it's not the right way to do it. Here's what I'm doing right now.
PER answers below I've changed this code and I'm expanding on the question.
// Point from java.awt.Point;
private static void findShortestDistance(Point[] pt) {
ArrayList<Double> distance = new ArrayList<Double>(1000);
for(int i=0; i<pt.length; i++) {
for(int j=i+1; j<pt.length; j++) {
double tmp = pt[i].distance(pt[j]);
distance.add(tmp);
}
}
double min = distance.get(0);
for(Double d : distance) {
if(d < min) { min = d; }
}
}
There's the full code for the method I have so far. I'm trying to find the shortest distance between two points in the given array.

Have a look at wikipedia.
http://en.wikipedia.org/wiki/Closest_pair_of_points
And this question seems to be the same as
Shortest distance between points algorithm

As long as you say the above code is exactly what you want the following will be the implementation you want:
for(int i=0; i<pt.length; i++) {
for(int j = i + 1; j<pt.length; j++) {
/* do stuff */
}
}
However, I have a god feeling you are actually interested in comparing the array values or am I wrong?

for(int i=0; i<pt.length; i++) {
for(int j=i+1; j<pt.length; j++) {
if(pt[i] != pt[j]) { /* do stuff */ }
}
}

for(int i=0; i<pt.length; i++) {
for(int j=i; j--; ) {
{ /* do stuff */ }
}
}
And, for completeness:
for(int i=pt.length; i--; ) {
for(int j=i; j--; ) {
{ /* do stuff */ }
}
}

Initializing j to i+1 will skip the redundant comparisons.
for(int i = 0; i < pt.length; i++) {
for(int j = i + 1; j < pt.length; j++) {
if(pt[i] != pt[j]) { /* do stuff */ }
}
}
(BTW, changed the if-statement, assuming you meant to use i and j as indexes into an array.)
That's about the best you can get for the most basic case where you need to get a cross product of the array with itself, minus all the elements {x, y} | x == y. (i.e. an exhaustive list of unordered pairs of differing elements.) If you need ordered pairs of differing elements, then your code is best.

Related

Dynamic programming--Longest Common Substring: Understanding the space optimization

I am working through a ver typical question which is the Longest Common Substring of two strings.
The problem statement is quite clear:
for two string s1 and s2, find the length of their longest common substring.
I can understand the definition of the state represented by the dp array. It is a two-dimension array where two dimension just represents the index of the characters in each string(but just 1 based not 0 based).
The original solution code is like below which appears clear to me :
public int findLCSLength(String s1, String s2) {
int[][] dp = new int[s1.length()+1][s2.length()+1];
int maxLength = 0;
for(int i=1; i <= s1.length(); i++) {
for(int j=1; j <= s2.length(); j++) {
if(s1.charAt(i-1) == s2.charAt(j-1)) {
dp[i][j] = 1 + dp[i-1][j-1];
maxLength = Math.max(maxLength, dp[i][j]);
}
}
}
return maxLength;
}
This solution obviously can be optimized since the state of dp[i][j] just depends on the previous row which means two row will be sufficent for the dp array.
So I made the dp array a two-dimension one and use the mod operation to map the indexes in the range of 2.
static int findLCSLength(String s1, String s2) {
int[][] dp = new int[2][s2.length()+1];
int maxLength = 0;
for(int i=1; i <= s1.length(); i++) {
for(int j=1; j <= s2.length(); j++) {
if(s1.charAt(i-1) == s2.charAt(j-1)) {
dp[i%2][j] = 1 + dp[(i-1)%2][j-1];
maxLength = Math.max(maxLength, dp[i%2][j]);
}
}
}
return maxLength;
}
However my code didn't produce the correct answer for all test cases. I found one code snippet which gives correct answer on all test cases which has only one extra operation as I missed.
static int findLCSLength(String s1, String s2) {
int[][] dp = new int[2][s2.length()+1];
int maxLength = 0;
for(int i=1; i <= s1.length(); i++) {
for(int j=1; j <= s2.length(); j++) {
//This is the only extra line I missed
dp[i%2][j] = 0;
if(s1.charAt(i-1) == s2.charAt(j-1)) {
dp[i%2][j] = 1 + dp[(i-1)%2][j-1];
maxLength = Math.max(maxLength, dp[i%2][j]);
}
}
}
return maxLength;
}
One of the cases that my code fails is "passport" and "ppsspt", where my code produced 4 but the correct answer is obviously 3.
I am confused but this line , what does this line do and why it is necessary?
Hope anyone can help on that.
It resets the current count.
Your code sets this variable when:
if(s1.charAt(i-1) == s2.charAt(j-1)) {
But there's no else to set it to 0, which is effectively what that code does.
So consider when:
s1.charAt(i-1) != s2.charAt(j-1)
The previous value that you had in this array location will carry over to the next sub-string comparison when it shouldn't.

Sort an array of numbers into ascending order and find the position of a number within the list

I have produced an unsorted array of values of which I would like to put into an ascending order and determine the new position of the last number.
I have previously attempted successfully at other smaller input but got stuck on the last one where the the list consists of 1824300 values and the terminal just wouldn't run the sorting algorithm at all...
#include <stdio.h>
int main(void)
{
signed value = 16239, num = 1824300, i, j;
signed temp;
signed arr[num];
arr[0] = value;
printf("Your initial array is:\n");
printf("%i\n", arr[0]);
for (i = 1; i < num; i++)
{
value = (value*31334)%31337;
arr[i]= value;
printf("%i: ", i);
printf("%i\n", arr[i]);
}
// Insertion sort
for(i = 1; i < num; i++)
{
j = i;
temp = arr[j];
while((j > 0) && (arr[j - 1] > temp))
{
arr[j] = arr[j -1];
arr[j - 1] = temp;
j--;
}
}
insertion sort //
printf("Your sorted array is:\n");
for(i = 0; i < num; i++)
{
printf("%i: ", i);
printf("%i\n", arr[i]);
}
return 0;
}
Can someone please help me on it?
P.S. I am completely new to programming so my code might be very inefficient and messy so sorry about that!!
Thanks a lot!!!
So basically below is what I did at the end. I just inserted a simple counter! and it worked fine... Thank you for everyone who tried to help. Your answers are valuable to me and I am still learning how to implement the algorithms into codes which is a bit difficult for me since I have no programming experience before :((( The algorithms are not tricky to understand at all though...
signed count;
count = 0;
for (i = 0; i < num; i++)
{
if (arr[i] <= value)
{
count = count + 1;
}
}
printf("This is the index of your output in a sorted list: \n");
printf("%i\n", count);

The fastest algorithm for returning max length of consecutive same value fields of matrix?

Here is the given example:
We have the function which takes one matrix and it's number of columns and it's number of rows and returns int (this is gonna be length). For example:
int function (int** matrix, int n, int m)
The question is what's the fastest algorithm for implementing this function so it returns the maximum length of consecutive fields with the same value (doesn't matter if those same values are in one column or in one row, in this example on picture it's the 5 fields of one column with value 8)?
Values can be from 0-255 (grayscale for example).
So in the given example function should return 5.
If this is a bottleneck and the matrix is large, the first optimization to try is to make one pass over the matrix in sequential memory order (row-by-row in C or C++) rather than two. This is because it's very expensive to traverse a 2d array in the other direction. Cache and paging behavior are the worst possible.
For this you will need a row-sized array to track the number of consecutive values in the current run within each column.
int function (int a[][], int m, int n) {
if (n <= 0 || m <= 0) return 0;
int longest_run_len = 1; // Accumulator for the return value.
int current_col_run_len[n]; // Accumulators for each column
int current_row_run_len = 1; // Accumulator for the current row.
// Initialize the column accumulators and check the first row.
current_col_run_len[0] = 1;
for (int j = 1; j < n; j++) {
current_col_run_len[j] = 1;
if (a[0][j] == a[0][j-1]) {
if (++current_row_run_len > longest_run_len)
longest_run_len = current_row_run_len;
} else current_row_run_len = 1;
}
// Now the rest of the rows...
for (int i = 1; i < m; i++) {
// First column:
if (a[i][0] == a[i-1][0]) {
if (++current_col_run_len[0] > longest_run_len)
longest_run_len = current_col_run_len[0];
} else current_col_run_len[0] = 1;
// Other columns.
current_row_run_len = 1;
for (int j = 1; j < n; j++) {
if (a[i][j] == a[i][j-1]) {
if (++current_row_run_len > longest_run_len)
longest_run_len = current_row_run_len;
} else current_row_run_len = 1;
if (a[i][j] == a[i-1][j]) {
if (++current_col_run_len[j] > longest_run_len)
longest_run_len = current_col_run_len[j];
} else current_col_run_len[j] = 1;
}
}
return longest_run_len;
}
You need to pass over each entry of the matrix at least once, so you can't possible do better than O(m*n).
The most straightforward way is to pass over each row and each column once. This will be two passes over the matrix, but the algorithm is still O(m*n).
Any attempt to do it in one pass will probably be a lot more complex.
int function (int** matrix, int n, int m) {
int best=1;
for (int i=0; i<m; ++i) {
int k=1;
int last=-1;
for (int j=0; j<n; ++j) {
if (matrix[i][j] == last) {
k++;
if (k > best) {
best=k;
}
}
else {
k=1;
}
last = matrix[i][j];
}
}
for (int j=0; j<n; ++j) {
int k=1;
int last=-1;
for (int i=0; i<m; ++i) {
if (matrix[i][j] == last) {
k++;
if (k > best) {
best=k;
}
}
else {
k=1;
}
last = matrix[i][j];
}
}
return best;
}

Bubble Sort using Bubble Up

Given the algorithm for Bubble Sort:
Algorithm BubbleSort(A[0...n]):
for i <- 0 to n-2 do
for j <- 0 to n-2-i do
if(A[j+1] < A[j] then swap(A[j], A[j+1]))
I have to rewrite the Bubble Sort algorithm using where we "Bubble Up" the smallest element to the ith position on the ith pass through the list.
Can anyone help me with this?
Currently you are traversing the array from the start, therefore if you come upon the largest element, it will be "Bubbled up" to the end of the array. If you want to do the opposite, "Bubbling down" the smallest element to the start, you need to traverse the array in the opposite direction, from the end to the start. Hope it helps you to find the way.
#include<stdio.h>
void bubbleSort(int *x,int size)
{
int e,f,m,g;
m=size-2;
while(m>0)
{
e=0;
f=1;
while(e<=m)
{
if(x[f]<x[e])
{
g=x[e]; //swaping
x[e]=x[f];
x[f]=g;
}
e++;
f++;
}
m--;
}
}
void main()
{
int x[10],y;
for(y=0;y<=9;y++) //loop to insert 10 numbers into an array
{
printf("Enter a number: ");
scanf("%d",&x[y]);
}
bubbleSort(x,10); //pass number entered by user and size of array to bubbleSort
for(y=0;y<=9;y++) //loop to print sorted numbers
{
printf("%d\n",x[y]);
}
}
Looks like the answer to this has not been accepted yet. Hence trying to check if this is still an issue.
Here is what I think can be a possible implementation in Java. As #Warlord mentioned, the algorithm is to ensure that the array in concern for sorting is imagined as a vertical array. With each pass, all we are doing is check if there is a larger element below and if found that element is bubbled up to the top.
static void bubbleUpSort(int[] arr){
final int N = arr.length;
int tmp = 0;
for (int i=0; i < N; i++){
for (int j=N-1; j >= i+1; j--){
if (arr[j] < arr[j-1]){
tmp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = tmp;
}
}
}
for (int k =0; k < arr.length; k++){
System.out.print(arr[k] + " ");
}
}
Called from main as:
public static void main(String[] args) {
System.out.println("Bubble Up Sort");
int[] bUp = {19, 2, 9, 4, 7, 12, 13, 3, 6};
bubbleUpSort(bUp);
}
Bubble Sort
Comparing each with the neighbor and swapping if first is greater than the next
function bubbleSort(arr){
let temp;
console.log("Input Array");
console.log(arr);
for (let i = 0; i < arr.length-1; i++) {
for (let j = 0; j < arr.length-i-1; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
console.log(arr[j],"swapped with",arr[j+1])
console.log(arr);
} else {
console.log("SKIP");
}
}
}
console.log("Sorted using Bubble Sort");
return arr;
}
console.log(bubbleSort([7,6,9,8,2,1,4,3,5]));

K-Server Dynamic Algorithm

I’m trying to get optimal solution for K-server problem for 3 servers using dynamic algorithm.
The idea is to generate all possible permutation and check them all to find the optimum value.
I understand it’s a slow exhaust search algorithm with exponential time big O.
Anyway, this is what I have, as far as I understand it should work, but it gives me false value.
here first 3 points are the servers. And dist(x,y) function calculate Cartesian distance of the points x-th and y-th.
void optimalSol()
{
int cost[10][10][10][10];
for(int l=3; l<=totalPoints; l++)
{
for(int i=0; i<=l; i++)
{
for(int j=0; j<=l; j++)
{
for(int k=0; k<=l; k++)
{
int current_min=99999;
//cost[i][j][k][l]=0;
if((i!=l) && (j!=l) && (k!=l))
cost[i][j][k][l]=99999;
else
{
for(int m=0; m<=l; m++)
{
if(current_min > (cost[m][j][k][l-1] + dist(m, i)))
{
if(cost[m][j][k][l-1] + dist(m, i)>0)
current_min = cost[m][j][k][l-1] + dist(m, i);
}
else if(current_min > (cost[i][m][k][l-1] + dist(m,j)))
{
if(cost[i][m][k][l-1] + dist(m,j)>0)
current_min = cost[i][m][k][l-1] + dist(m,j);
}
else if(current_min > (cost[i][j][m][l-1] + dist(m,k)))
{
if(cost[i][j][m][l-1] + dist(m,k)>0)
current_min = cost[i][j][m][l-1] + dist(m,k);
}
}
cost[i][j][k][l] = current_min;
}
}
}
}
}
printCostTable(cost);
}

Resources