Order a matrix of values based on gradient - algorithm

The goal is to visualize a matrix of values 'nicely'. The matrix looks like
a b c
A 2 3 1
B 5 6 7
C 2 9 5
We've two sets {A} and {a}, that have no predefined order. We've also a measure value for each combination M(A,a) = Number.
We would like show the values in a 'nice' way by sorting these values for both sets. We want in the bottom left the smaller values and in the top right the biggest values.
So, for each Matrix of measures M we can define a function that is based on the gradient. For each possible order of set {A} and {a} we define the gradient as :
Gradient(i,j) = F(M(i+1,j) - M(i,j)) + F(M(i,j+1) - M(i,j))
where F(x) = x if x >0 and F(x) = 2*x if x < 0 as we want to go 'up'
Gradient( M(A,a) ) - Sum( Gradient(i,j), for all i,j except the top and right border )
The 'nice' order is the one where we've (indeed not guarantee it's unique). The value of 2 in the F(x) function is arbitrary but the goal is to give more negative weight to the gradiants that go down. If somebody has a better idea welcomed.
Max( Gradient )
Besides doing all combinations that is a terrible algorithm O(n^4), is there a better solution? Some formal ideas about this problem?

Related

How to solve SPOJ : SCALE using binary search?

http://www.spoj.com/problems/SCALE/
I am trying to do it using recursion but getting TLE.
The tags of the problem say BINARY SEARCH.
How can one do it using binary search ?
Thanx in advance.
First thing to notice here is that if you had two weights of each size instead of one, then the problem would be quite trivial, as we we would only need to represent X in its base 3 representation and take corresponding number of weights. For, example if X=21 then we could take two times P_3 and one time P_2, and put those into another scale.
Now let's try to make something similar using the fact that we can add to both scales (including the one where X is placed):
Assume that X <= P_1+P_2+...+P_n, that would mean that X <= P_n + (P_n-1)/2 (easy to understand why). Therefore, X + P_(n-1) + P_(n-2)+...+P_1 < 2*P_n.
(*) What that means is that if we add some of the weights from 1 to n-1 to same scale as X, then the number on that scale still does
not have 2 in its n-th rightmost digit (either 0 or 1).
From now on assume that digit means a digit of a number in its base-3 representation (but it can temporarily become larger than 2 :P ). Now lets denote the total weight of first scale (where X is placed) as A=X and the other scale is B=0 and our goal is to make them equal (both A and B will change as we will make our progress) .
Let's iterate through all digits of the A from smallest to largest (leftmost). If the current digit index is i and it:
Equals to 0 then just ignore and proceed further
Equals to 1 then we place weight P_i=3^(i-1) on scale B.
Equals to 2 then we add P_i=3^(i-1) to scale A. Note that it would result in the increase of the digit (i+1).
Equals to 3 (yes this case is possible, if both current and previous digit were 2) add 1 to digit at index i+1 and go further (no weights are added to any scale).
Due to (*) obviously the procedure will run correctly (as the last digit will be equal to 1 in A), as we will choose only one weight from the set and place them correctly, and obviously the numbers A and B will be equal after the procedure is complete.
Now second case X > P_1+P_2+...+P_n. Obviously we cannot balance even if we place all weights on the second scale.
This completes the proof and shows when it is possible and the way how to place the weights to both scales to equalise them.
EDIT:
C++ code which I successfully submitted on SPOJ just now https://ideone.com/tbB7Ve
The solution to this problem is quite trivial. The idea is the same as #Yerken's answer, but expressed in a bit different way:
Only the first weight has a mass not divisible by 3. So the first weight is the only one has effect on balancing mod 3 property of the 2 scales:
If X mod 3 == 0, the first weight must not be used
If X mod 3 == 1, the first weight must be on scale B (the currently empty one)
If X mod 3 == 2, the first weight must be on scale A
Subtract both scales by weight(B) --> solution doesn't change, and now weight(A) is divisible by 3 while weight(B) == 0
Set X' = weight(A)/3 and divide every weights Pi by 3 ==> Solution doesn't change, and now it's the same problem with N' = N-1 and X' = (X+1)/3
pseudo-code:
listA <- empty
listB <- empty
for i = 1 to N {
if (X == 0) break for loop; // done!
if (X mod 3 == 1) then push i to listB;
if (X mod 3 == 2) then push i to listA;
X = (X + 1)/3; // integer division
}
hasSolution <- (X == 0)
C++ code: http://ideone.com/LXLGmE

