Minimal set of n-tuples covering a given set of n-tuples - graph

Input: a set of M ordered tuples of n elements, where each element is a set, i.e.:
(A1, A2, ..., An), where each Ai is a set
Problem: combine these n-tuples together to create the minimal set of n-tuples.
2 n-tuples can be combined together iff they differ only on one position, i.e.:
A = (A1, A2, ..., An) and B = (B1, B2, ..., Bn) can be combined into (A1, A2, ..., Ai U Bi, Ai+1, ..., An) iff Aj = Bj, for every j != i.
An example:
Input: 4 2-tuples: ({1}, {1}), ({1}, {2}), ({3}, {1}), ({3}, {2})
Output: one 2-tuple: ({1, 3}, {1, 2})
My question is: how would you approach this problem? Do you know if it can be reduced to a known NP problem? One idea would be to model this as a graph: if tuples A and B can be combined, draw a colored edge between them with color i (i = the position where they differ).

Related

Why do we have at least three definitions of a graph in math?

Definition 1 - 2 sets and function
Definitioin 2 - 1 set and 1 family
Definition 3 - 1 relation
Why do we need such a diversity? Are some of these definitions old-fashioned or all of them have their pros and cons?
Undirected graphs and directed graphs
The third definition differs from the first two because it is about directed graphs, while the first two define undirected graph. We care about directed graphs and undirected graphs because they are adapted to different situations and to solving different problems.
You can think of directed graphs and undirected graphs as two different objects.
In general, undirected graphs are somewhat easier to reason about, and most often if someone mentions a "graph" without precision, they mean an undirected graph.
Named edges and incidence function
The first two definitions are pretty much equivalent.
The first definition, with (V, E, ѱ) gives "names" to vertices (elements of V) and names to edges (elements of E), and uses an "incidence function" ѱ to tell you which edge in E corresponds to which pair of vertices of V.
The second definition uses only (V', E') and no ѱ. I am calling them V' and E' instead of V and E to make a distinction from the first definition. Here the vertices have "names", they are the elements of V'; but the edges don't really have individual names, and E' is defined as a subset of the set of undirected pairs of V. Therefore an edge is an undirected pair of elements of V'.
Here is an example of a graph:
By the first definition:
V = {a, b, c, d};
E = {1, 2, 3};
ѱ : E -> {unordered pairs of V}
1 -> ab
2 -> ac
3 -> cd.
By the second definition:
V' = {a, b, c, d}
E' = {ab, ac, cd}.
As you can see, V' = V, and E' is the image of E by ѱ.
If you don't care about "names" for the edges, the second definition is somewhat shorter. But which one you use really doesn't matter; the theorems you might prove with one definition will be equivalent to the theorems you can prove for the other definition. The difference between the two definition is just a set theory nitpick of what "edge" means: is it a pair of elements of V, or an element of another set which is mapped to a pair of elements of V by a function? Note that the function ѱ is a bijection between the two sets E and E', so really E and E' are two different names for the same set.
Algorithms, programming languages, and representations of graphs
If you ever have to code an algorithm using a graph in your favourite programming language, you will have to decide how to represent the graph using variables and arrays and all the data structures you are used to.
For the vertices, most often, people use V = {0, 1, 2, ..., n-1} where n is the number of vertices. This is convenient because it means you can use the vertices as indices for an array.
For the edges, sometimes we encode E using an vertex-vertex incidence matrix of size n*n with a 1 in cell i,j to indicate an edge between vertices i and j and a 0 in cell i,j to indicate no edge. Here is the incidence matrix for the graph above (I replaced a,b,c,d with 0,1,2,3 as the names for the vertices):
0 1 2 3
0 0 1 1 0
1 1 0 0 0
2 1 0 0 1
3 0 0 1 0
Sometimes we encode E using an array of lists: an array of size n, where cell i contains the list of indices of vertices which are neighbours of vertex i. Here is the array of lists for the same graph:
0: 1,2
1: 0
2: 0,3
3: 2
Those two representations are closer to the second definition, since the edges don't have names; we just care about whether each pair of vertices is an edge or not.
Recently I had to write a C++ program where it was very important for me to number the edges, because I wanted to be able to use them as indices of a matrix. Thus I had V = {0, 1, 2, ..., n-1}; E = {0, 1, 2, ..., m-1}; and then I used an std::map<int, std::pair<int, int>> to map the edge indices to pairs of vertex indices. This representation was closer to your first definition, which an std::map for ѱ. Note that I had to make a choice between mapping edge indices to pairs of vertex indices, or mapping pairs of vertex indices to edge indices. Had I felt the necessity, I could even have used both. The first definition doesn't care, because ѱ is a bijection, so mathematicians can use ѱ and its inverse function ѱ^-1 indifferently; but the data structure std::map is not a mathematical function, and inversing it might take time.
Conclusion
Both definitions are equivalent, and it really doesn't matter which one you use. But if you need to code algorithms using graphs, take some time to consider different representations of graphs and which one will make your algorithm the most efficient.

