EDIT: I found a solution thanks to the paper A survey of algorithms for calculating power indices of weighted majority games
I'd like to solve the following problem:
Given a set N={1,..,n} with a vector of weights W={w_1,..,w_n}, sorted in descending order and with total sum 1, find all subsets C (also called "coalitions") of N such that
- C is "winning", that means that the sum of the weights of elements inside the subset C exceeds a certain threshold (e.g. 0.5)
- C is "minimal", that means that removing any element from C will make the subset not "winning" anymore.
To clarify, an example could be: N={1,2,3} W={0.45,0.35,0.2}
- The "winning" subsets here are {1,2},{2,3},{1,3} and {1,2,3} since they all exceed 0.5 total weight
- only {1,2}, {2,3} and {1,3} are minimal, since in {1,2,3} you could remove one element and get the ones above.
From the paper cited above, I now implemented this code which recursively generates the list of all minimal winning coalitions
MWC = function(w,threshold=0.5){
n = length(w)
l = list()
enumerate = function(S1,n1,b1){
if(n1==n){
return(list(c(S1,n1)))
}else{
if(sum(w[(n1+1):n]) >= b1){
l = c(l,enumerate(S1,n1+1,b1))
}
if(w[n1] >= b1){
l=c(l,list(c(S1,n1)))
}else{
l = c(l,enumerate(c(S1,n1),n1+1,b1-w[n1]))
return(l)
}
}
}
return(enumerate(c(),1,threshold))
}
w = c(0.46,0.3,0.19,0.05)
MWC(w)
The code runs up to around n = 20, after the exponential complexity makes everything unfeasible.