Документация Engee

Целевые функции

На этой странице описываются макросы и функции, относящиеся только к линейным и квадратичным целевым функциям, если не указано иное. Сведения о нелинейных целевых функциях см. в разделе Nonlinear Modeling.

Задание линейной целевой функции

Чтобы задать линейную целевую функцию, используйте макрос @objective.

Чтобы создать целевую функцию минимизации, используйте Min:

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, 2x + 1)
2 x + 1

Чтобы создать целевую функцию максимизации, используйте Max:

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Max, 2x + 1)
2 x + 1

Задание квадратичной целевой функции

Чтобы задать квадратичную целевую функцию, используйте макрос @objective.

Чтобы возвести переменную в квадрат, используйте ^2:

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, x^2 + 2x + 1)
x² + 2 x + 1

Между переменными также могут быть билинейные члены:

julia> model = Model();

julia> @variable(model, x)
x

julia> @variable(model, y)
y

julia> @objective(model, Max, x * y + x + y)
x*y + x + y

Задание нелинейной целевой функции

Чтобы задать нелинейную целевую функцию, используйте макрос @objective:

julia> model = Model();

julia> @variable(model, x <= 1);

julia> @objective(model, Max, log(x))
log(x)

Запрос целевой функции

Для получения текущей целевой функции используйте метод objective_function.

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, 2x + 1)
2 x + 1

julia> objective_function(model)
2 x + 1

Вычисление целевой функции в точке

Чтобы вычислить целевую функцию в точке, указав значения переменных, используйте value.

julia> model = Model();

julia> @variable(model, x[1:2]);

julia> @objective(model, Min, 2x[1]^2 + x[1] + 0.5*x[2])
2 x[1]² + x[1] + 0.5 x[2]

julia> f = objective_function(model)
2 x[1]² + x[1] + 0.5 x[2]

julia> point = Dict(x[1] => 2.0, x[2] => 1.0);

julia> value(z -> point[z], f)
10.5

Запрос целевого назначения

Для получения текущего целевого назначения используйте метод objective_sense.

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, 2x + 1)
2 x + 1

julia> objective_sense(model)
MIN_SENSE::OptimizationSense = 0

Изменение целевой функции

Чтобы изменить целевую функцию, вызовите @objective с новой целевой функцией.

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, 2x)
2 x

julia> @objective(model, Max, -2x)
-2 x

Кроме того, можно воспользоваться функцией set_objective_function.

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, 2x)
2 x

julia> new_objective = @expression(model, -2 * x)
-2 x

julia> set_objective_function(model, new_objective)

Изменение коэффициента целевой функции

Чтобы изменить коэффициент целевой функции, используйте метод set_objective_coefficient.

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, 2x)
2 x

julia> set_objective_coefficient(model, x, 3)

julia> objective_function(model)
3 x

Чтобы изменить коэффициент квадратичной целевой функции, используйте метод set_objective_coefficient с двумя переменными:

julia> model = Model();

julia> @variable(model, x);

julia> @variable(model, y);

julia> @objective(model, Min, x^2 + x * y)
x² + x*y

julia> set_objective_coefficient(model, x, x, 2)

julia> set_objective_coefficient(model, x, y, 3)

julia> objective_function(model)
2 x² + 3 x*y

Изменение целевого назначения

Чтобы изменить целевое назначение, используйте метод set_objective_sense.

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, 2x)
2 x

julia> objective_sense(model)
MIN_SENSE::OptimizationSense = 0

julia> set_objective_sense(model, MAX_SENSE);

julia> objective_sense(model)
MAX_SENSE::OptimizationSense = 1

Можно также вызвать @objective и передать существующую целевую функцию.

julia> model = Model();

julia> @variable(model, x);

julia> @objective(model, Min, 2x)
2 x

julia> @objective(model, Max, objective_function(model))
2 x

Задание векторнозначной целевой функции

Чтобы определить задачу оптимизации с несколькими целевыми функциями, передайте вектор целевых функций:

julia> model = Model();

julia> @variable(model, x[1:2]);

julia> @objective(model, Min, [1 + x[1], 2 * x[2]])
2-element Vector{AffExpr}:
 x[1] + 1
 2 x[2]

julia> f = objective_function(model)
2-element Vector{AffExpr}:
 x[1] + 1
 2 x[2]

В руководстве Multi-objective knapsack представлен пример решения целочисленной программы с несколькими целевыми функциями.

В большинстве случаев решатели оптимизации нескольких целевых функций возвращают несколько решений, соответствующих точкам на границе Парето. Сведения о запросе нескольких решений и работе с ними см. в разделе Multiple solutions.

Обратите внимание, что целевое назначение должно быть одно, то есть нельзя одновременно задать назначение минимизации и максимизации. Чтобы обойти это ограничение, выберите Min и сделайте отрицательными все целевые функции, которые необходимо максимизировать:

julia> model = Model();

julia> @variable(model, x[1:2]);

julia> @expression(model, obj1, 1 + x[1])
x[1] + 1

julia> @expression(model, obj2, 2 * x[1])
2 x[1]

julia> @objective(model, Min, [obj1, -obj2])
2-element Vector{AffExpr}:
 x[1] + 1
 -2 x[1]

Определение целевых функций в виде выражений обеспечивает гибкость в решении различных вариантов одной и той же задачи. При этом некоторые целевые функции исключаются и ограничиваются фиксированным значением.

julia> model = Model();

julia> @variable(model, x[1:2]);

julia> @expression(model, obj1, 1 + x[1])
x[1] + 1

julia> @expression(model, obj2, 2 * x[1])
2 x[1]

julia> @expression(model, obj3, x[1] + x[2])
x[1] + x[2]

julia> @objective(model, Min, [obj1, obj2, obj3])  # Задача с тремя целевыми функциями
3-element Vector{AffExpr}:
 x[1] + 1
 2 x[1]
 x[1] + x[2]

julia> # Вызовите optimize!(model), изучите решение, обсудите результат с заинтересованными лицами, а затем
       # решите, следует ли решить новую задачу, исключив третью целевую функцию
       # и ограничив ее значением больше 2.0.
       nothing

julia> @objective(model, Min, [obj1, obj2])   # Задача с двумя целевыми функциями
2-element Vector{AffExpr}:
 x[1] + 1
 2 x[1]

julia> @constraint(model, obj3 <= 2.0)
x[1] + x[2] ≤ 2