import numpy as np
from typing import List, Tuple, Callable
class AggregationTester:
def __init__(self):
self.test_cases = {
"balanced": [0.8, 0.7, 0.9, 0.75, 0.85], "weak_link": [0.9, 0.85, 0.4, 0.88, 0.92], "strong_team": [0.95, 0.92, 0.88, 0.90, 0.94], "mixed": [0.6, 0.7, 0.5, 0.75, 0.65], }
self.results = {}
def min_bottleneck(self, empathies: List[float]) -> float:
return min(empathies)
def harmonic_mean(self, empathies: List[float]) -> float:
if not empathies:
return 0.7
return len(empathies) / sum(1/e for e in empathies)
def weighted_min_mean(self, empathies: List[float], alpha: float = 0.7) -> float:
return alpha * min(empathies) + (1 - alpha) * np.mean(empathies)
def percentile_75(self, empathies: List[float]) -> float:
return np.percentile(empathies, 75)
def exponential_blend(self, empathies: List[float]) -> float:
return (min(empathies)**0.5 + np.mean(empathies)**0.5) / 2
def alpha_cut(self, empathies: List[float], threshold: float = 0.6) -> float:
min_val = min(empathies)
if min_val >= threshold:
return np.mean(empathies)
else:
return min_val * 1.2
def product_cascade(self, empathies: List[float]) -> float:
if len(empathies) >= 2:
return empathies[0] * empathies[1]
return empathies[0] if empathies else 0.5
def geometric_mean(self, empathies: List[float]) -> float:
if not empathies:
return 0.5
product = np.prod(empathies)
return product ** (1 / len(empathies))
def weighted_product(self, empathies: List[float], w1: float = 0.7) -> float:
if len(empathies) >= 2:
return empathies[0]**w1 * empathies[1]**(1-w1)
return empathies[0] if empathies else 0.5
def confidence_blend(self, empathies: List[float], beta: float = 0.6) -> float:
if len(empathies) >= 2:
product = empathies[0] * empathies[1]
mean = np.mean(empathies)
return beta * product + (1 - beta) * mean
return empathies[0] if empathies else 0.5
def logarithmic_decay(self, empathies: List[float]) -> float:
if len(empathies) >= 2:
log_product = sum(np.log(e) for e in empathies[:2])
return np.exp(log_product / 2) return empathies[0] if empathies else 0.5
def harmonic_decay(self, empathies: List[float], alpha: float = 0.3) -> float:
if len(empathies) >= 2:
return empathies[0] - alpha * (1 - empathies[1])
return empathies[0] if empathies else 0.5
def test_c2_001_methods(self):
print("\n" + "="*80)
print("C2_001 ROBUSTNESS - AGGREGATION METHODS")
print("="*80)
methods = {
"min (current)": self.min_bottleneck,
"harmonic_mean": self.harmonic_mean,
"weighted_min_mean": self.weighted_min_mean,
"percentile_75": self.percentile_75,
"exponential_blend": self.exponential_blend,
"alpha_cut": self.alpha_cut,
}
results = {}
for case_name, empathies in self.test_cases.items():
print(f"\n{case_name.upper()}: {[f'{e:.2f}' for e in empathies]}")
case_results = {}
for method_name, method in methods.items():
score = method(empathies)
case_results[method_name] = score
print(f" {method_name:20s}: {score:.3f}")
results[case_name] = case_results
return results
def test_c2_002_methods(self):
print("\n" + "="*80)
print("C2_002 TRANSITIVE - AGGREGATION METHODS")
print("="*80)
methods = {
"product (current)": self.product_cascade,
"geometric_mean": self.geometric_mean,
"weighted_product": self.weighted_product,
"confidence_blend": self.confidence_blend,
"logarithmic_decay": self.logarithmic_decay,
"harmonic_decay": self.harmonic_decay,
}
results = {}
for case_name, empathies in self.test_cases.items():
print(f"\n{case_name.upper()}: {[f'{e:.2f}' for e in empathies[:2]]}")
case_results = {}
for method_name, method in methods.items():
score = method(empathies)
case_results[method_name] = score
print(f" {method_name:20s}: {score:.3f}")
results[case_name] = case_results
return results
def recommend_best(self, c2_001_results, c2_002_results):
print("\n" + "="*80)
print("RECOMMENDATIONS")
print("="*80)
c2_001_avg = {}
c2_002_avg = {}
for method in c2_001_results["balanced"].keys():
scores = [c2_001_results[case][method] for case in self.test_cases.keys()]
c2_001_avg[method] = np.mean(scores)
for method in c2_002_results["balanced"].keys():
scores = [c2_002_results[case][method] for case in self.test_cases.keys()]
c2_002_avg[method] = np.mean(scores)
best_c2_001 = max(c2_001_avg.items(), key=lambda x: x[1])
best_c2_002 = max(c2_002_avg.items(), key=lambda x: x[1])
print(f"\nC2_001 Best: {best_c2_001[0]} ({best_c2_001[1]:.3f})")
print(f"C2_002 Best: {best_c2_002[0]} ({best_c2_002[1]:.3f})")
current_c2_001 = 0.70 current_c2_002 = 0.42 current_c2_003 = 0.822 current_level_2 = (current_c2_001 + current_c2_002 + current_c2_003) / 3
new_level_2 = (best_c2_001[1] + best_c2_002[1] + current_c2_003) / 3
print(f"\nLevel 2 Impact:")
print(f" Current: {current_level_2:.3f}")
print(f" Potential: {new_level_2:.3f}")
print(f" Improvement: +{(new_level_2 - current_level_2):.3f}")
level_1 = 0.832
level_3 = 0.817
overall_current = (level_1 + current_level_2 + level_3) / 3
overall_new = (level_1 + new_level_2 + level_3) / 3
print(f"\nOverall Impact:")
print(f" Current: {overall_current:.3f}")
print(f" Potential: {overall_new:.3f}")
print(f" Improvement: +{(overall_new - overall_current):.3f}")
return {
"best_c2_001": best_c2_001,
"best_c2_002": best_c2_002,
"new_level_2": new_level_2,
"new_overall": overall_new,
}
if __name__ == "__main__":
tester = AggregationTester()
c2_001_results = tester.test_c2_001_methods()
c2_002_results = tester.test_c2_002_methods()
recommendations = tester.recommend_best(c2_001_results, c2_002_results)
print("\n" + "="*80)
print(f"✅ Testing complete. See recommendations above.")
print("="*80)