Check if 4 points in space are corner points of a rectangle

I have 4 points in space A(x,y,z), B(x,y,z), C(x,y,z) and D(x,y,z). How can I check if these points are the corner points of a rectangle?
You must first determine whether or not the points are all coplanar, since a rectangle is a 2D geometric object, but your points are in 3-space. You can determine they are coplanar by comparing cross products as in:
V1 = (B-A)×(B-C)
V2 = (C-A)×(C-D)
This will give you two vectors which, if A, B, C, and D are coplanar are linearly dependent. By considering what Wolfram has to say on vector dependence, we can test the vectors for linear dependence by using
C = (V1∙V1)(V2∙V2) - (V1∙V2)(V2∙V1)
If C is 0 then the vectors V1 and V2 are linearly dependent and all the points are coplanar.
Next compute the distances between each pair of points. There should be a total of 6 such distances.
D1 = |A-B|
D2 = |A-C|
D3 = |A-D|
D4 = |B-C|
D5 = |B-D|
D6 = |C-D|
Assuming none of these distances are 0, these points form a rectangle if and only if the vertices are coplanar (already verified) and these lengths can be grouped into three pairs where elements of each pair have the same length. If the figure is a square, two sets of the pairs will have be the same length and will be shorter than the remaining pair.
Update: Reading this again, I realize the the above could define a parallelogram, so an additional check is required to check that the square of the longest distance is equal to the sum of the squares of the two shorter distances. Only then will the parallelogram also be a rectangle.
Keep in mind all of this is assuming infinite precision and within a strictly mathematical construct. If you're planning to code this up, you will need to account for rounding and accept a degree of imprecision that's not really a player when speaking in purely mathematical terms.
Check if V1=B-A and V2=D-A are orthogonal using the dot product. Then check if
C-A == V1+V2
within numerical tolerances. If both are true, the points are coplanar and form a rectangle.
Here a function is defined to check whether the 4 points represents the rectangle or not .
from math import sqrt
def Verify(A, B, C, D, epsilon=0.0001):
# Verify A-B = D-C
zero = sqrt( (A[0]-B[0]+C[0]-D[0])**2 + (A[1]-B[1]+C[1]-D[1])**2 + (A[2]-B[2]+C[2]-D[2])**2 )
if zero > epsilon:
raise ValueError("Points do not form a parallelogram; C is at %g distance from where it should be" % zero)
# Verify (D-A).(B-A) = 0
zero = (D[0]-A[0])*(B[0]-A[0]) + (D[1]-A[1])*(B[1]-A[1]) + (D[2]-A[2])*(B[2]-A[2])
if abs(zero) > epsilon:
raise ValueError("Corner A is not a right angle; edge vector dot product is %g" % zero)
else:
print('rectangle')
A = [x1,y1,z1]
print(A)
B = [x2,y2,z2]
C = [x3,y3,z3]
D = [x4,y4,z4]
Verify(A, B, C, D, epsilon=0.0001)

Shortest keyboard distance typing

Can anyone help me with this problem?
We have a grid of MxN characters from some specific aplhabet, S={A,B,C,D} for example.
The cursor is positioned on (1,1) position, and we can move cursor using the arrow keys, up, down, left, right, and press enter to select the character ( just like selecting nick in old games ). What is minimum cost of operations where they are weighted same, (e.g. move right is equally costly as selecting the char) given some input string from aplhabet S? There can also be multiple occurences of the same character in the matrix.
Example:
alphabet S={A,B,C,D}
matrix :
ABDC
CADB
ABAA
and input string ADCABDA.
My incomplete solution would be:
Construct directed grid graph and find shortest path from 1,1 to end character, with inbetween characters similar to towns in TSP, and from optimal subpaths construct optimal final path using dynamic programming. Problem is that you could end with many possible end characters, and I totally have no idea how to construct longer optimal path from smaller optimal subpaths.
You should construct a graph with nodes something like this:
A1 A1 A1
A2 D1 C1 A2 B1 D1 A2
Start A3 D2 C2 A3 B2 D2 A3 End
A4 A4 B3 A4
A5 A5 A5
where there are edges connecting each node in a column to each node in the next column. Start is (1,1) and End is wherever. The edge weights are the "taxicab" distances between each pair of keys.
Now it's a fairly straightforward dynamic programming problem. You can start at either end; it's probably conceptually simpler to start at Start. Keep track of the minimum cost so far to reach each node.
You could use 3D dynamic programming, where each state is (x, y, l) - (x, y) representing current position and l representing what letter you are at.
To explain further. You start at position (0, 0, 0). First letter is "A". You can try all A's and we know that distance will be Manhattan distance (http://en.wikipedia.org/wiki/Taxicab_geometry). Solution for (0, 0, 0) would be minimum of all possibilities.
At each step repeat the above process. Note that importance of memorising each step. In the below sample code memo acts as function, you would use array in reality.
Here is sample pseudo-code:
f(x, y, l):
if memo(x, y, l) != -1:
return memo(x, y, l) # Check if already calculated.
if l == length(word):
return memo(x, y, l) = 0 # Ending condition.
memo(x, y, l) = inf
next_letter = word[l]
for each (x2, y2) in grid that contains next_letter:
distance = |x2 - x| + |y2 - y|
next_calc = f(x2, y2, l+1)
memo(x, y, l) = min(memo(x, y, l), distance + next_calc)
return memo(x, y, l)
Set all memo to -1, so we know that no states are calculated.
Solution is f(0, 0, 0).
Let me know which steps I need to clarify further.

