-1

I have 77 elements n1,n2,n3... etc I need to calculate superset. I used the binary mask algorithme but the number is to big to fit in int. Here is the code:

private static Vector powerset(String[] set) {

       //create the empty power set
       Vector power = new Vector();

       //get the number of elements in the set
       int elements = set.length;

       //the number of members of a power set is 2^n
       int powerElements = (int) Math.pow(2,elements);

       //run a binary counter for the number of power elements
       for (int i = 0; i < powerElements; i++) {

           //convert the binary number to a string containing n digits
           String binary = intToBinary(i, elements);

           //create a new set
           Vector innerSet = new Vector();

           //convert each digit in the current binary number to the corresponding element
            //in the given set
           for (int j = 0; j < binary.length(); j++) {
               if (binary.charAt(j) == '1')
                   innerSet.add(set[j]);
           }

           //add the new set to the power set
           power.add(innerSet); 
       }
       return power;
   }
   private static String intToBinary(int binary, int digits) {

       String temp = Integer.toBinaryString(binary);
       int foundDigits = temp.length();
       String returner = temp;
       for (int i = foundDigits; i < digits; i++) {
           returner = "0" + returner;
       }

       return returner;
   } 

I tried to remove the int by using long or double, but nothing worked.

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
sdx11
  • 181
  • 1
  • 1
  • 9
  • What do you mean by "calculate every possible set"? Please be more specific. – Turing85 May 28 '16 at 17:43
  • You realise that 2^77 is quite a large number? – Oliver Charlesworth May 28 '16 at 17:49
  • yes i do and i need that much – sdx11 May 28 '16 at 17:52
  • 77 represent a numbers of node in graph – sdx11 May 28 '16 at 17:53
  • 3
    Abandon this plan. The resulting set will not fit in all computer memory ever created. Depending on what you're going to do with this, there may be other useful (implicit) representations of that set though, for example based on ZDDs. – harold May 28 '16 at 17:55
  • i can't the result isn't going to be stored ,i need the result for comparision – sdx11 May 28 '16 at 18:07
  • 1
    @dodomoh - Try calculating how long it would take to compute 2^77 things. – Oliver Charlesworth May 28 '16 at 18:11
  • i think it will take a few days – sdx11 May 28 '16 at 18:14
  • 1
    @dodomoh On my machine, I can do roughly 4 billion *simple* calculations in 1 second. That is `2^32` in 1 second. There are `86400` seconds in a day, `31536000` in a year. That's roughly `2^25` (`33554432`) seconds per year. So `2^(32+25) = 2^57` calculations will take one year. That means `2^77` will take `2^20` years, i.e. **one million years**. *"a few days", yeah, right.* – Andreas May 28 '16 at 18:32
  • @Andreas thank you for making it the clear that "a few days" is not enough. – sdx11 May 28 '16 at 21:02

2 Answers2

1

You need a data structure storing binary digits that is 77 digits long. You could use an array of 77 ints and manually increment the array as one big binary number where each element of the array is one bit in your number. I wrote the Increment method below.

int[] num = new int[77];
for (int i = 0; i < 77; i++) num[i]= 0;
//create a new set
for (int i = 0; i < powerElements; i++) {
    Vector innerSet = new Vector();

    for (int j = 0; j < 77; j++) {
        if (num[i] == 1)
            innerSet.add(set[j]); 
    }
    Increment(num);
}

// Increment an array of ints as if it is a binary number. The LSB is the 77th element in the array, index 76.
public void Increment(int[] num) {
    int carry = 1;
    int i = 76;
    while (i > 0) {
        tmp = int[i] + carry;
        if (tmp == 0) break;
        if (tmp == 1) {int[i] = 1; break;}
        carry = 1;
        int[i] = 0;
        i--;
    }
    if (carry == 1) throw new Exception("Overflow");
}

As noted by commenters, you won't have room to store 2^77 sets. And it will take virtually forever to count up to 2^77.

