Euclidean distance when similar features are slightly shifted - euclidean-distance

Let us say I want to find a similar vector for a vector
a = [0 0 2 0 0 0 0 0 0]
I have two candidates:
b1 = [0 0 0 2 0 0 0 0 0], where the "feature" is just 1 position away
b2 = [0 0 0 0 0 0 0 2 0], where the "feature" is 5 positions away
Euclidean distance for (a, b1) is the same as for (a, b2). What I want is for b1 to get a higher "similarity" score. Is there a well-known method (name it, please) to deal with such problems? Some kind of fuzzy Euclidean distance?
One possible solution I can come up with is to calculate the Euclidean distance for (a, b1) with the whole b1 shifted by 1 position left, then by 2 positions left, by 3 positions left, etc., then do the same for shifting right. Every time I do it, I adjust the calculated Euclidean position by a weight which decreases as the shifting distance increases. The same procedure is then repeated for b2. Then the results are compared to find a better match.

Look at levenstein distance. It operates on strings, to find similarity (edit distance), but when modified to use on vectors it will get you higher similarity to b1 than to b2. It could be modified to compare actual values (not just match/mismatch of character)

Related

Can we really avoid extra space when all the values are non-negative?

This question is a follow-up of another one I had asked quite a while ago:
We have been given an array of integers and another number k and we need to find the total number of continuous subarrays whose sum equals to k. For e.g., for the input: [1,1,1] and k=2, the expected output is 2.
In the accepted answer, #talex says:
PS: BTW if all values are non-negative there is better algorithm. it doesn't require extra memory.
While I didn't think much about it then, I am curious about it now. IMHO, we will require extra memory. In the event that all the input values are non-negative, our running (prefix) sum will go on increasing, and as such, sure, we don't need an unordered_map to store the frequency of a particular sum. But, we will still need extra memory (perhaps an unordered_set) to store the running (prefix) sums that we get along the way. This obviously contradicts what #talex said.
Could someone please confirm if we absolutely do need extra memory or if it could be avoided?
Thanks!
Let's start with a slightly simpler problem: all values are positive (no zeros). In this case the sub arrays can overlap, but they cannot contain one another.
I.e.: arr = 2 1 5 1 1 5 1 2, Sum = 8
2 1 5 1 1 5 1 2
|---|
|-----|
|-----|
|---|
But this situation can never occur:
* * * * * * *
|-------|
|---|
With this in mind there is algorithm that doesn't require extra space (well.. O(1) space) and has O(n) time complexity. The ideea is to have left and right indexes indicating the current sequence and the sum of the current sequence.
if the sum is k increment the counter, advance left and right
if the sum is less than k then advance right
else advance left
Now if there are zeros the intervals can contain one another, but only if the zeros are on the margins of the interval.
To adapt to non-negative numbers:
Do as above, except:
skip zeros when advancing left
if sum is k:
count consecutive zeros to the right of right, lets say zeroes_right_count
count consecutive zeros to the left of left. lets say zeroes_left_count
instead of incrementing the count as before, increase the counter by: (zeroes_left_count + 1) * (zeroes_right_count + 1)
Example:
... 7 0 0 5 1 2 0 0 0 9 ...
^ ^
left right
Here we have 2 zeroes to the left and 3 zeros to the right. This makes (2 + 1) * (3 + 1) = 12 sequences with sum 8 here:
5 1 2
5 1 2 0
5 1 2 0 0
5 1 2 0 0 0
0 5 1 2
0 5 1 2 0
0 5 1 2 0 0
0 5 1 2 0 0 0
0 0 5 1 2
0 0 5 1 2 0
0 0 5 1 2 0 0
0 0 5 1 2 0 0 0
I think this algorithm would work, using O(1) space.
We maintain two pointers to the beginning and end of the current subsequence, as well as the sum of the current subsequence. Initially, both pointers point to array[0], and the sum is obviously set to array[0].
Advance the end pointer (thus extending the subsequence to the right), and increase the sum by the value it points to, until that sum exceeds k. Then advance the start pointer (thus shrinking the subsequence from the left), and decrease the sum, until that sum gets below k. Keep doing this until the end pointer reaches the end of the array. Keep track of the number of times the sum was exactly k.

Intuition behind working with `k` to find the kth-symbol in the grammar