Towers of Hanoi - Bellman equation solution

I have to implement an algorithm that solves the Towers of Hanoi game for k pods and d rings in a limited number of moves (let's say 4 pods, 10 rings, 50 moves for example) using Bellman dynamic programming equation (if the problem is solvable of course).
Now, I understand the logic behind the equation:
where V^T is the objective function at time T, a^0 is the action at time 0, x^0 is the starting configuration, H_0 is cumulative gain f(x^0, a^0)=x^1.
The cardinality of the state space is $k^d$ and I get that a good representation for a state is a number in base k: d digits that can go from 0 to k-1. Each digit represents a ring and the digit can go from 0 to k-1, that are the labels of the k rings.
I want to minimize the number of moves for going from the initial configuration (10 rings on the first pod) to the end one (10 rings on the last pod).
What I don't get is: how do I write my objective function?
The first you need to do is choose a reward function H_t(s,a) which will define you goal. Once this function is chosen, the (optimal) value function is defined and all you have to do is compute it.
The idea of dynamic programming for the Bellman equation is that you should compute V_t(s) bottom-up: you start with t=T, then t=T-1 and so on until t=0.
The initial case is simply given by:
V_T(s) = 0, ∀s
You can compute V_{T-1}(x) ∀x from V_T:
V_{T-1}(x) = max_a [ H_{T-1}(x,a) ]
Then you can compute V_{T-2}(x) ∀s from V_{T-1}:
V_{T-2}(x) = max_a [ H_{T-2}(x,a) + V_{T-1}(f(x,a)) ]
And you keep on computing V_{t-1}(x) ∀s from V_{t}:
V_{t-1}(x) = max_a [ H_{t-1}(x,a) + V_{t}(f(x,a)) ]
until you reach V_0.
Which gives the algorithm:
forall x:
V[T](x) ← 0
for t from T-1 to 0:
forall x:
V[t](x) ← max_a { H[t](x,a) + V[t-1](f(x,a)) }
What actually was requested was this:
def k_hanoi(npods,nrings):
if nrings == 1 and npods > 1: #one remaining ring: just one move
return 1
if npods == 3:
return 2**nrings - 1 #optimal solution with 3 pods take 2^d -1 moves
if npods > 3 and nrings > 0:
sol = []
for pivot in xrange(1, nrings): #loop on all possible pivots
sol.append(2*k_hanoi(npods, pivot)+k_hanoi(npods-1, nrings-pivot))
return min(sol) #minimization on pivot
k = 4
d = 10
print k_hanoi(k, d)
I think it is the Frame algorithm, with optimization on the pivot chosen to divide the disks in two subgroups. I also think someone demonstrated this is optimal for 4 pegs (in 2014 or something like that? Not sure btw) and conjectured to be optimal for more than 4 pegs. The limitation on the number of moves can be implemented easily.
The value function in this case was the number of steps needed to go from the initial configuration to the ending one and it needed be minimized. Thank you all for the contribution.

Tiling a Triangular Grid

Design and explain a recursive divide-and-conquer algorithm. Anyone has ideas?
Given an isosceles right triangular grid for some k ≥ 2 as shown in Figure 1(b), this problem asks you to completely cover it using the tiles given in Figure 1(a). The bottom-left corner of the grid must not be covered. No two tiles can overlap and all tiles must remain completely inside the given triangular grid. You must use all four types of tiles shown in Figure 1(a), and no tile type can be used to cover more than 40% of the total grid area. You are allowed to rotate the tiles, as needed, before putting them on the grid.
This is the idea of induction indeed, and is similar to the famous example "L-Tile" covering
As you said, you have solved the problem for k = 2, it's a good and correct starting point to solving small example first, yet I think this problem there is a bit tricky for k = 2 case, mainly due to the each type cannot exceed 40% constrain.
Then for k>2, say k = 3 in your example, we try to make use of what you have solved, i.e. the case k = 2
With very simple observation, one may notice that for k = n, it can actually be made up of 4 k=n-1 cases (see image below)
Now the shaded part in the middle form a hole that can filled by 1 type B, so we can first filled the 4 small n-1 case and fill the hole with type B...
But then this construction face a problem: type B will exceed 40% of the area!
Consider k = 2, no matter how you fill the area, 2 type B must be used, I do not have a strong proof but by some brute force trail & error you should be convinced. Then for k = 3, we have 4 small triangles meaning we have 2*4 = 8 Type B, plus 1 more to fill the hole will gives us 9 Type B, each uses 1.5 sq units, which total uses up 13.5 sq units.
As k = 3, the total area is (2^3)^2 / 2 = 32 sq units
13.5/32 = 0.42.... which violate the constrain!
So what to do? Here is the reason why we have to use a trick to handle the k = 2 case (I assume you have go through this part as you said you know how to do k = 2 case)
First, we know that using our constructive method to build a large triangle from 4 smaller triangles, only Type B will violate this constrain (i.e. the 40% area), you can verify yourself. So we want to reduce the total number of Type B used, yet each smaller triangle must use at least 2 Type B, so the only place we may reduce is the empty hole in the middle of the large triangle, can we use other Type instead of Type B? At the same time, we want the other parts of the small triangle remain unchanged so that we can use same argument to do an induction (i.e. in general speaking, form 2^n triangle from 4 2^(n-1) triangles using same construction method)
The answer is YES if we special design the k = 2 case
See my construction below: (There maybe other construction works too, but I only need to know one)
The trick is I intentionally move 1 Type B next to the empty(gray) triangle
Let's stop right here for a bit, and do some verification:
To construct a k = 2 case, we use
2 Type A = 2 sq.units < 40%
2 Type B = 3 sq.units < 40%
1 Type C = 1.5 sq.units < 40%
1 Type D = 1 sq.unit < 40%
Total use 7.5 sq.units, good
Now imagine we use exactly the same method to construct those 4 triangles to make a large one, the middle one still be an empty hole with shape of Type B, but now instead of filling it with 1 Type B, we fill the hole TOGETHER WITH the 3 Type B just next to them (look back the k = 2 case), using Type A & D
(I use same color scheme as above for easy understanding), we do this for all 3 small triangles which made up the hole in the middle.
Here is the last part (I know it's long...)
We have reduce the number of Type B used when constructing a large triangle from smaller ones, but at the same time we increase the number of Type A & D used! So is this new construction method valid?
First notice that it does not change any parts of the small triangles except the Type B next to the gray triangle, i.e. If the 40% constrain is fulfilled, this method is inductive and recursive to fill a 2^n side triangle
Then let's count again the number of each Type we used.
For k = 3, total units is 32, we uses:
2*4+3 = 11 Type A = 11 sq.units < 40%
2*4-3 = 5 Type B = 7.5 sq.units < 40%
1*4 = 4 Type C = 6 sq.units < 40%
1*4+3 = 7 Type D = 7 sq.unit < 40%
Total we cover 31.5 units, good, now let's proof the 40% constrain is satisfied for k = n > 3
Let FA(n-1) be the total area of Type A used to fill 2^n-1 triangles using our new method, likewise, FB(n-1), FC(n-1), FD(n-1) with similar definitions
Assume F*(n-1) is true, i.e. not exceeding 40% of total area, we proof that F*(n) is true.
We got
FA(n) = FA(n-1)*4 + 3*1
FB(n) = FB(n-1)*4 - 3*1.5
FC(n) = FC(n-1)*4
FD(n) = FD(n-1)*4 + 3*1
We only show the proof for FD(n), other three should be proofed with similar method (M.I.)
Using method of substitution, FD(n) = 2*(4^(n-2)) - 1 for n>=3 (You should at least try to come up with this equation yourself)
We want to show FD(n)/(2^2(n)/2) < 0.4
i.e. 2FD(n)/4^n < 0.4
Consider LHS,
LHS = (4*(4^(n-2)) - 1)/4^n
< 4^(n-1)/4^n = 1/4 < 0.4 Q.E.D
That means using this method, all Type A-D will not exceed 40% of total area for any 2^k sided triangle, for k >= 3, finally we show that inductively, there is a method satisfy all constrains to construct such a triangle.
TL;DR
The hard part is to satisfy the 40% area constrain
Use a special construction on k = 2 case first, try to use it to build k = 3 case (then k = 4, k = 5...idea of induction!)
When using k=n-1 case to build k=n case, write down the formula of total area consumed by each type, and show that they would not exceed 40% of total areas
Combined point 2 & 3, it's an induction method to show that for any k >= 2, there is a method (which we described) to fill the 2^k sided triangle without breaking any constrains

Compare two arrays of points [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I'm trying to find a way to find similarities in two arrays of different points. I drew circles around points that have similar patterns and I would like to do some kind of auto comparison in intervals of let's say 100 points and tell what coefficient of similarity is for that interval. As you can see it might not be perfectly aligned also so point-to-point comparison would not be a good solution also (I suppose). Patterns that are slightly misaligned could also mean that they are matching the pattern (but obviously with a smaller coefficient)
What similarity could mean (1 coefficient is a perfect match, 0 or less - is not a match at all):
Points 640 to 660 - Very similar (coefficient is ~0.8)
Points 670 to 690 - Quite similar (coefficient is ~0.5-~0.6)
Points 720 to 780 - Let's say quite similar (coefficient is ~0.5-~0.6)
Points 790 to 810 - Perfectly similar (coefficient is 1)
Coefficient is just my thoughts of how a final calculated result of comparing function could look like with given data.
I read many posts on SO but it didn't seem to solve my problem. I would appreciate your help a lot. Thank you
P.S. Perfect answer would be the one that provides pseudo code for function which could accept two data arrays as arguments (intervals of data) and return coefficient of similarity.
Click here to see original size of image
I also think High Performance Mark has basically given you the answer (cross-correlation). In my opinion, most of the other answers are only giving you half of what you need (i.e., dot product plus compare against some threshold). However, this won't consider a signal to be similar to a shifted version of itself. You'll want to compute this dot product N + M - 1 times, where N, M are the sizes of the arrays. For each iteration, compute the dot product between array 1 and a shifted version of array 2. The amount you shift array 2 increases by one each iteration. You can think of array 2 as a window you are passing over array 1. You'll want to start the loop with the last element of array 2 only overlapping the first element in array 1.
This loop will generate numbers for different amounts of shift, and what you do with that number is up to you. Maybe you compare it (or the absolute value of it) against a threshold that you define to consider two signals "similar".
Lastly, in many contexts, a signal is considered similar to a scaled (in the amplitude sense, not time-scaling) version of itself, so there must be a normalization step prior to computing the cross-correlation. This is usually done by scaling the elements of the array so that the dot product with itself equals 1. Just be careful to ensure this makes sense for your application numerically, i.e., integers don't scale very well to values between 0 and 1 :-)
i think HighPerformanceMarks's suggestion is the standard way of doing the job.
a computationally lightweight alternative measure might be a dot product.
split both arrays into the same predefined index intervals.
consider the array elements in each intervals as vector coordinates in high-dimensional space.
compute the dot product of both vectors.
the dot product will not be negative. if the two vectors are perpendicular in their vector space, the dot product will be 0 (in fact that's how 'perpendicular' is usually defined in higher dimensions), and it will attain its maximum for identical vectors.
if you accept the geometric notion of perpendicularity as a (dis)similarity measure, here you go.
caveat:
this is an ad hoc heuristic chosen for computational efficiency. i cannot tell you about mathematical/statistical properties of the process and separation properties - if you need rigorous analysis, however, you'll probably fare better with correlation theory anyway and should perhaps forward your question to math.stackexchange.com.
My Attempt:
Total_sum=0
1. For each index i in the range (m,n)
2. sum=0
3. k=Array1[i]*Array2[i]; t1=magnitude(Array1[i]); t2=magnitude(Array2[i]);
4. k=k/(t1*t2)
5. sum=sum+k
6. Total_sum=Total_sum+sum
Coefficient=Total_sum/(m-n)
If all values are equal, then sum would return 1 in each case and total_sum would return (m-n)*(1). Hence, when the same is divided by (m-n) we get the value as 1. If the graphs are exact opposites, we get -1 and for other variations a value between -1 and 1 is returned.
This is not so efficient when the y range or the x range is huge. But, I just wanted to give you an idea.
Another option would be to perform an extensive xnor.
1. For each index i in the range (m,n)
2. sum=1
3. k=Array1[i] xnor Array2[i];
4. k=k/((pow(2,number_of_bits))-1) //This will scale k down to a value between 0 and 1
5. sum=(sum+k)/2
Coefficient=sum
Is this helpful ?
You can define a distance metric for two vectors A and B of length N containing numbers in the interval [-1, 1] e.g. as
sum = 0
for i in 0 to 99:
d = (A[i] - B[i])^2 // this is in range 0 .. 4
sum = (sum / 4) / N // now in range 0 .. 1
This now returns distance 1 for vectors that are completely opposite (one is all 1, another all -1), and 0 for identical vectors.
You can translate this into your coefficient by
coeff = 1 - sum
However, this is a crude approach because it does not take into account the fact that there could be horizontal distortion or shift between the signals you want to compare, so let's look at some approaches for coping with that.
You can sort both your arrays (e.g. in ascending order) and then calculate the distance / coefficient. This returns more similarity than the original metric, and is agnostic towards permutations / shifts of the signal.
You can also calculate the differentials and calculate distance / coefficient for those, and then you can do that sorted also. Using differentials has the benefit that it eliminates vertical shifts. Sorted differentials eliminate horizontal shift but still recognize different shapes better than sorted original data points.
You can then e.g. average the different coefficients. Here more complete code. The routine below calculates coefficient for arrays A and B of given size, and takes d many differentials (recursively) first. If sorted is true, the final (differentiated) array is sorted.
procedure calc(A, B, size, d, sorted):
if (d > 0):
A' = new array[size - 1]
B' = new array[size - 1]
for i in 0 to size - 2:
A'[i] = (A[i + 1] - A[i]) / 2 // keep in range -1..1 by dividing by 2
B'[i] = (B[i + 1] - B[i]) / 2
return calc(A', B', size - 1, d - 1, sorted)
else:
if (sorted):
A = sort(A)
B = sort(B)
sum = 0
for i in 0 to size - 1:
sum = sum + (A[i] - B[i]) * (A[i] - B[i])
sum = (sum / 4) / size
return 1 - sum // return the coefficient
procedure similarity(A, B, size):
sum a = 0
a = a + calc(A, B, size, 0, false)
a = a + calc(A, B, size, 0, true)
a = a + calc(A, B, size, 1, false)
a = a + calc(A, B, size, 1, true)
return a / 4 // take average
For something completely different, you could also run Fourier transform using FFT and then take a distance metric on the returning spectra.

Weights Optimization in matlab

I have to do optimization in supervised learning to get my weights.
I have to learn the values (w1,w2,w3,w4) such that whenever my vector A = [a1 a2 a3 a4] is 1 the sum w1*a1 + w2*a2 + w3*a3 + w4*a4 becomes greater than 0.5 and when its -1 ( labels ) then it becomes less than 0.5.
Can somebody tell me how I can approach this problem in Matlab ? One way that I know is to do it using evolutionary algorithms, taking a random value vector and then changing to pick the best n values.
Is there any other way that this can be approached ?
You can do it using linprog.
Let A be a matrix of size n by 4 consisting of all n training 4-vecotrs you have. You should also have a vector y with n elements (each either plus or minus 1), representing the label of each training 4-vecvtor.
Using A and y we can write a linear program (look at the doc for the names of the parameters I'm using). Now, you do not have an objective function, so you can simply set f to be f = zeros(4,1);.
The only thing you have is an inequality constraint (< a_i , w > - .5) * y_i >= 0 (where <.,.> is a dot-product between 4-vector a_i and weight vector w).
If my calculations are correct, this constraint can be written as
cmat = bsxfun( #times, A, y );
Overall you get
w = linprog( zeros(4,1), -cmat, .5*y );

Resources