Merging linear chain of vertices in a Graph (in C++) - c++

I have a large graph and it is represented in adjacency list. I would like to compress the graph by merging the linear chain of nodes. For example, if the edges are a-c, b-c, c-d, d-e, e-f, e-g:
a - c - d - e - f
| |
b g
Then c-d, d-e can be merged to a single node x and the new edge list should have a-x, b-x, x-g. I would like to implement it in C++, but I am wondering if there is any C++ graph library which handles this. Also, any suggestion for a efficient algorithm is appreciated.

I think you example might be broken so I am going to solve a slightly different one:
a - c - i - d - e - f
| |
b g
|
h
I think the solution looks like:
a - c - x - e - f
| |
b h
If you agree, then consider counting the number of times each vertex appears in the adjacency list, and storing the first two neighbors for each:
a b c d e f g h i
1 1 3 2 3 1 2 1 2
c c a i d e e g c
b e g h d
The places where it is 2, we can consider collapsing: at d, g, and i:
d g i # candidates
2 2 2
i e c
e h d
Now you can see g has two neighbors not in the candidates, so simply delete g because it is a singleton "chain." This leaves d, whose neighbor i is in the candidates, so collapse d and i into a new vertex x and you're done.

You simply need to remove all nodes with degree 2, merging their two neighbors into a single node.
Repeat the process till no such nodes are left.
The Boost Graph library is usually a good way to store and work with graphs. See here how to merge vertices and contract the edge.

Related

Adjacency matrix and Bron–Kerbosch algorithm

I want to find maximum cliques in a graph that is given to me in a form of adjacency matrix. I what I am trying to do I am being given the amount of shops I need to find with the same product tag that are being collected and whether sufficient amount of those shops was found
so input goes along lines
x - shop count.
y - product count/tag.
z - in how many shops does the product need to be present.
so let's say I got
5 - x
2 - y
4 - z
Then the adjacency matrix going with it is:
0 1 1 1 1
1 0 2 2 1
1 2 0 2 2
1 2 2 0 1
1 1 2 1 0
There are two different products available, now I want to find out whether there are atleast 4 shops selling specific product. I found out about Bron–Kerbosch algorithm e.g. http://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm
But I don't know how to pick my R, P and X subsets and how to represent them. It does not have to be very efficient nor I believe there is a need for any more advanced data structure than a 2D array but I just don't know how to use this adjacency matrix as a list of my vertices etc. Could anyone give me an idea on how to get started with this algorithm? Probably telling me how to treat R, P and X with my data would be sufficient. I would want to create my program in C++
From the wikipedia article:
BronKerbosch3(G):
P = V(G)
R = X = empty
for each vertex v in a degeneracy ordering of G:
BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
P := P \ {v}
X := X ⋃ {v}
where G is the graph and BronKerbosch2() is defined as :
BronKerbosch2(R,P,X):
if P and X are both empty:
report R as a maximal clique
choose a pivot vertex u in P ⋃ X
for each vertex v in P \ N(u):
BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
P := P \ {v}
X := X ⋃ {v}
So now you know your choice of R, P and X. Also lookup what an adjacency matrix actually is as mentioned in the comments. Also, read the article carefully for the use of degeneracy in the algorithm.
In C++, you could use std::array<std::array<int, SIZE>, SIZE> for the 2D adjacency matrix and then proceed with the algorithm.

How to get full access to one dimension in OpenCV mat?

Ok, My problem is not accessing one element from the mat, but I want to get the whole mat while one dimension is fixed. Let's say we have a three dimension matrix and I want to access the third dimension which should return a rows*cols mat.
In matlab, this is extremely easy, say A is a three dimension matrix(3*3*3), if we want to access the the third dimension, then just use A(:,:,1), A(:,:,2) A(:,:,3). But how should we do in OpenCV? It seems that OpenCV didn't provide this method?
I am asking this because I have a vector of Mat: Vector frames, each element in the vector is a two dimension gray image. I want to change the vector format into a three-dimensional Mat format. But I just don't know how to copy it. The ideal way should be:
for(int i=0; i<frames.size(); i++) {
A(:,:,i) = frames[i].clone();
}
How should I do this? Thanks!
To answer your specific question on how to combine 3 channels into one image, you would use merge like so:
merge(frames, A);
For the more general question of how to access 2D planes of a 3D Mat, hopefully this tutorial will give you some insight. Specifically how the B, G and R components of a Mat are interleaved on each row like so (they have a much better image in the tutorial):
| Col 1 | Col 2 | Col 3 | Col 4 |...
Row 1 |B G R | B G R | B G R | B G R |...
Row 2 |B G R | B G R | B G R | B G R |...
Row 3 |B G R | B G R | B G R | B G R |...
...

