Added 18/06/2025
Miscellaneous
basic_constrained
Dimension
{
"x": 4,
"y": 4,
"F": 1,
"G": 2,
"H": 2,
"f": 1,
"g": 2,
"h": 2
}
Solution
{
"optimality": "global",
"x": [1, 0, 3, -4],
"y": [1, 0, 3, -4],
"F": 26,
"G": [0, 2],
"H": [0, 0],
"f": 26,
"g": [0, 2],
"h": [0, 0]
}
$title basic_constrained
$onText
minimise x1^2 + x2^2 + x3^2 + x4^2
subject to x1 >= +1.0,
x2 >= -2.0,
x3 == +3.0,
x4 == -4.0,
y = argmin(y1^2 + y2^2 + y3^2 + y4^2),
y1 >= +1.0,
y2 >= -2.0,
y3 == +3.0,
y4 == -4.0,
$offText
set i / 1*4 /;
variables obj_val_upper, obj_val_lower, x(i), y(i);
equations obj_eq_upper, obj_eq_lower,
G1_upper, G2_upper, H1_upper, H2_upper,
g1_lower, g2_lower, h1_lower, h2_lower;
* Objective functions
obj_eq_upper.. obj_val_upper =e= sum(i, sqr(x(i)));
obj_eq_lower.. obj_val_lower =e= sum(i, sqr(y(i)));
* Upper-level constraints
G1_upper.. x('1') =g= 1.0;
G2_upper.. x('2') =g= -2.0;
H1_upper.. x('3') =e= 3.0;
H2_upper.. x('4') =e= -4.0;
* Lower-level constraints
g1_lower.. y('1') =g= 1.0;
g2_lower.. y('2') =g= -2.0;
h1_lower.. y('3') =e= 3.0;
h2_lower.. y('4') =e= -4.0;
* Solve
model basic_constrained / all /;
$echo bilevel x min obj_val_lower y obj_eq_lower g1_lower g2_lower h1_lower h2_lower > "%emp.info%"
solve basic_constrained us emp min obj_val_upper;
\subsection{basic\_constrained}
\label{subsec:basic_constrained}
% Description
A basic example where the upper and lower level programs are totally unlinked. The unique global optimum is found at $x=[1, 0, 3, -4]$ and $y=[1, 0, 3, -4]$.
% Equation
\begin{flalign*}
\minimise_{x, y} \quad
& x_1^2 + x_2^2 + x_3^2 + x_4^2 \\
\subjectto \quad
& x_1 \geq 1, \\
& x_2 \geq -2, \\
& x_3 = 3, \\
& x_4 = -4,\\
& y \in \argmin_{y}
\left\{
\begin{array}{l}
y_1^2 + y_2^2 + y_3^2 + y_4^2, \\
y_1 \geq 1, \\
y_2 \geq -2, \\
y_3 = 3, \\
y_4 = -4,\\
\end{array}
\right.
\end{flalign*}
classdef basic_constrained
%{
A basic example where the upper and lower level programs are totally unlinked.
%}
properties(Constant)
name = 'basic_constrained';
category = 'miscellaneous';
subcategory = '';
datasets = {};
x0 = [1.0, 0.0, 3.0, -4.0];
y0 = [1.0, 0.0, 3.0, -4.0];
end
methods(Static)
% Upper-level objective function
function val = F(x, ~, ~)
val = sum(x.^2);
end
% Upper-level inequality constraints
function val = G(x, ~, ~)
val = [x(1)-1; x(2)+2];
end
% Upper-level equality constraints
function val = H(x, ~, ~)
val = [x(3)-3; x(4)+4];
end
% Lower-level objective function
function val = f(~, y, ~)
val = sum(y.^2);
end
% Lower-level inequality constraints
function val = g(~, y, ~)
val = [y(1)-1; y(2)+2];
end
% Lower-level equality constraints
function val = h(~, y, ~)
val = [y(3)-3; y(4)+4];
end
% If the bilevel program is parameterized by data, this function should
% provide code to read data file and return an appropriate structure.
function val = read_data(~)
val = [];
end
% Key are the function/variable names
% Values are their dimention
function n = dimentions(key, ~)
n = dictionary( ...
'x', 4, ...
'y', 4, ...
'F', 1, ...
'G', 2, ...
'H', 2, ...
'f', 1, ...
'g', 2, ...
'h', 2 ...
);
if isKey(n,key)
n = n(key);
end
end
end
end
from bolib3 import np
"""
A basic example where the upper and lower level programs are totally unlinked.
minimise x1^2 + x2^2 + x3^2 + x4^2
subject to x1 >= +1.0,
x2 >= -2.0,
x3 == +3.0,
x4 == -4.0,
y = argmin(y1^2 + y2^2 + y3^2 + y4^2),
y1 >= +1.0,
y2 >= -2.0,
y3 == +3.0,
y4 == -4.0,
"""
# Properties
name: str = 'basic_constrained'
category: str = 'miscellaneous'
subcategory: str = ''
datasets: list = []
# Feasible point
x0 = [1.0, 0.0, 3.0, -4.0]
y0 = [1.0, 0.0, 3.0, -4.0]
# Methods
def F(x, y, data=None):
"""
Upper-level objective function
"""
return np.sum(np.square(x))
def G(x, y, data=None):
"""
Upper-level inequality constraints
"""
return np.array([
x[0] - 1,
x[1] + 2
])
def H(x, y, data=None):
"""
Upper-level equality constraints
"""
return np.array([
x[2] - 3,
x[3] + 4
])
def f(x, y, data=None):
"""
Lower-level objective function
"""
return np.sum(np.square(y))
def g(x, y, data=None):
"""
Lower-level inequality constraints
"""
return np.array([
y[0] - 1,
y[1] + 2,
])
def h(x, y, data=None):
"""
Lower-level equality constraints
"""
return np.array([
y[2] - 3,
y[3] + 4,
])
def read_data(filepath=''):
"""
If the bilevel program is parameterized by data, this function should
provide code to read data file and return an appropriate python structure.
"""
pass
def dimensions(key='', data=None):
"""
If the argument 'key' is not specified, then:
- a dictionary mapping variable/function names (str) to the corresponding dimension (int) is returned.
If the first argument 'key' is specified, then:
- a single integer representing the dimension of the variable/function with the name {key} is returned.
"""
n = {
"x": 4, # Upper-level variables
"y": 4, # Lower-level variables
"F": 1, # Upper-level objective functions
"G": 2, # Upper-level inequality constraints
"H": 2, # Upper-level equality constraints
"f": 1, # Lower-level objective functions
"g": 2, # Lower-level inequality constraints
"h": 2, # Lower-level equality constraints
}
if key in n:
return n[key]
return n