CarbonGap's picture
Upload 44 files
ba2dcff verified
Raw
History Blame Contribute Delete
2.04 kB
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)}