Cluster terrain map disjoint by river through map/matrix?

I have simple matrix (matrix, which represents terrain map in 2d game, contains ASCII characters for example 'm' for mountain, 'v' for valley, 'r' for river) and on map there maybe one or none river. River can flow from any position from matrix to any ( and always separate map on two distinct parts => no source of river on map possible, always enter at one end and exists on another). How to separate matrix/terrain map on two clusters if there is river present ?
example terrain
v v v v v v v v r v v v v v
v v v v v m m m r m m m m m
v v v v v m m r r m m m m m
m m v m m m m r r m m m v v
v v v v v v r r v v v v v v
here I should get left cluster and right cluster of coordinates which are not river.
You should try looking up the Fill algorithm.
http://en.wikipedia.org/wiki/Flood_fill
Basically you want to pick a point that it's not in a river, start the flood fill algorithm which will give you a set of points connected to the starting point. This way now you have one part and finding the one is pretty easy from now on.
Your map induces a graph:
there's one vertex for each map cell
two vertices are connected if they are adjacent and none of them is an 'r'
Once the graph is constructed, you can run a graph traversal algorithm like breadth-first search (BFS) or depth-first search (DFS) to find the connected components of the graph.
I'd recommend using BFS, because if the map is large then DFS might get you into a stack overflow (if its recursive implementation is used).
You'll want to run the BFS only on non-'r' nodes, so that in the end you'll end up with two connected components.

How to solve Linear Diophantine equations in programming?

I have read about Linear Diophantine equations such as ax+by=c are called diophantine equations and give an integer solution only if gcd(a,b) divides c.
These equations are of great importance in programming contests. I was just searching the Internet, when I came across this problem. I think its a variation of diophantine equations.
Problem :
I have two persons,Person X and Person Y both are standing in the middle of a rope. Person X can jump either A or B units to the left or right in one move. Person Y can jump either C or D units to the left or right in one move. Now, I'm given a number K and I have to find the no. of possible positions on the rope in the range [-K,K] such that both the persons can reach that position using their respective movies any number of times. (A,B,C,D and K are given in question).
My solution:
I think the problem can be solved mathematically using diophantine equations.
I can form an equation for Person X like A x_1 + B y_1 = C_1 where C_1 belongs to [-K,K] and similarly for Person Y like C x_2 + D y_2 = C_2 where C_2 belongs to [-K,K].
Now my search space reduces to just finding the number of possible values for which C_1 and C_2 are same. This will be my answer for this problem.
To find those values I'm just finding gcd(A,B) and gcd(C,D) and then taking the lcm of these two gcd's to get LCM(gcd(A,B),gcd(C,D)) and then simply calculating the number of points in the range [1,K] which are multiples of this lcm.
My final answer will be 2*no_of_multiples in [1,K] + 1.
I tried using the same technique in my C++ code, but it's not working(Wrong Answer).
This is my code :
http://pastebin.com/XURQzymA
My question is: can anyone please tell me if I'm using diophantine equations correctly ?
If yes, can anyone tell me possible cases where my logic fails.
These are some of the test cases which were given on the site with problem statement.
A B C D K are given as input in same sequence and the corresponding output is given on next line :
2 4 3 6 7
3
1 2 4 5 1
3
10 12 3 9 16
5
This is the link to original problem. I have written the original question in simple language. You might find it difficult, but if you want you can check it:
http://www.codechef.com/APRIL12/problems/DUMPLING/
Please give me some test cases so that I can figure out where am I doing wrong ?
Thanks in advance.
Solving Linear Diophantine equations
ax + by = c and gcd(a, b) divides c.
Divide a, b and c by gcd(a,b).
Now gcd(a,b) == 1
Find solution to aU + bV = 1 using Extended Euclidean algorithm
Multiply equation by c. Now you have a(Uc) + b (Vc) = c
You found solution x = U*c and y = V * c
The problem is that the input values are 64-bit (up to 10^18) so the LCM can be up to 128 bits large, therefore l can overflow. Since k is 64-bit, an overflowing l indicates k = 0 (so answer is 1). You need to check this case.
For instance:
unsigned long long l=g1/g; // cannot overflow
unsigned long long res;
if ((l * g2) / g2 != l)
{
// overflow case - l*g2 is very large, so k/(l*g2) is 0
res = 0;
}
else
{
l *= g2;
res = k / l;
}