I took part in a coding contest wherein I encountered the following question:
On the first row, we write a 0. Now in every subsequent row, we look at the previous row and replace each occurrence of 0 with 01, and each occurrence of 1 with 10. Given row N and index K, return the K-th indexed symbol in row N. (The values of K are 1-indexed.)
While solving the question, I solved it like a level-order traversal of a tree, trying to form the new string at each level. Unfortunately, it timed-out. I then tried to think along the terms of caching the results, etc. with no luck.
One of the highly upvoted solutions is like this:
class Solution {
public:
int kthGrammar(int N, int K) {
if (N == 1) return 0;
if (K % 2 == 0) return (kthGrammar(N - 1, K / 2) == 0) ? 1 : 0;
else return (kthGrammar(N - 1, (K + 1) / 2) == 0) ? 0 : 1;
}
};
My question is simple - what is the intuition behind working with the value of K (especially, the parities of K)? (I hope to be able to identify such questions when I encounter them in future).
Thanks.
Look at the sequence recursively. In generating a new row, the first half is identical to the process you used to get the previous row, so that part of the expansion is already done. The second half is merely the same sequence inverted (0 for 1, 1 for 0). This is one classic way to generate a parity map: flip all the bits and append, representing adding a 1 to the start of each binary number. Thinking of expanding the sequence 0-3 to 0-7, we start with
00 => 0
01 => 1
10 => 1
11 => 0
We now replicate the 2-digit sequence twice: first with a leading 0, which preserves the original parity; second with a leading 1, which inverts the parity.
000 => 0
001 => 1
010 => 1
011 => 0
100 => 1
101 => 0
110 => 0
111 => 1
Is that an intuition that works for you?
Just for fun, as a different way to solve this, consider that the nth row (0-indexed) has 2^n elements in it, and a determination as to the value of the kth (0-indexed) element can be made soley according to the parity of how many bits are set in k.
The check for parity in the code you posted is just to make the division by two correct, there's no advanced math or mystery hiding here :) Since the pattern is akin to a tree, where the pattern size multiplies by two for each added row, correctly dividing points to the element's parent. The indexes in this question are said to be "1-indexed;" if the index is 2, dividing by two yields the parent index (1) in the row before; and if the index is 1, dividing (1+1) by two yields that same parent index. I'll leave it to the reader to generalize that to ks parity. After finding the parent, the code follows the rule stated in the question: if the parent is 0, the left-child must be 0 and right-child 1, and vice versa.
0
0 1
0 1 1 0
0 1 1 0 1 0 0 1
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
a a b a b b a
0 01 0110 01101001 0110100110010110
a b b a b a a b
0110100110010110 1001011001101001

Is Dilation/Erosion with fixed kernel for a number of iterations is similar to dilating/eroding with equivalent kernel of bigger size

