2

I'm writing a brute-force algorithm to solve vertex cover like this:

BruteForceVertexCover( Graph G = (V,E) ){
    for size= 1 ... |V|
        vector<int> v = {0...size-1}
        do{
            if(test(G, v)) return v;     //test if v covers G
        }
        while(v has next combinations of lenght size);
    return empty vector<int>;
}

//this stops when find a answer, and it will find,
//since it tries all combinations of all sizes

where

bool test( Graph G = (V,E), vector<int> v ){
    for each u in v:
        for each w in G[u]
            remove u from G[w]     //this is linear in size of vector G[w]
        clear G[v]                 //removed all (bidirectional) edges that have u
    for i = 0 ... |V|
        if(G[i] is not empty) return false;
        return true;
}

im trying this to lots of graphs (but their maximum size is 20 vertices) and this is taking a decade... is there any optimization I can do on this brute force so it run faster?

Daniel
  • 5,752
  • 4
  • 21
  • 48
  • 1
    There are at least 2. First, you can try to generate the vertex sets in a different order that minimises the number of changes from one set to the next (this would be Gray code order if you were not concerned about generating them in increasing size order), and also test each in time proportional to the number of differences from the previous set. Ideally this would take each iteration from O(n) to O(1). – j_random_hacker Oct 05 '16 at 06:22
  • Second, you can apply a technique called "meet in the middle" to reduce the time complexity from O\*(2^n) to O\*(2^(n/2)): divide the vertices arbitrarily into 2 sets A and B of size 10 each, then for each of the 2^10 subsets X of A, test whether it is a vertex cover of the subgraph induced by A. If so, determine which edges between A and B remain uncovered: each such edge immediately determines a vertex in B that must be included. Let Y be this "must-include" set of vertices in B. Update z[Y] to |X| if this is smaller than its current value (initially infinite). ... – j_random_hacker Oct 05 '16 at 06:49
  • ... After this, for any vertex set S for which at least 1 assignment to z[S] has been made, z[S] tells you the minimum number of vertices in A that need to be included in order to solve the overall problem under the constraint that at least the vertices in S (recall, these are all from B) are in the solution. What we would *like* to do now is to try each of the 2^10 subsets Y of B, and for each one that we find to be a vertex cover of the subgraph induced by B, somehow look up the smallest value w of z[S] such that S is a subset of Y, and check whether |Y|+w is the best solution so far, ... – j_random_hacker Oct 05 '16 at 07:04
  • ... but that lookup step cannot (TTBOMK) be done efficiently (i.e., in poly-time). What we *can* do is to consider all subsets Y of B in increasing size order, for each calculating |Y|+z[Y] and then, in addition to checking whether this Y solves B (and, if so, whether |Y|+z[Y] is the best overall solution so far), "pushing" this information about Y into every subset S of B that contains Y plus exactly 1 more element of B: that is, for every vertex x in B \ Y, updating z[Y u {x}] with |Y|+z[Y]+1 if this is smaller than its current value. This ensures each z[S] is ready by the time we need it. – j_random_hacker Oct 05 '16 at 07:19
  • @Daniel Can I see your actual code? I am working on the same problem – Khalil Khalaf Dec 15 '16 at 03:07
  • sure @KyleAbrahamJr. but it's not optimized: http://pastebin.com/SJVMA19P – Daniel Dec 22 '16 at 21:54

0 Answers0