' Copyright 2026, Gurobi Optimization, LLC
'
' This example formulates and solves the following simple nonlinear model
' using the nonlinear API:
'
' minimize x - y
' subject to sin(x) * x + x^2 * y <= 1
' y = cos(x) (<=> cos(x) - y = 0)
' -1 <= x <= 2
' 0 <= y <= 2
'
' The example is split into two functions that show two ways to build the
' nonlinear constraints with the new NL API:
'
' - nlconstrNLAPI(): uses the nonlinear expression API. The left-hand sides
' of the constraints are built as GRBNLExpr objects with the overloaded
' operators, the nonlinear functions hosted on GRBNLExpr, and the Pow()
' helper, and passed directly to AddNLConstr().
'
' - nlconstrNLAPIAdv(): uses the advanced expression-tree variant of
' AddNLConstr(), where the left-hand side of each constraint is described
' with arrays of opcodes, data, and parent pointers.
'
' In both cases we retrieve a nonlinear constraint with GetNLConstrLHS(),
' delete it with Remove(), replace it with a simple linear constraint, and
' re-optimize.
Imports System
Imports Gurobi
Class nlconstr_vb
' Run both ways of building nonlinear constraints: the nonlinear
' expression API and the advanced expression-tree API.
Shared Sub Main()
Try
' First, the nonlinear expression API
nlconstrNLAPI()
' Then, the advanced expression-tree API
nlconstrNLAPIAdv()
Catch e As GRBException
Console.WriteLine("Error code: " & e.ErrorCode & ". " & e.Message)
End Try
End Sub
' nlconstrNLAPI(): formulates the model with the nonlinear expression API,
' passing GRBNLExpr left-hand sides to AddNLConstr().
Shared Sub nlconstrNLAPI()
' Create environment
Dim env As GRBEnv = New GRBEnv("nlconstr.log")
' Create empty model
Dim model As GRBModel = New GRBModel(env)
' Create variables
Dim x As GRBVar = model.AddVar(-1.0, 2.0, 1.0, GRB.CONTINUOUS, "x")
Dim y As GRBVar = model.AddVar(0.0, 2.0, -1.0, GRB.CONTINUOUS, "y")
' Add nonlinear constraint: sin(x)*x + x^2*y <= 1.
' The left-hand side is built as a GRBNLExpr:
' GRBNLExpr.Sin(x) -> sin(x)
' GRBNLExpr.Pow(x, 2.0) -> x^2 (a SQUARE node)
Dim nlc1 As GRBNLConstr = model.AddNLConstr( _
GRBNLExpr.Sin(x) * x + GRBNLExpr.Pow(x, 2.0) * y <= 1.0, _
"NonlinearConstraint1")
' Add nonlinear constraint: cos(x) - y = 0
Dim nlc2 As GRBNLConstr = model.AddNLConstr(GRBNLExpr.Cos(x) - y = 0.0, _
"NonlinearConstraint2")
' Optimize model
model.Optimize()
Console.WriteLine("")
Console.WriteLine("First solve (nonlinear constraints)")
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine("Optimal objective: " & model.ObjVal.ToString("E4"))
Console.WriteLine(" x=" & x.X.ToString("F6") & _
", y=" & y.X.ToString("F6"))
ElseIf model.Status = GRB.Status.INF_OR_UNBD Then
Console.WriteLine("Model is infeasible or unbounded")
Else
Console.WriteLine("Optimization was stopped early")
End If
' Retrieve the first nonlinear constraint as a GRBNLExpr and print it
Dim lhs As GRBNLExpr = model.GetNLConstrLHS(nlc1)
Console.WriteLine("")
Console.WriteLine("Retrieved NL constraint: """ & lhs.ToString() & """")
' Delete the nonlinear constraints
model.Remove(nlc1)
model.Remove(nlc2)
model.Update()
Console.WriteLine("Deleted nonlinear constraints")
' Add a simple linear constraint instead: x + y >= 1
model.AddConstr(x + y, GRB.GREATER_EQUAL, 1.0, "LinearConstraint")
' Re-optimize
model.Optimize()
Console.WriteLine("")
Console.WriteLine("Second solve (linear constraint)")
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine("Optimal objective: " & model.ObjVal.ToString("E4"))
Console.WriteLine(" x=" & x.X.ToString("F6") & _
", y=" & y.X.ToString("F6"))
ElseIf model.Status = GRB.Status.INF_OR_UNBD Then
Console.WriteLine("Model is infeasible or unbounded")
Else
Console.WriteLine("Optimization was stopped early")
End If
' Dispose of model and env
model.Dispose()
env.Dispose()
End Sub
' nlconstrNLAPIAdv(): formulates the model with the advanced
' expression-tree variant of AddNLConstr(), where the left-hand side of
' each constraint is described with arrays of opcodes, data, and parents.
Shared Sub nlconstrNLAPIAdv()
' Create environment
Dim env As GRBEnv = New GRBEnv("nlconstr.log")
' Create empty model
Dim model As GRBModel = New GRBModel(env)
' Create variables
Dim x As GRBVar = model.AddVar(-1.0, 2.0, 1.0, GRB.CONTINUOUS, "x")
Dim y As GRBVar = model.AddVar(0.0, 2.0, -1.0, GRB.CONTINUOUS, "y")
' Expression tree for sin(x) * x + x^2 * y (10 nodes)
'
' node 0: PLUS (root)
' node 1: MULTIPLY (child of 0) -> sin(x) * x
' node 2: SIN (child of 1)
' node 3: VARIABLE x (child of 2)
' node 4: VARIABLE x (child of 1)
' node 5: MULTIPLY (child of 0) -> x^2 * y
' node 6: POW (child of 5)
' node 7: VARIABLE x (child of 6)
' node 8: CONSTANT 2 (child of 6)
' node 9: VARIABLE y (child of 5)
Dim opcode1 As Integer() = New Integer() { _
GRB.OPCODE_PLUS, _
GRB.OPCODE_MULTIPLY, _
GRB.OPCODE_SIN, _
GRB.OPCODE_VARIABLE, _
GRB.OPCODE_VARIABLE, _
GRB.OPCODE_MULTIPLY, _
GRB.OPCODE_POW, _
GRB.OPCODE_VARIABLE, _
GRB.OPCODE_CONSTANT, _
GRB.OPCODE_VARIABLE _
}
Dim data1 As Double() = New Double() { _
-1.0, -1.0, -1.0, _
x.Index, _
x.Index, _
-1.0, -1.0, _
x.Index, _
2.0, _
y.Index _
}
Dim parent1 As Integer() = New Integer() {-1, 0, 1, 2, 1, 0, 5, 6, 6, 5}
' Expression tree for cos(x) - y = 0 (4 nodes)
'
' node 0: MINUS (root)
' node 1: COS (child of 0)
' node 2: VARIABLE x (child of 1)
' node 3: VARIABLE y (child of 0)
Dim opcode2 As Integer() = New Integer() { _
GRB.OPCODE_MINUS, _
GRB.OPCODE_COS, _
GRB.OPCODE_VARIABLE, _
GRB.OPCODE_VARIABLE _
}
Dim data2 As Double() = New Double() { _
-1.0, -1.0, _
x.Index, _
y.Index _
}
Dim parent2 As Integer() = New Integer() {-1, 0, 1, 0}
' Add nonlinear constraint: sin(x)*x + x^2*y <= 1
Dim nlc1 As GRBNLConstr = model.AddNLConstr(opcode1, data1, parent1, _
GRB.LESS_EQUAL, 1.0, _
"NonlinearConstraint1")
' Add nonlinear constraint: cos(x) - y = 0
Dim nlc2 As GRBNLConstr = model.AddNLConstr(opcode2, data2, parent2, _
GRB.EQUAL, 0.0, _
"NonlinearConstraint2")
' Optimize model
model.Optimize()
Console.WriteLine("")
Console.WriteLine("First solve (nonlinear constraints)")
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine("Optimal objective: " & model.ObjVal.ToString("E4"))
Console.WriteLine(" x=" & x.X.ToString("F6") & _
", y=" & y.X.ToString("F6"))
ElseIf model.Status = GRB.Status.INF_OR_UNBD Then
Console.WriteLine("Model is infeasible or unbounded")
Else
Console.WriteLine("Optimization was stopped early")
End If
' Retrieve the first nonlinear constraint and print the number of nodes
Dim nnodes As Integer
model.GetNLConstrLHS(nlc1, nnodes, Nothing, Nothing, Nothing)
Console.WriteLine("")
Console.WriteLine("Retrieved NL constraint with " & nnodes & " nodes")
' Delete the nonlinear constraints
model.Remove(nlc1)
model.Remove(nlc2)
model.Update()
Console.WriteLine("Deleted nonlinear constraints")
' Add a simple linear constraint instead: x + y >= 1
model.AddConstr(x + y, GRB.GREATER_EQUAL, 1.0, "LinearConstraint")
' Re-optimize
model.Optimize()
Console.WriteLine("")
Console.WriteLine("Second solve (linear constraint)")
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine("Optimal objective: " & model.ObjVal.ToString("E4"))
Console.WriteLine(" x=" & x.X.ToString("F6") & _
", y=" & y.X.ToString("F6"))
ElseIf model.Status = GRB.Status.INF_OR_UNBD Then
Console.WriteLine("Model is infeasible or unbounded")
Else
Console.WriteLine("Optimization was stopped early")
End If
' Dispose of model and env
model.Dispose()
env.Dispose()
End Sub
End Class