While going through the OpenCV source code, I noticed that for iterations more than one it just creates a kernel of bigger size and do a single iteration.
So my question is if we take SQUARE structuring element of 3x3 size and dilate/erode it in three iterations, will it be same as dilating/eroding it with a 9x9 kernel once.
if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
{
anchor = Point(anchor.x*iterations, anchor.y*iterations);
kernel = getStructuringElement(MORPH_RECT,
Size(ksize.width + (iterations-1)*(ksize.width-1),
ksize.height + (iterations-1)*(ksize.height-1)),
anchor);
iterations = 1;
}
Refering to Jordi's Answer:
[Quoted] ... Note, however, that this does not hold for all structuring elements...
In fact, it holds, in the following way (not in Jordi's example):
First step, calculate the 5x5 kernel by dilation twice in 3x3 kernel on a single center point 5x5 source image:
00000 00000 00100
00000 010 00100 010 01110
00100 + 111 -> 01110 + 111 -> 11111 ===> this is the equivalent 5x5 kernel for 2x 3x3 dilation
00000 010 00100 010 01110
00000 00000 00100
Then applying twice of 3x3 original dilation kernel is equivalent to applying this 5x5 dilation kernel on a bigger image. For example:
0000000000 0000000000 00100
0000000000 010 010 0000000000 01110
0011100000 + 111 + 111 === 0011100000 + 11111
0000001000 010 010 0000001000 01110
0000000000 0000000000 00100
0000000000 0000000000
This does not directly answer your question though. However, I can not just use 'comment' as it is very hard (if not impossible) to format all these equations/explanations.
In fact, a proof for binary image (image with only value 0 or 1 in each pixel) for the larger combined kernel for dilation is easy:
Let's define the binary operator + to be the dilation operator, where the 1st operand is the kernel, and the second operand is the image to be dilated.. So, if we want to do dilation on image I with kernel K, we write dilated-image = K + I
Let's define binary operator U to be the union operator, or, in other word, the binary 'OR' operator for each pixel, where the two operand of U must be binary images in the same dimension. For example: A U B means doing -OR- on each corresponding pixel of A and B:
A= 0 0 1 B= 0 1 1
1 0 1 1 1 1
1 1 0 0 1 0
Then
A U B = 0 1 1
1 1 1
1 1 0
We also define U A(i), i=1, ..., n to be A(1) U A(2) U ... U A(n).
Let's define K^n to be the dilation-styled larger kernel by applying n times of kernel K on a single center point image.
Note that any image I, we can decompose it into union of single point images. For example,
0 1 0 0 1 0 0 0 0 0 0 0
I = 0 0 0 === 0 0 0 U 0 0 0 U 0 0 0
1 0 1 0 0 0 1 0 0 0 0 1
Now it's time to prove it:
For any image I, we define D(i), i = 1, ..., n to be the single point decomposition of I,
and thus I = U D(i), i = 1, ..., n
By definition of the binary dilation, K + I == K + (U D(i)) == U (K+D(i)).
(Remember that dilation is to mask kernel K on each pixel of I, and mark all corresponding 1's).
Now, let's see what is K + (K + I):
K + (K + I) == K + U (K + D(i))
== U(K + (K + D(i))) (Note: this is tricky. see Theorem 1 below)
== U (K^2 + D(i)) (by definition of K^2)
== K^2 + U D(i) (by definition of the dilation)
== K^2 + I (since I = U D(i))
Now, we already know K + (K + I) == K^2 + I, and it's easy to apply mathematical induction to prove that K + K + K .. + K + I = K^n + I (Note: please apply right association, as I have drop the parenthesis).
Theorem 1: Proof of the deduction from K + U (K + D(i)) to U(K + (K+D(i)))
It's suffice to just prove that for any two binary images A and B in a same dimension,
K + (A U B) = (K+A) U (K+B)
It's quite easy to see that, if we decompose image A and B, and apply kernel K on the decomposed images, those common points (i.e. the intersection points of A and B, or the common 1's point of A and B), will contribute the same resulting points after applying kernel K. And by the definition of dilation, we need to union all points contributed by each decomposed image of A and B. Thus Theorem 1 holds.
=== UPDATE ===
Regarding to kid.abr's comment "27 operations compared to 7x7 kernel with 49 operations":
Generally speaking, it is not 27 operations. It depends. For example, a source image of 100x100 pixels,
with 20 singular point (1's) sparsely distributed. Applying a 3x3 solid kernel (i.e. All 1's) 3 times on it
requires the following steps for each of the 20 singular point:
Loop 1: 9 operations, and generate 9 points.
Loop 2: For each of the 9 points generated, it needs 9 operations => 9 x 9 = 81 steps. And it generates 25 points
Loop 3: For each of the 25 points generated, it needs 9 operations => 25 x 9 = 225 steps.
Total: 9 + 81 + 225 = 315 steps.
Please note that when we visit a pixel with 0 value in the source image, we don't need to apply the kernel
on that point, right?
So, the same case applying the larger kernel, it requires 7x7 = 49 steps.
Yet, if the source image has a large solid area of 1's, the 3-step method wins.
Short answer: with a square structuring element, yes.
Long answer: you need to consider what the erosion/dilation operations do. Dilation, for instance, moves the kernel over the image and sets its centre to 1 whenever any of its grid positions are 1 (I'm assuming binary images, it works the same for greyscale). Increasing the distance between the centre of the structuring element and its edges is then the same as increasing the size of the kernel.
Note, however, that this does not hold for all structuring elements. Suppose you take a structuring element that is just a stretched plus, obviously dilating twice with size 3 is not the same as dilating once with size 5:
00000 00000 00100
00000 010 00100 010 01110
00100 + 111 -> 01110 + 111 -> 11111
00000 010 00100 010 01110
00000 00000 00100
00000 00100 00100
00000 00100 00100
00100 + 11111 -> 11111
00000 00100 00100
00000 00100 00100
Of course, this does work if we define the scaled version of plus as a square without its corners (as it usually would be). I think that in general this shortcut works when the kernel of size k+1 is the dilated version of the kernel of size k, but I have no proof for this.
Short answer for a general kernel: Yes for dilation/erosion, but not necessarily with an equivalent kernel.
From wikipedia:
Dilation: (A⊕B)⊕C = A⊕(B⊕C)
Erosion: (A⊖B)⊖C = A⊖(B⊕C)
Where ⊕ denotes the morphological dilation, and ⊖ denotes the morphological erosion.
Basically, performing erosion/dilation on image A with kernel B and then kernel C is equivalent to performing erosion/dilation on image A with the kernel obtained by dilating B with C. This can easily be expanded to an arbitrary number erosions/dilations.

Explore a matrix using Chebyshev distance

What is the fastest way of exploring an array from a point (i,j) , using Chebysev distance?
My aproach:
I am currently defining 2 one dimensional arrays that store the directions for the start then compute with a For what is left when radius > 1 ( radius is the "radius" of the chebysev circle I wanna explore the array) . I am finding I am exploring some elements twice . Is there an algorithm that shows what is the best aproach ?
Be 0 the distance between (i,j) and himself . I would want the matrix to be explored like this ( the numbers represent the distance between i,j and them). Ofcourse i,j is not always it the middle , it must be any point I choose .
2 2 2 2 2
2 1 1 1 2
2 1 0 1 2
2 1 1 1 2
2 2 2 2 2
Thank you and excuse my english :)
You can use the BFS algorithm. It is just a simple loop with a queue.
Your "edges" on are links between the position (i, j) and its 8 neighbors:
(i-1,j)
(i-1,j-1)
...
(i+1,j+1)

algorithm transfer one coin matrix to another coin matrix

Description:
There are m * n (m <= 100, n <=100) coins on the desktop forming a m row n column coin matrix. Every coin either face upward, or face backward, represented by 0 or 1.
Rules of the game are:
(1) every time, you are allowed to inverse one row of coins.
(2) every time, you are allowed to swap two columns.
Object:
from initial matrix -> target matrix
Input:
1. k the count of test caese
2. m n the count of rows and columns
3. the numbers of the inital matrix and the target matrix
Output
the least steps from initial matrix to target matrix, if it is not possible to transfer from initial to target, output -1.
sample intput
2
4 3
1 0 1
0 0 0
1 1 0
1 0 1
1 0 1
1 1 1
0 1 1
1 0 1
4 3
1 0 1
0 0 0
1 0 0
1 1 1
1 1 0
1 1 1
0 1 1
1 0 1
sample output
2
-1
I have coded one solution: mysolution.cc, which enumerate all posibilities and which is correct but it is too slow, could you provide a correct but fast solution.
Thanks.
The rows always stay in the same place, so if row r starts with k ones, it will always have either k ones or columns - k.
for each row, check if count_of_ones(initial,row) == count_of_ones(target,row), if yes, fine, else check if count_of_ones(initial,row) = columns - count_of_ones(target,row), if so, flip row, else output -1. As #maniek pointed out, it's not so easy when exactly half of the columns contain ones. Such rows would have to be treated in step 2 to try and form the required columns.
for each column, count the number of ones int the target and the working matrix (after flipping rows as appropriate). If the sequences of counts are not permutations of each other, output -1, otherwise try to find a permutation of columns that transforms working to target (any columns identical between working and target have to be kept fixed). If not possible, output -1, otherwise find minimum number of swaps necessary to achieve that permutation.
I will give you some thoughts. You compare row by row. If the i-th row of the first matrix has the same number of 1 as in the i-th row of the second matrix - then you don't inverse. If the i-th row of the first matrix has the same number of 1 as the 0 in the i-th row of the second matrix - then you must inverse. If neither of this is true, then there is no solution. This is all about inversing.
Now all columns are equal but in a different order(the second matrix has permuted columns from the first matrix). If the columns are not permutation of each other - return -1. This problem is equal to find the minimum number of swaps to convert a one permutation to other.