161 lines · 4.5 KB · Python
RawDownload
"""Multi-criteria decision making example using pymoo. This script demonstrates how to select preferred solutions froma Pareto front using various MCDM methods.""" from pymoo.algorithms.moo.nsga2 import NSGA2from pymoo.problems import get_problemfrom pymoo.optimize import minimizefrom pymoo.mcdm.pseudo_weights import PseudoWeightsfrom pymoo.visualization.scatter import Scatterfrom pymoo.visualization.petal import Petalimport numpy as np  def run_optimization_for_decision_making():    """Run optimization to obtain Pareto front."""     print("Running optimization to obtain Pareto front...")     # Solve ZDT1 problem    problem = get_problem("zdt1")    algorithm = NSGA2(pop_size=100)     result = minimize(        problem,        algorithm,        ('n_gen', 200),        seed=1,        verbose=False    )     print(f"Obtained {len(result.F)} solutions in Pareto front\n")     return problem, result  def apply_pseudo_weights(result, weights):    """Apply pseudo-weights MCDM method."""     print(f"Applying Pseudo-Weights with weights: {weights}")     # Normalize objectives to [0, 1]    F_norm = (result.F - result.F.min(axis=0)) / (result.F.max(axis=0) - result.F.min(axis=0))     # Apply MCDM    dm = PseudoWeights(weights)    selected_idx = dm.do(F_norm)     selected_x = result.X[selected_idx]    selected_f = result.F[selected_idx]     print(f"Selected solution (decision variables): {selected_x}")    print(f"Selected solution (objectives): {selected_f}")    print()     return selected_idx, selected_x, selected_f  def compare_different_preferences(result):    """Compare selections with different preference weights."""     print("="*60)    print("COMPARING DIFFERENT PREFERENCE WEIGHTS")    print("="*60 + "\n")     # Define different preference scenarios    scenarios = [        ("Equal preference", np.array([0.5, 0.5])),        ("Prefer f1", np.array([0.8, 0.2])),        ("Prefer f2", np.array([0.2, 0.8])),    ]     selections = {}     for name, weights in scenarios:        print(f"Scenario: {name}")        idx, x, f = apply_pseudo_weights(result, weights)        selections[name] = (idx, f)     # Visualize all selections    plot = Scatter(title="Decision Making - Different Preferences")    plot.add(result.F, color="lightgray", alpha=0.5, s=20, label="Pareto Front")     colors = ["red", "blue", "green"]    for (name, (idx, f)), color in zip(selections.items(), colors):        plot.add(f, color=color, s=100, marker="*", label=name)     plot.show()     return selections  def visualize_selected_solutions(result, selections):    """Visualize selected solutions using petal diagram."""     # Get objective bounds for normalization    f_min = result.F.min(axis=0)    f_max = result.F.max(axis=0)     plot = Petal(        title="Selected Solutions Comparison",        bounds=[f_min, f_max],        labels=["f1", "f2"]    )     colors = ["red", "blue", "green"]    for (name, (idx, f)), color in zip(selections.items(), colors):        plot.add(f, color=color, label=name)     plot.show()  def find_extreme_solutions(result):    """Find extreme solutions (best in each objective)."""     print("\n" + "="*60)    print("EXTREME SOLUTIONS")    print("="*60 + "\n")     # Best f1 (minimize f1)    best_f1_idx = np.argmin(result.F[:, 0])    print(f"Best f1 solution: {result.F[best_f1_idx]}")    print(f"  Decision variables: {result.X[best_f1_idx]}\n")     # Best f2 (minimize f2)    best_f2_idx = np.argmin(result.F[:, 1])    print(f"Best f2 solution: {result.F[best_f2_idx]}")    print(f"  Decision variables: {result.X[best_f2_idx]}\n")     return best_f1_idx, best_f2_idx  def main():    """Main execution function."""     # Step 1: Run optimization    problem, result = run_optimization_for_decision_making()     # Step 2: Find extreme solutions    best_f1_idx, best_f2_idx = find_extreme_solutions(result)     # Step 3: Compare different preference weights    selections = compare_different_preferences(result)     # Step 4: Visualize selections with petal diagram    visualize_selected_solutions(result, selections)     print("="*60)    print("DECISION MAKING EXAMPLE COMPLETED")    print("="*60)    print("\nKey Takeaways:")    print("1. Different weights lead to different selected solutions")    print("2. Higher weight on an objective selects solutions better in that objective")    print("3. Visualization helps understand trade-offs")    print("4. MCDM methods help formalize decision maker preferences")  if __name__ == "__main__":    main()