Find the vertices of a line between two points with a given stroke width

I am currently trying to create a render of a path in clojure (although I am happy with answers in other languages if they're easy to understand). A simple explanation is that I want to draw a line between two points with a given thickness - however I only want to find vertices of the line so that I can output it to a Wavefront file (a 3d model file with the extension .obj).
So, for example given points A and B which can be joined up like so:
I wish to find points A1 and B1
This could also be thought of given a border to a shape. For example given A, B, C and D:
I would wish to find A1, B2, C1 and D1:
The actual shape would be much more complicated however and may have a few hundred points.
My original thought was to do an enlargement from the centre of the shape with a scale factor of less than 1, like so:
(defn shrink-pos [centre-x centre-y x y]
(let [diff-y (- y centre-y)
diff-x (- x centre-x)
dist (Math/sqrt (+ (* diff-y diff-y) (* diff-x diff-x)))
n-x (+ centre-x (* diff-x 0.8))
n-y (+ centre-y (* diff-y 0.8))]
[n-x n-y]))
Unfortunately this does not seem to work. The width of the border/stroke is not uniform and there is no border between the last point and the first which join to close the shape.
Is there a way to do this programmatically?
For 'thick' line:
Let's AB is vector from A to B.
ab is normalized (unit length) vector (vector normalization)
ab = normalized(AB)
p is perpendicular vector to ab
p.x = -ab.y, p.y = ab.x
needed points' coordinates:
B' = B + thickness * p
A' = A + thickness * p
For polygon offseting:
Let's two neighbour edges are AB and BC (intersecting in vertice B).
Find normalized (unit) vectors ab and cb.
Calc unit bisector vector
b = normalized(ab + cb)
Calc length of bisector segments as l=d/sin(fi)
where d is offset, and fi is angle between vectors b and ab.
It could be found as:
fi = atan2(crossproduct(b,ab), dotproduct(b,ab))
And find offset polygon vertice (for inner and outer offset polygons):
B' = B + l * b
B'' = B - l * b
P.S. Don't forget about inner polygon vertice vanishing for large offsets and weird loops for non-convex polygons

the graph in sage

I want define new graph in sage. Let G be finite group. The graph's vertices are subgroup and two vertices are adjacent if and only if sum of two subgroup is G.
I have trouble with define this graph in sage. Any suggestion?
I have idea in gap but I don't have idea what can I change in sage?
Summands := function(G)
local n, i, sgl, l, A, B, D;
obtain a list of all subgroups
sgl := List(LatticeSubgroups(G)!.conjugacyClassesSubgroups, Representative);
n is the number of divisors of |G|
n := Size(DivisorsInt(Size(G)));
D := [];
if IsOddInt(n) then l := QuoInt(n + 1, 2);
else l := QuoInt(n, 2);
fi;
for i in [1..l] do
for A in Filtered(sgl, function(g) return Size(g) = DivisorsInt(Size(G))[i]; end) do
for B in Filtered(sgl, function(g) return Size(g) = DivisorsInt(Size(G))[n+1-i]; end) do
Add(D, [A, B]);
od;
od;
od;
return D;
end;
Here are Sage equivalents to some of these commands. Incidentally, we use GAP for the group calculations!
sage: D = DihedralGroup(5)
sage: D.subgroups()
[Permutation Group with generators [()], Permutation Group with generators [(2,5)(3,4)], Permutation Group with generators [(1,2)(3,5)], Permutation Group with generators [(1,3)(4,5)], Permutation Group with generators [(1,4)(2,3)], Permutation Group with generators [(1,5)(2,4)], Permutation Group with generators [(1,2,3,4,5)], Permutation Group with generators [(1,5,4,3,2), (1,5)(2,4)]]
sage: divisors(D.cardinality())
[1, 2, 5, 10]
To make graphs in Sage, you can pass dictionaries of lists or other things; see
sage: Graph?
for more information on that.
Edit - left in to make comments comprehensible:
By the way, it looks like you are trying to make a list of pairs of subgroups A and B such that |A||B|=ord(G). Is that necessarily the same as groups whose sum (whatever you mean by that - direct sum?) is the original group? I'm thinking for instance of even a group of order four; summing any two subgroups of order two may not be isomorphic to the original group - for instance, if the two subgroups are the same one if you mean some sort of ambient sum (does this even make sense?), or if you use direct sum but the group is the cyclic group of order 4, not the Klein four group.

Resources