File size: 3,639 Bytes
af3df09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import math
import json
import regex
import inspect
import guidance
from ast import literal_eval
from transformers import Tool
from ortools.linear_solver import pywraplp

guidance.llm = guidance.llms.OpenAI("gpt-4")

structure_program = guidance(
'''
{{#user~}}
{{description}}
Help me extract args from the data blob to apply the following algorithm:
{{code}}

----

{{~#each examples}}
Data Blob: {{this.input}}
Result: {{this.output}}
---
{{~/each}}

Please help me extract the input values from a given data blob into a JSON.
Data Blob: {{data_blob}}
Result: 
{{~/user}}

{{#assistant~}}
{{gen 'output'}}
{{~/assistant}}
''')

class IntegerProgrammingTool(Tool):
    name = "integer_programming_tool"
    description = """
    This tool solves an integer programming problem.
    Input is data_blob
    Output is the optimal solution as a string.
    """
    inputs = ["text"]
    outputs = ["text"]
    examples = [
        {'input': '''
        ,Space,Price
        Puzzle,1,2
        BoardGame,5,12

        Constraint,100
        ''',
        'output': {
            "objective_coeffs": [
                [1, 2],
                [5, 15],
            ],
            "constraints": [100],
            "bounds": [
                [0, None],
                [0, None]
            ],
            "goal": "max"
          },
        },
        {'input': '''
        ,Space,Price
        Puzzle,3,12
        BoardGame,15,120

        Constraint,300
        ''',
        'output': {
            "objective_coeffs": [
                [3, 2],
                [15, 120],
            ],
            "constraints": [300],
            "bounds": [
                [0, None],
                [0, None]
            ],
            "goal": "max"
          },
        },
    ]
    def __call__(self, data_blob):
        code = inspect.getsourcelines(self.__call__)
        args = structure_program(
            description=self.description,
            code=code,
            examples=self.examples,
            data_blob=data_blob,
        )['output']
        pattern = regex.compile(r"\{(?:[^{}]|(?R))*\}")
        matches = pattern.findall(args)[0]
        args = literal_eval(matches)
        print(args)
        objective_coeffs = args['objective_coeffs']
        constraints = args['constraints']
        bounds = args['bounds']
        goal = args['goal']

        objective_coeffs = list(zip(*objective_coeffs))
        solver = pywraplp.Solver.CreateSolver("CBC")
        variables = [solver.IntVar(
        int(bounds[i][0]) if bounds[i][0] is not None else -math.inf,
        int(bounds[i][1]) if bounds[i][1] is not None else math.inf,
        f"x{i}") for i in range(len(objective_coeffs))]

        # Set objective function
        objective = solver.Objective()
        for i, coeff_list in enumerate(objective_coeffs):
            for j, coeff_value in enumerate(coeff_list):
                objective.SetCoefficient(variables[j], coeff_value)
        if goal == 'max':
            objective.SetMaximization()
        else:
            objective.SetMinimization()

        # Add constraints
        for i, constraint_value in enumerate(constraints):
            if constraint_value:
                constraint = solver.RowConstraint(0, constraint_value)
                for j, coeff in enumerate(objective_coeffs[i]):
                    constraint.SetCoefficient(variables[j], coeff)
        
        solver.Solve()
        
        solution = {"Objective value": objective.Value()}
        for i, variable in enumerate(variables):
            solution[f"x{i}"] = variable.solution_value()
        
        return json.dumps(solution)