Eliminating Unnecessary Vertices In a Graph - graph-algorithm

I am studying for an interview and came across this question which I am having trouble solving. It goes like this:
Create an efficient algorithm that does two tasks to an undirected graph G: (1) elim- inates multiple copies of edges by replacing them with a single edge and (2) replaces edges (u, v) and (v,w) by an edge (u,w) where v is an edge of degree two. Be aware that removing a vertex with degree two can create multiple copies of edges and that removing multiple copies of edges can create a vertex with degree two.
I don't quite understand how removing a vertex with degree two can create multiple copies of edges and how removing multiple copies of edges can create a vertex with degree two. Can someone help clarify?

in a graph of four vertexes, w, x, y, z
w *----- x -----* y ------- z
| |
*---------------*
if you replace (w, x) and (x, y) with (w, y) using replaces rule, than it looks like, there are two parallel edges from w to y. if you remove duplicate edges, than the graph, will look like:
w --------------- y ------- z
so now if you replace (w, y) and (y, z) with (w, z) we are down to just (w, z)
w ------------------------- z
not exactly what was intended

Removing a vertex with degree two can create multiple copies of edges:
original edge: (u,v), (v,w), (u,w) after removing v: (u, w), (u, w)
Removing multiple copies of edges can create a vertex with degree two:
original edge: (u,v), (v,w), (v,w) after removing (v,w): (u, v), (v, w)

Related

Implementing convolutional neural network backprop in ArrayFire (gradient calculation)

I modified equation 9.12 in http://www.deeplearningbook.org/contents/convnets.html to center the MxN convolution kernel.
That gives the following expression (take it on faith for now) for the gradient, assuming 1 input and 1 output channel (to simplify):
dK(krow, kcol) = sum(G(row, col) * V(row+krow-M/2, col+kcol-N/2); row, col)
To read the above, the single element of dK at krow, kcol is equal to the sum over all of the rows and cols of the product of G times a shifted V. Note G and V have the same dimensions. We will define going outside V to result in a zero.
For example, in one dimension, if G is [a b c d], V is [w x y z], and M is 3, then the first sum is dot (G, [0 w x y]), the second sum is dot (G, [w x y z]), and the third sum is dot (G, [x y z 0]).
ArrayFire has a shift operation, but it does a circular shift, rather than a shift with zero insertion. Also, the kernel sizes MxN are typically small, e.g., 7x7, so it seems a more optimal implementation would read in G and V once only, and accumulate over the kernel.
For that 1D example, we would read in a and w,x and start with [a*0 aw ax]. Then we read in b,y and add [bw bx by]. Then read in c,z and add [cx cy cz]. Then read in d and finally add [dy dz d*0].
Is there a direct way to compute dK in ArrayFire? I can't help but think this is some kind of convolution, but I've been unable to wrap my head around what the convolution would look like.
Ah so. For a 3x3 dK array, I use unwrap to convert my MxN input arrays to two MxN column vectors. Then I do 9 dot products of shifted subsets of the two column vectors. No, that doesn't work since the shift is in 2 dimensions.
So I need to create intermediate arrays of 1 x (MxN) and (MxN) x 9 in size, where each column of the latter is a shifted MxN window of the original with a pad border of zeros of size 1, and then do a matrix multiply.
Hmm, that requires too much memory (sometimes.) So the final solution is to do a gfor over the output 3x3, and for each loop, do a dot product of the unwrapped-once G and the unwrapped-repeatedly V.
Agreed?

Ortho projection of 3D points with a vector

