idol
A C++ Framework for Optimization
Loading...
Searching...
No Matches
Description.h
1//
2// Created by henri on 20.06.24.
3//
4
5#ifndef IDOL_BILEVEL_DESCRIPTION_H
6#define IDOL_BILEVEL_DESCRIPTION_H
7
8#include <utility>
9
10#include "idol/mixed-integer/modeling/constraints/Ctr.h"
11#include "idol/mixed-integer/modeling/variables/Var.h"
12#include "idol/mixed-integer/modeling/objects/Versions.h"
13#include "idol/mixed-integer/modeling/models/Model.h"
14
15namespace idol::Bilevel {
16 class Description;
17}
18
21 QuadExpr<Var> m_follower_objective;
22
23 template<class T, unsigned int N>
24 void set_annotation(const Vector<T, N> &t_vector, unsigned int t_value) {
25 if constexpr (N == 1) {
26 for (const auto& x : t_vector) {
27 x.set(m_level, t_value);
28 }
29 } else {
30 for (const auto& x : t_vector) {
31 add_vector<T, N - 1>(x);
32 }
33 }
34 }
35
36public:
37 Description(Env& t_env, const std::string& t_name) : m_level(t_env, t_name + "_lower_level", MasterId) {}
38
39 explicit Description(Env& t_env) : Description(t_env, "bilevel") {}
40
41 explicit Description(const Annotation<unsigned int>& t_lower_level) : m_level(t_lower_level) {}
42
43 Description(const Annotation<unsigned int>& t_lower_level,
44 AffExpr<Var> t_follower_objective)
45 : m_level(t_lower_level),
46 m_follower_objective(std::move(t_follower_objective)) {}
47
48 [[nodiscard]] const Annotation<unsigned int>& lower_level() const { return m_level; }
49
50 [[nodiscard]] const QuadExpr<Var>& lower_level_obj() const { return m_follower_objective; }
51
52 void make_upper_level(const Var& t_var) { t_var.set(m_level, MasterId); }
53
54 void make_upper_level(const Ctr& t_ctr) { t_ctr.set(m_level, MasterId); }
55
56 void make_upper_level(const QCtr& t_ctr) { t_ctr.set(m_level, MasterId); }
57
58 void make_lower_level(const Var& t_var) { t_var.set(m_level, 0); }
59
60 template<unsigned int N> void make_lower_level(const Vector<Var, N>& t_vars) { set_annotation<Var, N>(t_vars, 0); }
61
62 void make_lower_level(const Ctr& t_ctr) { t_ctr.set(m_level, 0); }
63
64 void make_lower_level(const QCtr& t_ctr) { t_ctr.set(m_level, 0); }
65
66 void set_lower_level_obj(QuadExpr<Var> t_objective) { m_follower_objective = std::move(t_objective); }
67
68 [[nodiscard]] bool is_upper(const Var& t_var) const { return t_var.get(m_level) == MasterId; }
69
70 [[nodiscard]] bool is_upper(const Ctr& t_ctr) const { return t_ctr.get(m_level) == MasterId; }
71
72 [[nodiscard]] bool is_upper(const QCtr& t_ctr) const { return t_ctr.get(m_level) == MasterId; }
73
74 [[nodiscard]] bool is_lower(const Var& t_var) const { return t_var.get(m_level) != MasterId; }
75
76 [[nodiscard]] bool is_lower(const Ctr& t_ctr) const { return t_ctr.get(m_level) != MasterId; }
77
78 [[nodiscard]] bool is_lower(const QCtr& t_ctr) const { return t_ctr.get(m_level) != MasterId; }
79};
80
81namespace idol::Bilevel {
82 static bool is_coupling(const Model& t_model, const Description& t_description, const Ctr& t_ctr) {
83
84 if (!t_description.is_upper(t_ctr)) {
85 return false;
86 }
87
88 for (const auto& [var, constant] : t_model.get_ctr_row(t_ctr)) {
89 if (t_description.is_lower(var)) {
90 return true;
91 }
92 }
93
94 return false;
95 }
96}
97
98#endif //IDOL_BILEVEL_DESCRIPTION_H
const ValueT & get(const Annotation< ValueT > &t_annotation) const
Definition Object.h:78
void set(const Annotation< ValueT > &t_annotation, ArgsT &&...t_args) const
Definition Object.h:96