Spaces:
Sleeping
Sleeping
| import numpy as np | |
| from scipy.optimize import linprog | |
| def run_optimization(resource_caps, method_constraints, method_costs): | |
| """ | |
| Run linear optimization to maximize CO₂ removal while respecting resource limits and method constraints. | |
| Args: | |
| resource_caps (dict): {resource: available_quantity} | |
| method_constraints (dict): {method: {"active": bool, "max_share": float}} | |
| method_costs (dict): {method: {resource: usage_per_tCO2}} | |
| Returns: | |
| (bool, dict): (success_flag, result_dict) | |
| result_dict includes "total_removed", "method_usage" | |
| """ | |
| methods = list(method_costs.keys()) | |
| resources = list(resource_caps.keys()) | |
| # A matrix: each row is a resource, each column a method | |
| A_resource = np.array([ | |
| [method_costs[m].get(r, 0.0) for m in methods] | |
| for r in resources | |
| ]) | |
| b_resource = np.array([resource_caps[r] for r in resources]) | |
| # Constraint: sum(x_i) * share_i ≤ x_i | |
| A_share = [] | |
| b_share = [] | |
| for i, m in enumerate(methods): | |
| row = np.zeros(len(methods)) | |
| row += -method_constraints[m]["max_share"] | |
| row[i] += 1 | |
| A_share.append(row) | |
| b_share.append(0) | |
| # Combine constraints | |
| A_ub = np.vstack([A_resource, A_share]) | |
| b_ub = np.concatenate([b_resource, b_share]) | |
| # Objective: maximize sum(x_i), hence minimize -1 * sum(x_i) | |
| c = -1 * np.ones(len(methods)) | |
| bounds = [(0, None)] * len(methods) | |
| try: | |
| result = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds, method="highs") | |
| if result.success: | |
| x = np.floor(result.x).astype(int) | |
| total_removed = int(x.sum()) | |
| method_usage = {m: int(x[i]) for i, m in enumerate(methods) if x[i] > 0} | |
| return True, {"total_removed": total_removed, "method_usage": method_usage} | |
| else: | |
| return False, {"message": result.message} | |
| except Exception as e: | |
| return False, {"message": str(e)} | |