Loading...
Loading...
Google Optimization Tools. An open-source software suite for optimization, specialized in vehicle routing, flows, integer and linear programming, and constraint programming. Features the world-class CP-SAT solver. Use for vehicle routing problems (VRP), scheduling, bin packing, knapsack problems, linear programming (LP), integer programming (MIP), network flows, constraint programming, combinatorial optimization, resource allocation, shift scheduling, job-shop scheduling, and discrete optimization problems.
npx skill4agent add tondevrel/scientific-agent-skills ortoolscp_model.CpModelpywraplp.Solverrouting_enums_pb2AddConstraint0.5OPTIMALFEASIBLEINFEASIBLELIMIT_REACHEDpip install ortoolsfrom ortools.sat.python import cp_model
from ortools.linear_solver import pywraplp
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcpfrom ortools.sat.python import cp_model
# 1. Create the model
model = cp_model.CpModel()
# 2. Define variables: NewIntVar(lower_bound, upper_bound, name)
x = model.NewIntVar(0, 10, 'x')
y = model.NewIntVar(0, 10, 'y')
# 3. Add constraints
model.Add(x + y <= 8)
model.Add(x > 2)
# 4. Define Objective
model.Maximize(x + 2 * y)
# 5. Solve
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status == cp_model.OPTIMAL:
print(f'x = {solver.Value(x)}, y = {solver.Value(y)}')1.25125INFEASIBLEmodel.AddElementsolver.parameters.max_time_in_seconds = 60.0solver.Value(var)if x > 5: model.Add(...)OnlyEnforceIfx * ysin(x)x * yfrom ortools.sat.python import cp_model
# ❌ BAD: Using standard Python logic inside the model
# if solver.Value(x) > 5: # ❌ Value() is not available during modeling!
# model.Add(y == 1)
# ✅ GOOD: Conditional constraints (Logical Implication)
b = model.NewBoolVar('b')
model.Add(x > 5).OnlyEnforceIf(b)
model.Add(x <= 5).OnlyEnforceIf(b.Not())
model.Add(y == 1).OnlyEnforceIf(b)
# ❌ BAD: Floating point variables in CP-SAT
# x = model.NewIntVar(0, 1.5, 'x') # ❌ Error!
# ✅ GOOD: Scaling
# x_scaled = model.NewIntVar(0, 150, 'x_scaled') # 150 represents 1.50from ortools.linear_solver import pywraplp
# Create solver with GLOP backend (Google Linear Optimization Package)
solver = pywraplp.Solver.CreateSolver('GLOP')
# Define continuous variables
x = solver.NumVar(0, solver.infinity(), 'x')
y = solver.NumVar(0, solver.infinity(), 'y')
# Constraint: x + 2y <= 14
ct = solver.Constraint(-solver.infinity(), 14)
ct.SetCoefficient(x, 1)
ct.SetCoefficient(y, 2)
# Objective: Maximize 3x + 4y
objective = solver.Objective()
objective.SetCoefficient(x, 3)
objective.SetCoefficient(y, 4)
objective.SetMaximization()
solver.Solve()
print(f'Solution: x={x.solution_value()}, y={y.solution_value()}')from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def solve_vrp():
# 1. Distance Matrix (distance between locations)
data = {'distance_matrix': [[0, 10, 20], [10, 0, 15], [20, 15, 0]],
'num_vehicles': 1, 'depot': 0}
# 2. Setup Index Manager and Routing Model
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
data['num_vehicles'], data['depot'])
routing = pywrapcp.RoutingModel(manager)
# 3. Create Distance Callback
def distance_callback(from_index, to_index):
return data['distance_matrix'][manager.IndexToNode(from_index)][manager.IndexToNode(to_index)]
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# 4. Solve
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
solution = routing.SolveWithParameters(search_parameters)
return solutionmodel = cp_model.CpModel()
# Define an Interval Variable (Start, Duration, End)
duration = 10
start_var = model.NewIntVar(0, 100, 'start')
end_var = model.NewIntVar(0, 100, 'end')
interval_var = model.NewIntervalVar(start_var, duration, end_var, 'interval')
# No-overlap constraint (Machines can only do one task at a time)
model.AddNoOverlap([interval_var1, interval_var2, interval_var3])def solve_shifts(num_employees, num_days, shifts_per_day):
model = cp_model.CpModel()
shifts = {}
for e in range(num_employees):
for d in range(num_days):
for s in range(shifts_per_day):
shifts[(e, d, s)] = model.NewBoolVar(f'shift_e{e}d{d}s{s}')
# Constraint: Each shift is assigned to exactly one employee
for d in range(num_days):
for s in range(shifts_per_day):
model.Add(sum(shifts[(e, d, s)] for e in range(num_employees)) == 1)
# Constraint: Each employee works at most one shift per day
for e in range(num_employees):
for d in range(num_days):
model.Add(sum(shifts[(e, d, s)] for s in range(shifts_per_day)) <= 1)
solver = cp_model.CpSolver()
status = solver.Solve(model)
return shifts, solverdef bin_packing(items, bin_capacities):
model = cp_model.CpModel()
# x[i, j] = 1 if item i is in bin j
x = {}
for i in range(len(items)):
for j in range(len(bin_capacities)):
x[i, j] = model.NewBoolVar(f'x_{i}_{j}')
# Each item in exactly one bin
for i in range(len(items)):
model.Add(sum(x[i, j] for j in range(len(bin_capacities))) == 1)
# Bin capacity constraint
for j in range(len(bin_capacities)):
model.Add(sum(x[i, j] * items[i] for i in range(len(items))) <= bin_capacities[j])model.AddHint(x, 5)
model.AddHint(y, 2)solver = cp_model.CpSolver()
solver.parameters.num_search_workers = 8 # Use 8 CPU cores# ❌ Problem: model.Add(x * 0.1 <= 5)
# ✅ Solution:
model.Add(x <= 50) # Multiply both sides by 10solver.Solve(model)INFEASIBLE# ✅ Solution: Use 'Sufficient Assmptions' or 'Constraint Relaxation'
# to identify which constraint is causing the conflict.# ✅ Solution: Add symmetry-breaking constraints
# model.Add(x_A <= x_B) # Force an ordering