Python interface and modeling environment for SCIP optimization solver
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Nonlinear mathematical functions for advanced optimization modeling. These functions integrate with PySCIPOpt's expression system to enable modeling of nonlinear optimization problems including exponential, logarithmic, trigonometric, and power functions.
Exponential function for modeling exponential growth, decay, and other exponential relationships in optimization problems.
def exp(expr):
"""
Exponential function: e^expr
Creates a nonlinear expression representing the exponential function
applied to the input expression. Commonly used in nonlinear programming,
portfolio optimization, and exponential utility functions.
Parameters:
- expr: Expression, variable, or numeric value to exponentiate
Returns:
GenExpr: General expression representing e^expr
Example:
# Exponential utility function
utility = -exp(-risk_aversion * portfolio_return)
# Exponential decay constraint
model.addCons(concentration <= initial_amount * exp(-decay_rate * time))
"""Natural logarithm function for modeling logarithmic relationships and transformations.
def log(expr):
"""
Natural logarithm function: ln(expr)
Creates a nonlinear expression representing the natural logarithm
of the input expression. Used in logarithmic utility functions,
entropy maximization, and geometric programming.
Parameters:
- expr: Expression, variable, or numeric value (must be positive)
Returns:
GenExpr: General expression representing ln(expr)
Example:
# Logarithmic utility function
utility = log(consumption)
# Entropy constraint
model.addCons(quicksum(p[i] * log(p[i]) for i in range(n)) >= min_entropy)
# Log barrier for interior point methods
barrier = -quicksum(log(x[i]) for i in range(n))
"""Square root function for modeling quadratic relationships and Euclidean distances.
def sqrt(expr):
"""
Square root function: √expr
Creates a nonlinear expression representing the square root
of the input expression. Used in distance calculations,
geometric constraints, and quadratic transformations.
Parameters:
- expr: Expression, variable, or numeric value (must be non-negative)
Returns:
GenExpr: General expression representing √expr
Example:
# Euclidean distance constraint
distance = sqrt((x1 - x2)**2 + (y1 - y2)**2)
model.addCons(distance <= max_distance)
# Quadratic mean constraint
quad_mean = sqrt(quicksum(x[i]**2 for i in range(n)) / n)
# Risk measure (standard deviation)
risk = sqrt(variance_expr)
"""Sine and cosine functions for modeling periodic phenomena and geometric relationships.
def sin(expr):
"""
Sine function: sin(expr)
Creates a nonlinear expression representing the sine function
applied to the input expression (in radians). Used in periodic
optimization problems, signal processing, and geometric modeling.
Parameters:
- expr: Expression, variable, or numeric value (angle in radians)
Returns:
GenExpr: General expression representing sin(expr)
Example:
# Periodic production constraint
seasonal_demand = base_demand + amplitude * sin(2 * pi * time / period)
# Signal processing constraint
signal = quicksum(amplitude[i] * sin(frequency[i] * time + phase[i])
for i in range(n))
"""
def cos(expr):
"""
Cosine function: cos(expr)
Creates a nonlinear expression representing the cosine function
applied to the input expression (in radians). Used alongside sine
for complete trigonometric modeling.
Parameters:
- expr: Expression, variable, or numeric value (angle in radians)
Returns:
GenExpr: General expression representing cos(expr)
Example:
# Circular constraint (unit circle)
model.addCons(cos(angle)**2 + sin(angle)**2 == 1)
# Harmonic oscillator
position = amplitude * cos(frequency * time + phase)
# Geometric positioning
x_coord = radius * cos(angle)
y_coord = radius * sin(angle)
"""from pyscipopt import Model, exp, quicksum
model = Model("exponential_utility")
# Investment variables
investments = [model.addVar(name=f"invest_{i}", lb=0) for i in range(5)]
total_investment = quicksum(investments)
# Risk aversion parameter
risk_aversion = 2.0
# Expected returns (given)
expected_returns = [0.05, 0.08, 0.12, 0.15, 0.20]
# Portfolio expected return
portfolio_return = quicksum(expected_returns[i] * investments[i]
for i in range(5)) / total_investment
# Exponential utility function (risk-averse)
utility = -exp(-risk_aversion * portfolio_return)
# Maximize utility (minimize negative utility)
model.setObjective(utility, "minimize")
# Budget constraint
model.addCons(total_investment == 100000, name="budget")
model.optimize()from pyscipopt import Model, log, quicksum
model = Model("log_barrier")
# Variables with positivity constraints
x = [model.addVar(name=f"x_{i}", lb=0.001) for i in range(3)] # Small lower bound
# Original objective
original_obj = quicksum((i+1) * x[i] for i in range(3))
# Logarithmic barrier to enforce positivity
barrier_param = 0.1
barrier_term = -barrier_param * quicksum(log(x[i]) for i in range(3))
# Combined objective with barrier
model.setObjective(original_obj + barrier_term, "minimize")
# Linear constraints
model.addCons(x[0] + 2*x[1] + x[2] <= 10, name="constraint1")
model.addCons(2*x[0] + x[1] + 3*x[2] <= 15, name="constraint2")
model.optimize()from pyscipopt import Model, sqrt
model = Model("geometric_constraints")
# Facility locations
facilities = [(0, 0), (10, 0), (5, 8)] # Fixed facility coordinates
n_customers = 5
# Customer assignment variables
customer_x = [model.addVar(name=f"customer_{i}_x", lb=0, ub=10)
for i in range(n_customers)]
customer_y = [model.addVar(name=f"customer_{i}_y", lb=0, ub=10)
for i in range(n_customers)]
# Assignment variables (which facility serves each customer)
assignment = {}
for i in range(n_customers):
for j in range(3):
assignment[i, j] = model.addVar(name=f"assign_{i}_{j}", vtype="B")
# Each customer assigned to exactly one facility
for i in range(n_customers):
model.addCons(quicksum(assignment[i, j] for j in range(3)) == 1,
name=f"assign_customer_{i}")
# Distance constraints
max_distance = 6.0
for i in range(n_customers):
for j in range(3):
# Distance from customer i to facility j
distance = sqrt((customer_x[i] - facilities[j][0])**2 +
(customer_y[i] - facilities[j][1])**2)
# If assigned, distance must be within limit
# Using big-M constraint: distance <= max_distance + M*(1 - assignment[i,j])
big_M = 20.0 # Large enough constant
model.addCons(distance <= max_distance + big_M * (1 - assignment[i, j]),
name=f"distance_{i}_{j}")
# Minimize total assignment cost (example)
model.setObjective(quicksum(assignment[i, j] for i in range(n_customers)
for j in range(3)), "minimize")
model.optimize()from pyscipopt import Model, sin, cos, quicksum
import math
model = Model("signal_processing")
# Time points
time_points = [i * 0.1 for i in range(100)] # 0.0, 0.1, 0.2, ..., 9.9
n_time = len(time_points)
# Signal parameters to optimize
amplitude = [model.addVar(name=f"amp_{i}", lb=0, ub=5) for i in range(3)]
frequency = [model.addVar(name=f"freq_{i}", lb=0.1, ub=2.0) for i in range(3)]
phase = [model.addVar(name=f"phase_{i}", lb=0, ub=2*math.pi) for i in range(3)]
# Target signal (given data)
target_signal = [math.sin(0.5*t) + 0.3*math.cos(1.2*t + 0.5) for t in time_points]
# Approximation error variables
error = [model.addVar(name=f"error_{t}", lb=-10, ub=10) for t in range(n_time)]
# Signal approximation constraints
for t in range(n_time):
# Approximate signal as sum of sinusoids
approx_signal = quicksum(
amplitude[i] * sin(frequency[i] * time_points[t] + phase[i])
for i in range(3)
)
# Error definition
model.addCons(error[t] == approx_signal - target_signal[t],
name=f"error_def_{t}")
# Minimize sum of squared errors
model.setObjective(quicksum(error[t]**2 for t in range(n_time)), "minimize")
model.optimize()from pyscipopt import Model, sqrt, quicksum
model = Model("conic_constraints")
# Variables
x = [model.addVar(name=f"x_{i}", lb=-5, ub=5) for i in range(3)]
t = model.addVar(name="t", lb=0)
# Second-order cone constraint: ||x|| <= t
# Equivalent to: sqrt(x[0]^2 + x[1]^2 + x[2]^2) <= t
norm_x = sqrt(quicksum(x[i]**2 for i in range(3)))
model.addCons(norm_x <= t, name="second_order_cone")
# Minimize the norm
model.setObjective(t, "minimize")
# Additional linear constraints
model.addCons(x[0] + x[1] + x[2] >= 2, name="linear_constraint")
model.addCons(2*x[0] - x[1] + x[2] <= 3, name="another_constraint")
model.optimize()from pyscipopt import Model, log, exp, quicksum
model = Model("logarithmic_mean")
# Positive variables
x = [model.addVar(name=f"x_{i}", lb=0.1) for i in range(5)]
# Geometric mean constraint using logarithms
# Geometric mean: (x[0] * x[1] * ... * x[4])^(1/5)
# Taking log: (1/5) * (log(x[0]) + log(x[1]) + ... + log(x[4]))
# Then exp to get back to original scale
log_geometric_mean = (1/5) * quicksum(log(x[i]) for i in range(5))
geometric_mean = exp(log_geometric_mean)
# Constraint: geometric mean >= target
target_geometric_mean = 2.0
model.addCons(geometric_mean >= target_geometric_mean, name="geo_mean_constraint")
# Arithmetic mean constraint for comparison
arithmetic_mean = quicksum(x[i] for i in range(5)) / 5
model.addCons(arithmetic_mean <= 10, name="arith_mean_constraint")
# Minimize sum of variables
model.setObjective(quicksum(x[i] for i in range(5)), "minimize")
model.optimize()from pyscipopt import Model, exp, log
model = Model("compound_interest")
# Investment variables over time periods
periods = 10
investments = [model.addVar(name=f"invest_period_{t}", lb=0)
for t in range(periods)]
# Interest rate (annual)
interest_rate = 0.05
# Compound growth using exponential function
final_values = []
for t in range(periods):
# Value after compound interest: investment * e^(rate * remaining_time)
remaining_time = periods - t
final_value = investments[t] * exp(interest_rate * remaining_time)
final_values.append(final_value)
# Total final value
total_final_value = quicksum(final_values)
# Target final value
target_value = 100000
model.addCons(total_final_value >= target_value, name="target_achievement")
# Budget constraints for each period
period_budgets = [5000, 6000, 7000, 8000, 9000, 10000, 8000, 6000, 4000, 2000]
for t in range(periods):
model.addCons(investments[t] <= period_budgets[t],
name=f"budget_period_{t}")
# Minimize total investment
model.setObjective(quicksum(investments[t] for t in range(periods)), "minimize")
model.optimize()
# Print results
if model.getStatus() == 'optimal':
print(f"Total investment needed: {model.getObjVal():.2f}")
print(f"Final value achieved: {sum(model.getVal(fv) for fv in final_values):.2f}")Install with Tessl CLI
npx tessl i tessl/pypi-pyscipopt