"how numbers are stored and used in computers"
The Maximum Weighted Clique (MWC) problem is an extension of the Maximum Clique problem where each vertex has an associated weight. The goal is to find a clique (a fully connected subgraph) with the maximum total weight.
Given an undirected graph
The MWC problem is NP-hard, being a generalization of the already NP-hard maximum clique problem. The problem becomes even more challenging with weights, as the greedy strategies that work well for unweighted cases may perform poorly.
code.py1def max_weighted_clique(graph, weights): 2 n = len(graph) 3 best_weight = 0 4 best_clique = [] 5 6 def is_connected_to_all(vertex, clique): 7 return all(graph[vertex][v] for v in clique) 8 9 def branch_and_bound(candidates, current_clique, current_weight): 10 nonlocal best_weight, best_clique 11 12 # Update best solution if current is better 13 if current_weight > best_weight: 14 best_weight = current_weight 15 best_clique = current_clique.copy() 16 17 # Upper bound calculation 18 potential = current_weight + sum(weights[v] for v in candidates) 19 if potential <= best_weight: 20 return 21 22 # Try adding each candidate 23 for v in candidates: 24 if is_connected_to_all(v, current_clique): 25 new_candidates = [u for u in candidates 26 if u > v and graph[v][u]] 27 branch_and_bound(new_candidates, 28 current_clique + [v], 29 current_weight + weights[v]) 30 31 initial_candidates = list(range(n)) 32 branch_and_bound(initial_candidates, [], 0) 33 return best_clique, best_weight
code.py1def greedy_weighted_clique(graph, weights): 2 n = len(graph) 3 clique = [] 4 vertices = list(range(n)) 5 # Sort vertices by weight 6 vertices.sort(key=lambda v: weights[v], reverse=True) 7 8 for v in vertices: 9 # Check if v can be added to clique 10 if all(graph[v][u] for u in clique): 11 clique.append(v) 12 13 return clique, sum(weights[v] for v in clique)
This technique uses graph coloring to improve the upper bound:
code.py1def color_based_bound(graph, weights, vertices): 2 colors = {} 3 weight_bounds = [] 4 5 for v in vertices: 6 # Find first available color 7 used_colors = {colors[u] for u in graph[v] 8 if u in colors} 9 color = 0 10 while color in used_colors: 11 color += 1 12 colors[v] = color 13 14 # Update weight bounds for each color 15 while len(weight_bounds) <= color: 16 weight_bounds.append(0) 17 weight_bounds[color] = max(weight_bounds[color], 18 weights[v]) 19 20 return sum(sorted(weight_bounds, reverse=True))
Graph Representation
Weight Handling
Performance Optimization
Exact Solution (Branch and Bound)
Greedy Approximation
Color-based Branch and Bound
Where
Approximation Hardness
Special Cases
Input Validation
Solution Verification
Performance Monitoring