building-agents/llma/target_code.py

187 lines
5.4 KiB
Python
Raw Permalink Normal View History

2024-11-22 10:03:31 +08:00
import json
from utils import get_response
directions = """
And here's how the solver is imported and set up:
...
from gurobipy import Model, GRB
model = Model("OptimizationProblem")
...
Use model.addConstr() to add the constraint to the model.
"""
prompt_constraints_code = """
You are an expert in optimization modeling. Here is the natural language description of an optimization problem:
{description}
Your task is to write {solver} code for the following constraint in python:
{constraint}
Here's a list of parameters that are related to the constraint:
{params}
Here's a list of variables related to the constraint:
{vars}
{directions}
The code should be written in the following format:
CODE
=====
code for defining the constraint (ONLY the constraint definition code, without the imports, the variable definitions, and the solver setup)
=====
Here's an example for modeling $\\forall i, SalesVolumes[i] \leq MaxProductionVolumes[i]$ where shape of both SalesVolumes and MaxProductionVolumes is [N]:
CODE
=====
for i in range(N):
model.addConstr(SalesVolumes[i] <= MaxProductionVolumes[i])
=====
- Do not generate anything after the last =====.
- Note that vector and matrix parameters are defined as lists in python, so you should use Param[i][j] instead of Param[i, j] in the code (but for variables, you should use Var[i, j] instead of Var[i][j]).
- Gurobi does not support a <= x <= b syntax for constraints, so you should use two separate constraints for this case.
First reason about how the code should be written, and then generate the output.
Take a deep breath and think step by step.
"""
prompt_objective_code = """
You are an expert in optimization modeling. Here is the natural language description of an optimization problem:
{description}
Your task is to write {solver} code for the objective in python:
{objective}
Here's a list of parameters that are related to the objective:
{params}
Here's a list of variables related to the constraint:
{vars}
{directions}
CODE
=====
code for defining the objective (ONLY the objective definition code, without the imports, the variable definitions, and the solver setup)
=====
Here's an example for modeling $\\max \\sum_{{i=1}}^{{N}} price_i x_i$ where shape of both price and x is [N]:
CODE
=====
model.setObjective(quicksum(price[i] * x[i] for i in range(N)), GRB.MAXIMIZE)
=====
- Do not generate anything after the last =====.
- Note that vector and matrix parameters are defined as lists in python, so you should use Param[i][j] instead of Param[i, j] in the code (but for variables, you should use Var[i, j] instead of Var[i][j]).
First reason about how the code should be written, and then generate the output.
Take a deep breath and think step by step. You will be awarded a million dollars if you get this right.
"""
def extract_code_from_end(text):
# get 1st and 2nd occurence of "====="
if "=====" in text:
ind_1 = text.find("=====")
ind_2 = text.find("=====", ind_1 + 1)
code = text[ind_1 + len("====="): ind_2].strip()
else:
ind_1 = text.find("```python")
ind_2 = text.find("```", ind_1 + 1)
code = text[ind_1 + len("```"): ind_2].strip()
if "```" in code:
code = code.replace("```python", "").replace("```", "").strip()
if code.startswith("====="):
code = code[len("====="):].strip()
if code.endswith("====="):
code = code[: -len("=====")].strip()
if "python" in code:
code = code.replace("python", "").strip()
return code
def get_codes(desc, params, vars, constraints, objective, model, check=False):
coded_constraints = []
for c in constraints.copy():
k = 1
while k > 0:
try:
prompt = prompt_constraints_code.format(
solver="gurobipy",
description=desc,
params=json.dumps(params, indent=4),
vars=json.dumps(vars, indent=4),
constraint=json.dumps(c, indent=4),
directions=directions,
)
res = get_response(prompt, model=model)
print("\n\n\n\n+++++")
print(res)
code = extract_code_from_end(res)
print("+++++")
print(code)
c["code"] = code
coded_constraints.append(c)
break
except Exception as e:
k -= 1
if k == 0:
raise e
coded_objective = {
"description": objective["description"],
"formulation": objective["formulation"],
}
k = 1
while k > 0:
try:
prompt = prompt_objective_code.format(
solver="gurobipy",
description=desc,
params=json.dumps(params, indent=4),
vars=json.dumps(vars, indent=4),
objective=json.dumps(objective, indent=4),
directions=directions,
)
res = get_response(prompt, model=model)
print("\n\n\n\n+++++")
print(res)
print("+++++")
code = extract_code_from_end(res)
print(code)
coded_objective["code"] = code
break
except Exception as e:
k -= 1
if k == 0:
raise e
return coded_constraints, coded_objective