-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
df27c86
commit c4625da
Showing
9 changed files
with
126 additions
and
373 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import itertools | ||
import min_cut_solvers | ||
|
||
|
||
def get_coalition_value(coalition, induced_subgraph_game): | ||
agents = coalition.split(',') | ||
return sum([induced_subgraph_game[','.join(map(str,sorted(map(int,key))))] for key in itertools.combinations(agents, 2)]) | ||
|
||
|
||
def evaluateSplits_min_cut(coalition, induced_subgraph_game, min_cut_solver = min_cut_solvers.min_cut_brute_force, **kwargs): | ||
#print("coalition",coalition,end='=') | ||
agents = coalition.split(',') | ||
n = len(agents) | ||
if n==1: | ||
return [coalition], 0 | ||
if n==2: | ||
c_value = induced_subgraph_game[coalition] | ||
if c_value<=0: | ||
#print([agents[0],agents[1]], 0) | ||
return [agents[0],agents[1]], 0 | ||
else: | ||
#print([coalition], c_value) | ||
return [coalition], c_value | ||
min_cut_mapping = {} | ||
for idx,agent in enumerate(agents): | ||
min_cut_mapping[agent] = str(idx+1) | ||
subproblem_as_induced_subgraph_game = {','.join([min_cut_mapping[vertex] for vertex in map(str,sorted(map(int,key)))]):induced_subgraph_game[','.join(map(str,sorted(map(int,key))))] for key in itertools.combinations(agents, 2)} | ||
xbest_brute, best_cost_brute = min_cut_solver(n,subproblem_as_induced_subgraph_game, **kwargs) | ||
if 0 in xbest_brute and 1 in xbest_brute: | ||
first_half = ','.join([agent for idx,agent in enumerate(agents) if xbest_brute[idx]]) | ||
second_half = ','.join([agent for idx,agent in enumerate(agents) if not xbest_brute[idx]]) | ||
bruteforce_solution_decoded = [first_half, second_half] | ||
best_cost_brute = get_coalition_value(first_half, induced_subgraph_game) + get_coalition_value(second_half, induced_subgraph_game) | ||
else: | ||
bruteforce_solution_decoded = [coalition] | ||
best_cost_brute = get_coalition_value(coalition, induced_subgraph_game) | ||
#print(bruteforce_solution_decoded, best_cost_brute) | ||
return bruteforce_solution_decoded, best_cost_brute | ||
|
||
|
||
def gcs(induced_subgraph_game, min_cut_solver = min_cut_solvers.min_cut_brute_force, **kwargs): | ||
grand_coalition = ','.join(map(str,sorted(map(int,(set([key.split(',')[i] for i in range(2) for key in induced_subgraph_game])))))) | ||
temp = [grand_coalition] | ||
optimal_cs = [] | ||
while(len(temp)): | ||
c = temp.pop() | ||
c_split_t,c_split_f = evaluateSplits_min_cut(c, induced_subgraph_game, min_cut_solver = min_cut_solver, **kwargs) | ||
if len(c_split_t)==1: | ||
optimal_cs+=c_split_t | ||
if len(c_split_t)>1: | ||
temp += c_split_t | ||
return optimal_cs, sum([get_coalition_value(c, induced_subgraph_game) for c in optimal_cs]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import math | ||
import itertools | ||
|
||
import min_cut_solvers | ||
|
||
def evaluateSplits(coalition, coalition_values, **kwargs): | ||
#print("coalition",coalition,end='=') | ||
agents = coalition.split(',') | ||
n_agents = len(agents) | ||
best_cost_brute = f[coalition] | ||
xbest_brute = [coalition] | ||
for b in range(1, 2**(n_agents-1)): | ||
x = [int(term) for term in reversed(list(bin(b)[2:].zfill(n_agents)))] | ||
first_half = ','.join([agent for i,agent in enumerate(agents) if int(x[i])]) | ||
second_half = ','.join([agent for i,agent in enumerate(agents) if not int(x[i])]) | ||
if best_cost_brute <= (f[first_half]+f[second_half]): | ||
best_cost_brute = f[first_half]+f[second_half] | ||
xbest_brute = [first_half, second_half] | ||
#print(xbest_brute, best_cost_brute) | ||
return xbest_brute, best_cost_brute | ||
|
||
|
||
def idp(coalition_values, evaluateSplits = evaluateSplits, min_cut_solver = min_cut_solvers.min_cut_brute_force, **kwargs): | ||
n_agents = math.ceil(math.log(len(coalition_values),2)) | ||
global t | ||
t = {} | ||
global f | ||
f = {} | ||
for coalition,coalition_value in coalition_values.items(): | ||
t[coalition] = [coalition] | ||
f[coalition] = coalition_value | ||
for coalition_size in range(2, n_agents): | ||
if((math.ceil((2*n_agents)/3)<coalition_size) and (coalition_size < n_agents)): # Ignoring this condition will make this function work as DP instead of IDP | ||
continue | ||
coalitions_of_cur_size = list(itertools.combinations(map(str,range(1,n_agents+1)), coalition_size)) | ||
for curCoalition in coalitions_of_cur_size: | ||
curCoalition = ','.join(curCoalition) | ||
split_t, split_f = evaluateSplits(curCoalition, coalition_values, min_cut_solver = min_cut_solver, **kwargs) | ||
if split_f > f[curCoalition]: | ||
t[curCoalition] = split_t | ||
f[curCoalition] = split_f | ||
grand_coalition = ','.join(map(str,range(1,n_agents+1))) | ||
|
||
split_t, split_f = evaluateSplits(grand_coalition, coalition_values, min_cut_solver = min_cut_solver, **kwargs) | ||
if split_f > f[grand_coalition]: | ||
t[grand_coalition] = split_t | ||
f[grand_coalition] = split_f | ||
temp = t[grand_coalition].copy() | ||
optimal_cs = [] | ||
while(len(temp)): | ||
C = temp.pop() | ||
if len(t[C])==1: | ||
optimal_cs+=t[C] | ||
if(len(t[C])!=1): | ||
temp += t[C] | ||
optimal_cs_value = sum([f[coalition] for coalition in optimal_cs]) | ||
return optimal_cs, optimal_cs_value |
Oops, something went wrong.