5

Here is an excise:

Consider the problem of finding a minimum weight connected subset T of edges from a weighted connected graph G. The weight of T is the sum of all the edge weights in T.Give an efficient algorithm to compute the minimum weight connected subset T.

Here are what I have got:

  1. I have to assume the weights are mixed by both positive and negative ones. Only the mix of both kinds of weights can make sense for this excise.

  2. I will sort the edges first, so the negative edges will come first.

  3. I will consider utilise Kruskal's algorithm, but should be with some modifications

  4. Because I welcome negative edges, I will try to add as many negative edges as possible.

  5. In addition, some positive edges may be added to just in case that not all negative edges are connected and they may need some positive edges as bridges.


Ok, above is my thinking. But when I try to get my hands dirty, I get stuck.

How can I always record the possible minimum weights set?

For example,

{0, 1} is with weight -20

{2, 3} is with weight -10

if {1, 3} has weight of 11, then of course I don't want {1, 3}

or if {1, 3} has weight of 9, then I want

With what kind of data structure I can always keep the minimum weight and the vertices for that weight?


It is worth to note that the subset this excise seeks for aim at edges.

Consider the problem of finding a minimum weight connected subset T of edges from a weighted connected graph G

This means that all vertices still need to be included.

Also it is more than a MST. Consider that if a vertex has two edges, one is -1, another is -2. In a normal MST algorithm, only edge of -2 will be taken. But in this excise, both -1 and -2 need to be taken to reduce the overall weight further.

Jackson Tale
  • 25,428
  • 34
  • 149
  • 271
  • You can do it with a little variation on disjoint set data structure, see my answer on [Kruskal algorithm](http://stackoverflow.com/questions/9459938/testing-for-a-circuit-when-implementing-kruskalls-algorithm/9960713#9960713). – Saeed Amiri May 02 '12 at 23:15
  • @SaeedAmiri, I think it is a little more than Kruskal algorithm. What variation you suggest? – Jackson Tale May 03 '12 at 11:04
  • If you understand Kruskal algorithm, variation is easy, just you should keep the weights of forests. – Saeed Amiri May 03 '12 at 12:05
  • @SaeedAmiri Yeah, I find out that I understood the excise in a wrong way and that's causes my problem. – Jackson Tale May 03 '12 at 12:24

1 Answers1

8

I think your algorithm is mostly correct already, but with slight modifications it becomes trivial to implement.

First, every negative edge has to be included in order to minimize the resulting weight. Next, calculate the number of connected components c. If c=1, you're done. Otherwise you need extra c-1 positive edges.

Now, while you were adding negative edges, consider this already as a Kruskal's algorithm process. Every negative edges may unite a couple of trees in the Kruskal's forest. However, you add the negative edge even if its ends belong to the same tree in the Kruskal's forest — unlike the usual Kruskal's algorithm where you only add those edges that unite two different trees.

After this phase, you're left with a graph of c connected components (they may not be trees anymore). Now just continue the Kruskal's algorithm as usual. Process the positive edges in the increasing order, keeping track of the number of unions the you've made with positive edges. Once this number gets to c-1, you're done.

By the way, all the process of Kruskal's algorithm can be implemented easily if you represent the forest as disjoint-set data structure. It requires just a couple of lines of code to write, and after that it is trivial to keep track of the number of unions that were made.


Some pseudocode follows:

sort(edges);
c := n;
for edge in edges:
    if edge.weight < 0:
        if find(edge.firstEnd) != find(edge.secondEnd):
            --c;
        unite(edge.firstEnd, edge.secondEnd);
    else:
        if c == 1: break;
        if find(edge.firstEnd) != find(edge.secondEnd):
            unite(edge.firstEnd, edge.secondEnd);
            --c;

Here unite and find are the functions of disjoint-set data structure.

Skiminok
  • 2,801
  • 1
  • 24
  • 29
  • I think there is a flaw in your algorithm. `every negative edge has to be included in order to minimize the resulting weight`, I don't think it is true because not every negative edges are connected together, and sometimes it needs positive edges to connect them. If those positive edges have large weights, the overall weight maybe even bigger than a single negative edge – Jackson Tale May 03 '12 at 07:46
  • @JacksonTale Your primary goal is to make the resulting subgraph connected. If you require positive edges to make your subgraph connected, then you require it anyway, and you have to include them even if they are large. Your secondary goal is minimizing the overall weight. Note that the overall weight need not to be negative, it just has to be minimal. Assume there exists a connected subgraph which does not include all the negative edges from the original graph. Then you can pick any non-included negative edge, add it to the graph, and the overall sum of all the edges included will decrease. – Skiminok May 03 '12 at 08:48
  • Sorry, I don't think so. for example, {0, 1} is with weight -20, {2, 3} is with weight -10, if edge {1, 3} has weight of 100, I would rather include {0, 1} only, because the overall weight is -20, right? if I do like you said, then the overall weight is 100-20-10=70. – Jackson Tale May 03 '12 at 11:01
  • In the excise, it is a minimum weight connected subset. It is subset, which means it does not need to include all vertices. Instead, you just find all connected vertices, total of whose edges are minimum. right? – Jackson Tale May 03 '12 at 11:03
  • @JacksonTale OK, I need a clarification now. Does the minimum weight connected subset have to include all the vertices of the original graph? I inferred from your problem description that it does. – Skiminok May 03 '12 at 11:13
  • Well, I am not sure. I just see it is "subset", then I assume that it doesn't need to have all vertices. Otherwise, it is just like finding a minimum spanning tree, right? – Jackson Tale May 03 '12 at 11:15
  • I think I am wrong, very sorry. `Consider the problem of finding **a minimum weight connected subset T of edges** from a weighted connected graph G`, it says subset of edges. So all vertices should be included. I am wrong. So, then what's the difference between this and finding MST? – Jackson Tale May 03 '12 at 11:17
  • @JacksonTale Then basically this is MST + all negative edges, as I desribed :) – Skiminok May 03 '12 at 11:34
  • lol sorry for the confusion I produced. But does a MST automatically include all negative edges? – Jackson Tale May 03 '12 at 11:43
  • @JacksonTale Not necessarily. A graph can contain more than `n-1` negative edges. In this case MST consists of `n-1` edges, all of them negative, but including extra negative edges to the MST decreases its weight even more. This is the only case when your minimal weight connected subset is not a tree. – Skiminok May 03 '12 at 11:47
  • Yeah, ok, thanks. I will mark your answer as correct now. thanks for your help, indeed. – Jackson Tale May 03 '12 at 11:49