I've faced with following problem: find the optimal edge coloring in a bipartite graph. I know that greedy coloring algorithm can sometimes not return the optimal number of colors. By 'greedy coloring algorithm' I mean: choose first vertex with the highest degree and color its edges on colors 1...degree, then choose the vertex with degree <= to the previous degree and color every of its incident edge on the first available number (the lowest number which is not used by its neighbour), the choose the next vertex etc.
But I've introduced one modification: the edges of first choosen vertex I color in descending order (degree...1), and edges of the next vertices as previously on 1...degree. This modification resulted in examples which I've come up I've got optimal number of colors. But I'm not pretty sure that it's always a rule. Does somebody know if this version of edge coloring algorithm is optimal, or maybe anyone is able to show any counterexample?
You can take your counterexample for the "naive" greedy algorithm and turn it into a counterexample for your "sophisticated" greedy algorithm. Simply insert dummy nodes with appropriate degree to "absorb" the backwards colorings. One can always fabricate a new node with degree n in an arbitrary part of the graph: simply insert n fresh nodes in the other part and connect them each by a single edge to the desired new node.
Since all nodes that get colored in descending order are freshly inserted, all the nodes in the original counterexample are colored in ascending order, hence get the same colors as they would have in the original "naive" greedy algorithm. Since the optimal coloring has at least as many colors as the degree of the original graph, and the freshly inserted nodes all have smaller degree than the original graph's maximal degree, the new graph does not need any more colors than the original. Therefore the coloring produced by the "sophisticated" algorithm -- which will still have more colors than necessary for the original graph -- is not optimal for the new graph.
For example, take the graph described in the comment below, which has nodes B,C,D on the left and E,F,G,H on the right. It has these edges:
B connects to E, F, and G
C connects to E, F, and G
D connects to G and H
For the moment, I will assume only the first node you touch gets colored in descending order. (For other nodes, it is not even clear what "descending order" might mean -- descending from what maximum? The degree of the node may not be high enough.)
Therefore, we insert a new node A on the left and three nodes I, J, and K on the right; the connectivity is now
A connects to I, J, and K
B connects to E, F, and G
C connects to E, F, and G
D connects to G and H
The sophisticated greedy algorithm will therefore color AI-3, AJ-2, AK-1, then proceed as the naive greedy algorithm on the remaining nodes.
Related
Question:
Given a graph G = (V,E) a k-coloring of G is a labeling of the vertices with the colors c_1, c_2, ..., c_k such that for every edge (u,v) the color of u is different from the color of v.
A. Give a linear time algorithm that finds a 2-coloring for a tree.
B. Think about coloring a tree with two colors so that you have the maximum number of nodes colored c_1. Prove that your algorithm from part (a), with a minor modification probably, can be used to solve this problem. Be precise.
C. Show an example of a tree, T, that can have at most j nodes colored c_1 in a 2-coloring but T can have j' > j nodes colored c_1 in a 3-coloring. Try to find the smallest example of such a tree T.
D. Give a linear time dynamic programming algorithm that creates a 3-coloring for a tree such that the maximum number of nodes are colored c_1. Justify your answer.
What I have:
Parts A and B seem rather simple, but I am struggling on C and D
A. This seems simple, run DFS, but modify it so if it
encounters an uncolored node color it c1 and its children c2,
encounters a colored node color its children the opposite color
if it ever tries to "flip" the color of a child, then return that it is impossible to have k-coloring
This is just DFS, so will run at O(V+E)
Edit: Since this a tree you can call BFS on a random node, alternating colors in the BFS
B. Since this is a binary first choice (ie c1 or c2) and all choices follow from the first choice, we can simply calculate which is superior coloring the first node c1 or c2. We can do this by adding a counter to the above algorithm calculating the number of c1 nodes. Run the algorithm twice once starting with c1, then with c2, compare the number of c1 nodes between the two, and then pick the graph with more c1 nodes
C. Been fiddling with this for a while and can't find a single one, much less the smallest one possible
Edit: 1-3, 2-3, 3-4, 4-5, 4-6 described by Bing Wang works here
D. No idea. I assume you are going to have to be using a modified DFS to have it run at linear, but am extremely unsure beyond that. I can come up with ways to brute force it, but nothing that runs at linear.
Edit: Still confused about this
c: 1-3, 2-3, 3-4, 4-5,4-6. This tree can have 3 nodes in each color in bi-color. But can have 4 nodes in the same color if you color node #3/#4 to two other colors - in a tri-color. You should be easily prove no smaller answer by going over all possibilities.
D: Just traverse the tree, e.g. DFS. Each node needs to keep c_1 count of all 3 colorings. WHen you deal with 1st node, that would be (1,0,0) - fairly easy count. Once you add the nodes into the visited, try all 3 colors, each color would be compatible with 2 colors of the connecting node, from which you pick the bigger one, etc, to construct the 3 values of current node.
E=[(1,3),(2,3),(3,4),(4,5),(4,6)]
V={v:set() for e in E for v in e}
[None if V[e[0]].add(e[1]) else V[e[1]].add(e[0]) for e in E]
serialized={}
def traverse(c):
serialized[c]=V[c]
[traverse(n) for n in V[c] if n not in serialized]
traverse(E[0][0])
visited=set()
for k,v in reversed(serialized.items()):
filtered=v.intersection(visited)
visited.add(k)
m=[1+sum(max([V[child][1],V[child][2]]) for child in filtered)
,sum(max([V[child][0],V[child][2]]) for child in filtered)
,sum(max([V[child][0],V[child][1]]) for child in filtered)]
V[k]=m
print(max(V[k]))
A. Pick any vertex and color it c1. Run BFS from there. Everything at an odd distance gets c2 and at an even distance gets c1.
B. There are only two colorings, and they differ only in swapping c1 for c2. Run (A) and swap if you need to.
C. Imagine A and B are connected, and a has a number of other neighbors which are all leaves, as does B. With 2 colors you can get one more than the size of A or B a given color, but with three you can give two different colors to A & B, and color all the leaves the same color. The count of leaves depends on the j an j' inputs. If we're finding the smallest values of j and j' possible, then give each two leaves. Then you can have four c1 leaves with A c2 and B c3, as opposed to a max of 3 with only two colors.
I've received a task to find an algorithm which divides a graph G(V,E) into pairs of neighboring edges (colors the graph, such that every pair of neighboring edges has the same color).
I've tried to tackle this problem by drawing out some random graphs and came to a few conclusions:
If a vertex is connected to 2(4,6,8...) vertices of degree 1, these make a pair of edges.
If a vertex of degree 1 is directly connected to a cycle, it doesn't matter which edge of the cycle is paired with the lone edge.
However, I couldn't come up with any other conclusions, so I tried a different approach. I thought about using DFS, finding articulation points and dividing graph into subgraphs with an even number of edges, because those should be dividable by this rule as well, and so on until I end up with only subgraphs of |E(G')| = 2.
Another thing I've come up with is to create a graph G', where E(G) = V(G') and V(G) = E(G'). That way I could get a graph, where I could remove pairs of vertices (former edges) either via DFS or always starting with leaf vertices along with their adjacent vertices.
The last technique is most appealing to me, but it seems to be the slowest one. Any feedback or tips on which of these methods would be the best is much appreciated.
EDIT: In other words, imagine the graph as a layout of a town. Vertices being crossroads, edges being the roads. We want to decorate (sweep, color) each road exactly once, but we can only decorate two connected roads at the same time. I hope this helps for clarification.
For example, having graph G with E={ab,bd,cd,ac,ae,be,bf,fd}, one of possible pair combinations is P={{ab,bf},{ac,cd},{ae,eb},{bd,df}}.
One approach is to construct a new graph G where:
A vertex in G corresponds to an edge in the original graph
An edge in G connects vertices a and b in G where a and b represent edges in the original graph that meet at a vertex in the original graph
Then, if I have understood the original problem correctly, the objective for G is to find the maximum matching, which can be done, for example, with the Blossom algorithm.
Given a graph G in which every edge connects an even degree node with an odd degree node. How can i prove that the graph is bipartite?
Thanks in advance
This is the Welsh-Powell graph colouring algorithm:
All vertices are sorted according to the decreasing value of their degree in a list V
Colours are ordered in a list C
The first non-coloured vertex v in V is coloured with the first available colour in C. "Available" means a colour that has not previously used by this algorithm
The remaining part of the ordered list V is traversed and the same colour is allocated to every vertex for which no adjacent vertex has the same colour
Steps 3 and 4 are applied iteratively until all the vertices have been coloured
A graph is bipartite if it is 2-colourable. This intuitive fact is proven in Cambridge Tracts in Mathematics 131.
This is, of course, the cannon with which to shoot a mosquito. A graph is bipartite iff its vertices can be divided into two sets, such that every edge connects a vertex from set 1 to one in set 2. You already have such a division: each edge connects a vertex from the set of odd-degree vertices, to a vertex in the set of even-degree vertices.
Because by definition you already have two disjoint sets of vertices such that the only edges go between a vertex in one set and a vertex in the other set.
The even degree nodes are one set, and the odd degree nodes are the other set.
Pick any node, put it in set A. Take all the nodes that link to it, put them in set B. Now for every node added, add all it's neighbors to the opposite set, and check for the ones that already belong to one of the sets that they are in the right set. If you get a contradiction then the graph is not bipartite.
If you run out of neighbors but there are still nodes left, pick again any node and continue the algorithm until you either have no nodes or you found a contradiction.
If by "prove", you mean "find out", the complete solution is here
Bipartite.java
It works by keeping two boolean arrays. A marked array to check if a node has been visited, and another colored array. It then does a depth first search, marking neighbors with alternate colors. If a neighbor is marked with same color, graph is not bipartite.
Given undirected, connected graph G={V,E}, a vertex in V(G), label him v, and a weight function f:E->R+(Positive real numbers), I need to find a MST such that v's degree is minimal. I've already noticed that if all the edges has unique weight, the MST is unique, so I believe it has something to do with repetitive weights on edges. I though about running Kruskal's algorithm, but when sorting the edges, I'll always consider edges that occur on v last. For example, if (a,b),(c,d),(v,e) are the only edges of weight k, so the possible permutations of these edges in the sorted edges array are: {(a,b),(c,d),(v,e)} or {(c,d),(a,b),(v,e)}. I've ran this variation over several graphs and it seems to work, but I couldn't prove it. Does anyone know how to prove the algorithm's correct (Meaning proving v's degree is minimal), or give a contrary example of the algorithm failing?
First note that Kruskal's algorithm can be applied to any weighted graph, whether or not it is connected. In general it results in a minimum-weight spanning forest (MSF), with one MST for each connected component. To prove that your modification of Kruskal's algorithm succeeds in finding the MST for which v has minimal degree, it helps to prove the slightly stronger result that if you apply your algorithm to a possibly disconnected graph then it succeeds in finding the MSF where the degree of v is minimized.
The proof is by induction on the number, k, of distinct weights.
Basis Case (k = 1). In this case weights can be ignored and we are trying to find a spanning forest in which the degree of v is minimized. In this case, your algorithm can be described as follows: pick edges for as long as possible according to the following two rules:
1) No selected edge forms a cycle with previously selected edges
2) An edge involving v isn't selected unless any edge which doesn't
involve v violates rule 1.
Let G' denote the graph from which v and all incident edges have been removed from G. It is easy to see that the algorithm in this special case works as follows. It starts by creating a spanning forest for G'. Then it takes those trees in the forest that are contained in v's connected component in the original graph G and connects each component to v by a single edge. Since the components connected to v in the second stage can be connected to each other in no other way (since if any connecting edge not involving v exists it would have been selected by rule 2) it is easy to see that the degree of v is minimal.
Inductive Case: Suppose that the result is true for k and G is a weighted graph with k+1 distinct weights and v is a specified vertex in G. Sort the distinct weights in increasing order (so that weight k+1 is the longest of the distinct weights -- say w_{k+1}). Let G' be the sub-graph of G with the same vertex set but with all edges of weight w_{k+1} removed. Since the edges are sorted in the order of increasing weight, note that the modified Kruskal's algorithm in effect starts by applying itself to G'. Thus -- by the induction hypothesis prior to considering edges of weight w_{k+1}, the algorithm has succeeded in constructing an MSF F' of G' for which the degree, d' of v in G' is minimized.
As a final step, modified Kruskal's applied to the overall graph G will merge certain of the trees in F' together by adding edges of weight w_{k+1}. One way to conceptualize the final step is the think of F' as a graph where two trees are connected exactly when there is an edge of weight w_{k+1} from some node in the first tree to some node in the second tree. We have (almost) the basis case with F'. Modified Kruskal's will add edged of weight w_{k+1} until it can't do so anymore -- and won't add an edge connecting to v unless there is no other way to connect to trees in F' that need to be connected to get a spanning forest for the original graph G.
The final degree of v in the resulting MSF is d = d'+d" where d" is the number of edges of weight w_{k+1} added at the final step. Neither d' nor d" can be made any smaller, hence it follows that d can't be made any smaller (since the degree of v in any spanning forest can be written as the sum of the number of edges whose weight is less than w_{k+1} coming into v and the number off edges of weight w_{k+1} coming into v).
QED.
There is still an element of hand-waving in this, especially with the final step -- but Stack Overflow isn't a peer-reviewed journal. Anyway, the overall logic should be clear enough.
One final remark -- it seems fairly clear that Prim's algorithm can be similarly modified for this problem. Have you looked into that?
For instance, suppose I have a graph G = (V, E) where
V = {A, B, C, D}
E = {(A, B), (A,D), (C, D)}
This graph is bipartite, and thus can be split into two disjoint sets {A, C} and {B, D}. My first guess is that I can simply walk the graph and assign alternating colors to each vertex. Is this the case, or is it more complicated/simpler than this? Are there any known algorithms for this?
Your first guess is correct - traverse the graph and alternate.
The algorithm should be simple. I'd keep two queues of nodes to visit, one for each colour. Pop nodes off the queues alternately, mark its colour, and push any non-visited adjacent nodes into the queue for the opposite colour. Terminate when the number of visited nodes + the length of both queues = number of nodes in the graph.
From Wikipedia (http://en.wikipedia.org/wiki/Bipartite_graph)
If a bipartite graph is connected, its bipartition can be defined by the parity of the distances from any arbitrarily chosen vertex v: one subset consists of the vertices at even distance to v and the other subset consists of the vertices at odd distance to v.
Thus, one may efficiently test whether a graph is bipartite by using this parity technique to assign vertices to the two subsets U and V, separately within each connected component of the graph, and then examine each edge to verify that it has endpoints assigned to different subsets.
Traverse the graph and alternate, if it doesn't succeded it means that your graph is not bipartite.
If you are sure that the graph is biparte, then you can just assign colors alternating them for traversing each vertex, as it holds that:
A graph is bipartite if and only if it is 2-colorable.
I implemented it in my graph drawing tool, you can see my code in JavaScript.
I just marked first vertex as left partity, then recursively marked it's neighbours as right partity, recursively mark their neighbours as left partity... If you find correctly marked node, stop recursion of this branch. If you find uncorrectly marked node, graph is not bipartite.
Maybe it can be done simpler, but during last few months I had some hard Prolog - Haskell coding days, maybe it had affected my brain and now I see recursion in everything :-D
Just in case anyone's curious, here's the code I came up with:
def dfs(root, colorings):
to_visit1 = deque()
to_visit2 = deque()
to_visit1.append(root)
while len(to_visit1) != 0 or len(to_visit2) != 0:
dfs_color(to_visit1, to_visit2, True, colorings)
dfs_color(to_visit2, to_visit1, False, colorings)
def dfs_color(queue, opposite_queue, color, colorings):
while len(queue) != 0:
v = queue.pop()
if v in adjacency_list:
colorings[v] = color
neighbors = adjacency_list[v]
del adjacency_list[v]
for neighbor in neighbors:
opposite_queue.append(neighbor)
Admittedly, this isn't my best code. I'm using True/False as the color because when I used recursion, it made it easy to just say not color. Of course, I had to change it because I blew my stack on bigger graphs. Also to give credit where due, this code is based on the wikipedia code for DFS.
Although as has been pointed out, I think this may just be a disguised BFS.