I have 3D points and I need to make an 2D orthographic projection of them onto a plane that is defined by the origin and a normal n. The meaning of this is basically looking at the points from the top (given the vertical vector). How can I do it?
What I'm thinking is:
project point P onto the 3D plane: P - P dot n * n
look at the 3D plane from the "back" in respect to the normal (not sure how to define this)
do an ortho projection using max-min coordinates of the points in the plane to define the clipping
I am working with iOS.
One way to do this would be to:
rotate the coordinate system so that the plane of interest lies in the x-y plane, and the normal vector n is aligned with the z-axis
project the points onto the x-y plane by setting their z-components to 0
Set up the coordinate transformation
There are infinitely many solutions to this problem since we can always rotate a solution in the x-y plane to get another valid solution.
To fix this, let's choose a vector v lying in the plane that will line up with the x-axis after the transformation. Any vector will do; let's take the vector in the plane with coordinates x=1 and y=0.
Since our plane intersects the origin, its equation is:
x*n1 + y*n2 + z*n3 = 0
z = -(x*n1 + y*n2)/n3
After substituting x=1, y=0, we see that
v = [1 0 -n1/n3]
We also need to make sure v is normalized, so set
v = v/sqrt(v1*v1 + v2*v2 + v3*v3)
EDIT: The above method will fail in cases where n3=0. An alternative method to find v is to take a random point P1 from our point set that is not a scalar multiple of n and calculate v = P1 - P1 dot n * n, which is the projection of P1 into the plane. Just keep searching through your points until you find one that satisfies (P1 dot n/norm(n)) != P1 and this is guaranteed to work.
Now we need a vector u that will line up with the y-axis after the transformation. We get this from the cross product of n and v:
u = n cross v
If n and v are normalized, then u is automatically normalized.
Next, create the matrix
M = [ v1 v2 v3 ]
[ u1 u2 u3 ]
[ n1 n2 n3 ]
Transform the points
Now given a 3 by N array of points P, we just follow the two steps above
P_transformed = M*P
P_plane = set the third row of P_transformed to zero
The x-y coordinates of P_plane are now a 2D coordinate system in the plane.
If you need to get the 3D spatial coordinates back, just do the reverse transformation with P_space = M_transpose*P_plane.

Rounding 3D random cube rotation to cloest 90 degrees

Imagine a cube with each of 6 walls in a different color. The cube rotates in random directions around its center point. When a user clicks or taps a screen, the rotation stops instantly. The cube is frozen in a random position. After the user releases mouse button or moves finger up from the screen, the cube should 'straighten', what means it should rotate around some axis by the smallest possible angle, just enough to present the most visible cube wall in the 'screen plane' the way that all edges are parallel to the edges of the screen.
Is there a way to find this closest 'straight' rotation, assuming that we have an access to the 'frozen' position given either by a rotation matrix, or by a quaternion (whichever is more convenient)?
One way of looking at the top 3x3 portion of a matrix is that it's just a description of the basis vectors as, if you were to apply one to a point:
[A D G] [x] [A*x + D*y + G*z] [A] [D] [G]
[B E H] [y] = [B*x + E*y + H*z] = x * [B] + y * [E] + z * [H]
[C F I] [z] [C*x + F*y + I*z] [C] [F] [I]
i.e. if you apply that matrix then the input x axis will end up running along (A, B, C), the input y axis will end up running along (D, E, F) and the input z axis will end up running along (G, H, I).
What I think you're asking is equivalent to "which axis has the least change along output z, i.e. is closest to perpendicular to the screen"? So you can determine that by looking for the value from (C, F, I) that has the least magnitude.
You can then use the z sign of the cross product of (A, B, C) and (D, E, F) to decide whether you're looking along the axis positively or negatively by the same logic that allows you to use that test for reverse face removal — whichever face would be visible if the camera were hypothetically moved backward to infinity is the one genuinely in front.
That also suggests an alternative test which you may prefer: do the transform and the face closest to perpendicular is whichever is visible and largest. It's the same logic behind the Lambert lighting model, with the fact that the faces were of a uniform size in the first place factored in. The advantage of that test is that you could do it directly on the GPU using the occlusion query, assuming none of them is actually occluded.
Simple solution.
1) Find the required wall, and construct vector from cube center to center of wall, let it be dir1
2) vector from cube center to camera, let it be dir2
3) Build quaternion "rotation_arc" between this vectors. http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm
4) rotate cube by quaternion from "3)"
To find wall : Build 6 vectors from center of cube to centers of walls. Than build vector from center of cube to camera. Estimate 6 angles between first vectors and second vector and select wall with smallest angle.