Expression transformation problem

Let's say we have the following statement: s = 3 * a * b - 2 * c, where s, a, b and c are variables. Also, we used Shunting Yard algorithm to build RPN expression, so now we can assign values to variables a, b and c and calculate s value by using simple RPN evaluator.
But, the problem is that I should be able to calculate a value of any variable a, b or c when values of all other variables are set.
So, I need to transform existing expression somehow to get a set of expressions:
a = (s + 2 * c) / (3 * b)
b = (s + 2 * c) / (3 * a)
c = (3 * a * b - s) / 2
How can I generate such expressions on basis of one original statement? Is there any standard approaches for solving such problems?
Constraints:
A set of available operators: +, -, *, /, including unary + and -
operators *, / and = can't have the same variable on both sides (e.g. s = a * a, or s = a + s are not acceptable)
Thanks
See this first: Postfix notation to expression tree to convert your RPN into a tree.
Once you have the equation left expression = right expression change this to left expression - right expression = 0 and create a tree of left expression - right expression via Shunting Yard and the above answer. Thus when you evaluate the tree, you must get the answer as 0.
Now based on your restrictions, observe that if a variable (say x) is unknown, the resulting expression will always be of the form
(ax + b)/(cx + d) where a,b,c,d will depend on the other variables.
You can now recursively compute the expression as a tuple (a,b,c,d).
In the end, you will end up solving the linear equation
(ax + b)/(cx + d) = 0 giving x = -b/a
This way you don't have to compute separate expressions for each variable. One expression tree is enough. And given the other variables, you just recursively compute the tuple (a,b,c,d) and solve the linear equation in the end.
The (incomplete) pseudocode will be
TupleOrValue Eval (Tree t) {
if (!t.ContainsVariable) {
blah;
return value;
}
Tuple result;
if (t.Left.ContainsVariable) {
result = Eval(t.Left);
value = Eval(t.Right);
return Compose(t.Operator, result, value);
} else {
result = Eval(t.Right);
value = Eval(t.Left);
return Compose(t.Operator, result, value);
}
}
Tuple Compose(Operator op, Tuple t, Value v) {
switch (op) {
case 'PLUS': return new Tuple(t.a + v*t.c, t.b + v*t.d, t.c, t.d);
// (ax+b)/(cx+d) + v = ( (a + vc)x + b + dv)/(cx + d)
// blah
}
}
For an example, if the expression is x+y-z = 0. The tree will be
+
/ \
x -
/ \
y z
For y=5 and z=2.
Eval (t.Right) will return y-z = 3 as that subtree does not contain x.
Eval(t.Left) will return (1,0,0,1) which corresponds to (1x + 0)/(0x + 1). Note: the above pseudo-code is incomplete.
Now Compose of (1,0,0,1) with the value 3 will give (1 + 3*0, 0 + 3*1, 0, 1) = (1,3,0,1) which corresponds to (x + 3)/(0x + 1).
Now if you want to solve this you take x to be -b/a = -3/1 = -3
I will leave the original answer:
In general it will be impossible.
For instance consider the expression
x*x*x*x*x + a*x*x*x*x + b*x*x*x + c*x*x + d*x = e
Getting an expression for x basically corresponds to find the roots of the polynomial
x5 + ax4 + bx3 + cx2 + dx -e
which has been proven to be impossible in general, if you want to use +,-,/,* and nth roots. See Abel Ruffini Theorem.
Are there are some restrictions you forgot to mention, which might simplify the problem?
The basic answer is you have to apply algebra to the set of equations you have, to produce equations that you want.
In general, if you start with this symbolic equation:
s = 3 * a * b - 2 * c
and you add constraints for s, a, and c:
s = ...
a = ...
c = ...
you need to apply standard laws of algebra to rearrange the set of equations to produce what you want, in this case, a formula for b:
b = ...
If you add different constraints, you need the same laws of algebra, applied in different ways.
If your equations are all of the form (as your example is not) of
left_hand_side_variable_n = combination_of_variables
then you can use rules for solving simultaneous equations. For linear combinations, this is pretty straightforward (you learned how to do this high school). And you can even set up a standard matrix and solve using a standard solver package without doing algebra.
If the equations are not linear, then you may not be able to find a solution no matter how good your math is (see other answers for examples). To the extent it is possible to do so, you can use a computer algebra system (CAS) to manipulate formulas. They do so by representing the formulas essentially as [math] abstract syntax trees, not as RPN, and apply source-to-source transformation rules (you would call these "algebra rules" from high school). They usually have a pretty big set of built-in rules ("knowledge") already. Some CAS will attempt to solve such systems of equations for you using the built-in rules; others, you have to tell what sequence of algebraic laws to apply in what order.
You may also use a constraint solver, which is a special kind of computer algebra system focused only on answering the kind of question you've posed, e.g., "with this set of constraints, and specific values for variables, what is the value of other variables?". These are pretty good if your equations follows the forms they are designed to solve; otherwise no gaurantee but that's not surprising.
One can also use a program transformation system, which manipulate arbitrary "syntax trees", because algrebra trees are just a special case of syntax trees. To use such a system, you define the langauge to be manipulated (e.g., conventional algebra) and the rules by which it can be manipulated, and the order in which to apply the rules. [The teacher did exactly this for you in your intro algebra class, but not in such a formal way] Here's an example of a my program transformation system manipulating algebra. For equation solving, you want much the same rules, but a different order of application.
Finally, if you want to do this in a C++ program, either you have to simulate one of the above more general mechanisms (which is a huge amount of work), or you have narrow what you are willing to solve significantly (e.g., "linear combinations") so that you can take advantage of a much simpler algorithm.
There is a quite straight-forward one for very basic expressions (like in your example) where each variable occurs mostly once and every operator is binary. The algorithm is mostly what you would do by hand.
The variable we are looking for will be x in the following lines. Transform your expression into the form f(...,x,...) == g(...). Either variable x is already on the left hand side or you just switch both sides.
You now have two functions consisting of applications of binary operators to sub-expressions, i.e. f = o_1(e_1,e_2) where each e_i is either a variable, a number or another function e_i = o_i(e_j, e_k). Think of this as the binary tree representation where nodes are operators and leafs are variables or numbers. Same applies for g.
Yyou can apply the following algorithm (our goal is to transform the tree into one representing the expression x == h(...):
while f != x:
// note: f is not a variable but x is a subexpression of f
// and thus f has to be of the form binop(e_1, e_2)
if x is within e_1:
case f = e_1 + e_2: // i.e. e_1 + e_2 = g
g <- g - e_2
case f = e_1 - e_2: // i.e. e_1 - e_2 = g
g <- g + e_2
case f = e_1 * e_2: // i.e. e_1 * e_2 = g
g <- g / e_2
case f = e_1 / e_2: // i.e. e_1 / e_2 = g
g <- g * e_2
f <- e_1
else if x is within e_2:
case f = e_1 + e_2: // i.e. e_1 + e_2 = g
g <- g - e_2
case f = e_1 - e_2: // i.e. e_1 - e_2 = g
g <- g + e_2
case f = e_1 * e_2: // i.e. e_1 * e_2 = g
g <- g / e_2
case f = e_1 / e_2: // i.e. e_1 / e_2 = g
g <- g * e_2
f <- e_1
Now that f = x and f = g was saved during all steps we have x = g as solution.
In each step you ensure that x remains on the lhs and at the same time you reduce the depth of the lhs by one. Thus this algorithm will terminate after a finite amount of steps.
In your example (solve for b):
f = 3a*b*2c*- and g = s
f = 3a*b* and g = s2c*+
f = b and g = s2c*+3a*/
and thus b = (s + 2*c)/(3*a).
If you have more operators you can extend the algorithm but you might run into problems if they are not invertible.