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