Why is the reconstructed model a scaled version using SfM(Structure from motion)?

I am learning structure from motion by myself and have read many materials.
Even if I have intrinsic parameters of the camera, a metric reconstruction is obtained
and produces a scaled model. From one material metric 3D reconstruction means that
the distance between the two captures is unknown. Why can't I get the distance using
point correspondences and intrinsic parameters? Can I get the model with physical
measurement if I use more than two images?
Thanks in advance.
Regards
Jogging
If you only have images, and no other information about the physical sizes of objects in the scene, you cannot recover those sizes from images alone - at best you can only reconstruct the scene only up to an unknown scale factor. This means, for example, that you may be able to tell that two lines are perpendicular to each other. You may also be able to compute the width/height ratio of a rectangular tile, but without being able to tell what the individual values of the height and the width are.
You can convince yourself that this is in fact the case by noticing that, for example, the images remain unchanged if you shrink down all the objects in the scene by a factor S, and then move it closer to the camera by the same amount. This is what allows doing some old-school special effects in movies using miniature models (like these), and it works regardless of whether the camera is fixed or moving with respect to the scene - i.e. it applies to the multiple image case as well.
If both the cameras and the scene are correspondingly scaled, the change will not be discernible in the captured images. That's why the scale factor is unknown in SfM. To obtain it, some physical measurement of the scene or the camera motion is typically needed.
If you're not convinced, simply do the math:
Let (P1 p1) and (P2 p2) be the 3x4 projection matrices of two cameras 1 and 2 (P1 is a 3x3 matrix and p1 a column vector), M a point in the scene, and m1 and m2 the respective projections of M in cameras 1 and 2. We have (~= means "is proportional to", because of the perspective division):
m1 ~= P1 M + p1
m2 ~= P2 M + p2
Introducing the camera centers C1 = -P1^-1 p1, C2 = -P2^-1 p2 and the translation T = C2 - C1 between the cameras, this can be written:
m1 ~= P1 (M - C1)
m2 ~= P2 (M - C2) = P2 (M - (C1 + T))
Now scale the whole scene by a factor of s and translate its origin it by o: M' = s M + o. Introduce two cameras 1' and 2', that are versions of 1 and 2 with the inverse scaling factor, i.e. P1' = 1/s P1 and P2' = 1/s P2. Scale and offset their centers C1' = s C1 + o and C2' = s (C1 + T) + o. The relative translation between the two cameras is now: C2' - C1' = s T. The projections of M' in 1' and 2' are:
m1' ~= P1' (M' - C1') = 1/s P1 (s M + o - s C1 - o) = P1 (M - C1)
~= m1
m2' ~= P2' (M' - C2') = 1/s P2 (s M + o - s (C1 + T) - o) = P2 (M - C2)
~= m2
So in the end, you get the same projections (your input in an SfM problem) with a scene that has a different scale and origin and correspondingly scaled and translated cameras. This can be generalized to more than two cameras.

path smooth algorithm for astar path planning based on quad tree

I implement an astar path finding method based on quad tree(the grids are difference in size, it's the main case), now I can get the rough path, but I don't get a smooth method to optimize the path, anyone who has one or reference may helps, thanks.
haha,I find the method for the difference size path smooth. Just use the funnel algorithm too, but there is a difference: when add left and right point for two quads, find one intersection side, and sort the four points(a0, a1, b0, b1) like ([x, y0], [x, y1], [x, y2], [x, y3], and y0 <= y1 <= y2 <= y3) , and use the two points [x, y1], [x, y2].

Resources