| 148 | } |
| 149 | |
| 150 | void MILPEncoder::encodeReLUConstraint( GurobiWrapper &gurobi, ReluConstraint *relu, bool relax ) |
| 151 | { |
| 152 | if ( !relu->isActive() || relu->phaseFixed() ) |
| 153 | { |
| 154 | ASSERT( relu->auxVariableInUse() ); |
| 155 | ASSERT( ( FloatUtils::gte( _tableau.getLowerBound( relu->getB() ), 0 ) && |
| 156 | FloatUtils::lte( _tableau.getLowerBound( relu->getAux() ), 0 ) ) || |
| 157 | ( FloatUtils::lte( _tableau.getUpperBound( relu->getB() ), 0 ) && |
| 158 | FloatUtils::lte( _tableau.getUpperBound( relu->getF() ), 0 ) ) ); |
| 159 | return; |
| 160 | } |
| 161 | |
| 162 | /* |
| 163 | We have added f - b >= 0 and f >= 0. Additionally, we add |
| 164 | f - b <= (1 - a) * (- lb_b) and f <= a * ub_f. |
| 165 | |
| 166 | When a = 1, the constraints become: |
| 167 | f - b <= 0, f <= ub_f. |
| 168 | When a = 0, the constriants become: |
| 169 | f - b <= - lb_b, f <= 0 |
| 170 | */ |
| 171 | gurobi.addVariable( Stringf( "a%u", _binVarIndex ), |
| 172 | 0, |
| 173 | 1, |
| 174 | relax ? GurobiWrapper::CONTINUOUS : GurobiWrapper::BINARY ); |
| 175 | |
| 176 | unsigned sourceVariable = relu->getB(); |
| 177 | unsigned targetVariable = relu->getF(); |
| 178 | double sourceLb = _tableau.getLowerBound( sourceVariable ); |
| 179 | double targetUb = _tableau.getUpperBound( targetVariable ); |
| 180 | |
| 181 | List<GurobiWrapper::Term> terms; |
| 182 | terms.append( GurobiWrapper::Term( 1, Stringf( "x%u", targetVariable ) ) ); |
| 183 | terms.append( GurobiWrapper::Term( -1, Stringf( "x%u", sourceVariable ) ) ); |
| 184 | terms.append( GurobiWrapper::Term( -sourceLb, Stringf( "a%u", _binVarIndex ) ) ); |
| 185 | gurobi.addLeqConstraint( terms, -sourceLb ); |
| 186 | |
| 187 | terms.clear(); |
| 188 | terms.append( GurobiWrapper::Term( 1, Stringf( "x%u", targetVariable ) ) ); |
| 189 | terms.append( GurobiWrapper::Term( -targetUb, Stringf( "a%u", _binVarIndex++ ) ) ); |
| 190 | gurobi.addLeqConstraint( terms, 0 ); |
| 191 | } |
| 192 | |
| 193 | void MILPEncoder::encodeLeakyReLUConstraint( GurobiWrapper &gurobi, |
| 194 | LeakyReluConstraint *lRelu, |
nothing calls this directly
no test coverage detected