nicomp
  • 4,344
  • 4
  • 27
  • 60
  • thank @nicomp but the sets won't be stored at all,it will be used in comparition finding the max clique in graph and 77 represent numbers of nodes tkank you for the answer i will to make use of the code – sdx11 May 28 '16 at 18:18
  • @dodomoh while it's true that Max Clique is NP-hard so there's probably no polynomial time algorithm to do it, you can do a lot better than trying literally every subset. – harold May 28 '16 at 18:44
  • @harold thank you for the comment but can you explain further how to implement another algorithm – sdx11 May 28 '16 at 20:57
  • @dodomoh which one would you like? There are some tricks with backtracking (some pruning), you could use ILP, or SAT (does not find k directly, but for any k you can test whether there is a clique of size k) – harold May 29 '16 at 14:36
  • @harold could you explain ILP and SAT and if you have url to documentation that would be great thank you – sdx11 May 29 '16 at 15:24
1

From the comments it become clear this is to find the maximum clique, so I will now focus on that instead of on the literal question.

First some simple tricks. With backtracking, many branches of the search space can be pruned. The rough idea looks like

findMaxClique(clique, banned, graph):
    if clique ∪ banned is everything:
        if isclique(clique) and size(clique) > size(bestFound):
            bestFound = clique
        return
    for each node n not in clique ∪ banned:
        try findMaxClique(clique + n, banned, graph)
        try findMaxClique(clique, banned + n, graph)

This is still the naive version, trying every possible subset. But there are some obvious improvements. For example, there's no point in waiting to test whether the potential clique is actually a clique until the last moment, every subset of nodes that form a clique also form a clique. Adding a node to it that doesn't leave it a clique is pointless. Call this #1. This prunes a lot.

Also, if the current clique plus the nodes that could possible be added to it is less than the best found clique, nothing better can be found in this branch of the search space. There are several different levels of effort you can do here, the simplest is just counting all in the leftover set, but you could go for the biggest clique in that set or something. Anyway I'll show the simple one, call it #2. Now we have something like:

findMaxClique(clique, banned, graph):
    if clique ∪ banned is everything:
        if size(clique) > size(bestFound):
            bestFound = clique
        return
    for each node n not in clique ∪ banned:
        if isclique(clique + n):
            try findMaxClique(clique + n, banned, graph)
        notbanned = graph - (banned ∪ n)
        if size(notbanned) >= size(bestFound):
            try findMaxClique(clique, banned + n, graph)

An other option to estimate the size of clique you could build is to use linear programming.

For example, this is an ILP model for max clique:

maximize sum x[i]
s.t.
for each i,j that are not adjacent, x[i]+x[j] ≤ 1
x[i] in { 0, 1 }

The linear relaxation (ie dropping the last constraint) of that is easy to compute, and you can lazily add the constraints if you want. Obviously there are constraints coming from the clique/banned sets, forcing certain x's to be 1 or 0 respectively. If the objective value of the linear relaxation is not better than your biggest found clique, then you can prune the current branch.

There are an other fun property of that model. If the resulting x has all entries from {0, 0.5, 1}, then you can immediately decide to pick all nodes for which x[i] = 1 to be in your clique, so you can skip a lot of branching in that case. This is probably uncommon high in the search tree, but you can add some Gomory cuts to encourage integrality. Your favourite LP solver may have them built in.

There are more clever tricks here, check the literature.

A completely different way to attack the problem is with SAT, which does not optimize at all, but you can try every size of clique and for every size use SAT to ask whether there is a clique of that size (and if it exists, what it looks like). Actually it's easiest as a Pseudo boolean model:

for each i,j that are not adjacent: ¬i + ¬j ≥ 1
sum of everything = k

The usual adjacency constraint is trivial to state in pure SAT, the sum constraint is annoying, requiring an addition circuit. That's easy enough to generate, but hard to write out here, not only because it depends on k.

harold
  • 61,398
  • 6
  • 86
  • 164
  • i implementing the Bron Kerbosch take look what i have done (stackoverflow.com/questions/37524112/bron-kerbosch-implementation-in-java) – sdx11 May 30 '16 at 11:35