@@ -118,20 +118,6 @@ def __radd__(
118
118
) -> "mip.LinExpr" :
119
119
return self .__add__ (other )
120
120
121
- def __iadd__ (
122
- self ,
123
- other : Union ["mip.Var" , "mip.LinExpr" , numbers .Real ],
124
- ) -> "mip.LinExpr" :
125
- if isinstance (other , Var ):
126
- self .add_var (other , 1 )
127
- elif isinstance (other , LinExpr ):
128
- self .add_expr (other )
129
- elif isinstance (other , numbers .Real ):
130
- self .add_const (other )
131
- else :
132
- raise TypeError ("type {} not supported" .format (type (other )))
133
- return self
134
-
135
121
def __sub__ (
136
122
self ,
137
123
other : Union ["mip.Var" , "mip.LinExpr" , numbers .Real ],
@@ -153,27 +139,11 @@ def __rsub__(
153
139
) -> "mip.LinExpr" :
154
140
return (- self ).__add__ (other )
155
141
156
- def __isub__ (
157
- self ,
158
- other : Union ["mip.Var" , "mip.LinExpr" , numbers .Real ],
159
- ) -> "mip.LinExpr" :
160
- if isinstance (other , Var ):
161
- self .add_var (other , - 1 )
162
- elif isinstance (other , LinExpr ):
163
- self .add_expr (other , - 1 )
164
- elif isinstance (other , numbers .Real ):
165
- self .add_const (- other )
166
- else :
167
- raise TypeError ("type {} not supported" .format (type (other )))
168
- return self
169
-
170
- def __mul__ (self , other : numbers .Real ) -> Union ["mip.LinExpr" , numbers .Real ]:
142
+ def __mul__ (self , other : numbers .Real ) -> "mip.LinExpr" :
171
143
if not isinstance (other , numbers .Real ):
172
144
raise TypeError ("Can not multiply with type {}" .format (type (other )))
173
145
174
- if fabs (other ) < mip .EPS :
175
- return other
176
- elif fabs (other - 1 ) < mip .EPS :
146
+ if fabs (other - 1 ) < mip .EPS :
177
147
return self
178
148
179
149
result = self .copy ()
@@ -185,50 +155,12 @@ def __mul__(self, other: numbers.Real) -> Union["mip.LinExpr", numbers.Real]:
185
155
def __rmul__ (self , other : numbers .Real ) -> "mip.LinExpr" :
186
156
return self .__mul__ (other )
187
157
188
- def __imul__ (self , other : numbers .Real ) -> "mip.LinExpr" :
189
- if not isinstance (other , numbers .Real ):
190
- raise TypeError ("Can not multiply with type {}" .format (type (other )))
191
-
192
- if fabs (other ) < mip .EPS :
193
- self .__const = 0.0
194
- self .__expr = {} # type: Dict[mip.Var, numbers.Real]
195
- return self
196
- elif fabs (other - 1 ) < mip .EPS :
197
- return self
198
-
199
- self .__const *= other
200
- for var in self .__expr .keys ():
201
- self .__expr [var ] *= other
202
- return self
203
-
204
158
def __truediv__ (self , other : numbers .Real ) -> "mip.LinExpr" :
205
159
if not isinstance (other , numbers .Real ):
206
160
raise TypeError ("Can not divide with type {}" .format (type (other )))
207
-
208
- if fabs (other ) < mip .EPS :
209
- raise ZeroDivisionError ()
210
- elif fabs (other - 1 ) < mip .EPS :
211
- return self
212
-
213
- result = self .copy ()
214
- result .__const /= other
215
- for var in result .__expr .keys ():
216
- result .__expr [var ] /= other
217
- return result
218
-
219
- def __itruediv__ (self , other : numbers .Real ) -> "mip.LinExpr" :
220
- if not isinstance (other , numbers .Real ):
221
- raise TypeError ("Can not divide with type {}" .format (type (other )))
222
-
223
161
if fabs (other ) < mip .EPS :
224
- raise ZeroDivisionError ()
225
- elif fabs (other - 1 ) < mip .EPS :
226
- return self
227
-
228
- self .__const /= other
229
- for var in self .__expr .keys ():
230
- self .__expr [var ] /= other
231
- return self
162
+ raise ZeroDivisionError ("Expression division by zero" )
163
+ return self .__mul__ (1.0 / other )
232
164
233
165
def __neg__ (self ) -> "LinExpr" :
234
166
return self .__mul__ (- 1 )
@@ -295,7 +227,7 @@ def __len__(self):
295
227
296
228
def add_const (self , val : numbers .Real ):
297
229
"""adds a constant value to the linear expression, in the case of
298
- a constraint this correspond to the right-hand-side
230
+ a constraint this corresponds to the right-hand-side
299
231
300
232
Args:
301
233
val(numbers.Real): a real number
@@ -334,7 +266,7 @@ def add_term(
334
266
elif isinstance (term , LinExpr ):
335
267
self .add_expr (term , coeff )
336
268
elif isinstance (term , numbers .Real ):
337
- self .add_const (term )
269
+ self .add_const (term * coeff )
338
270
else :
339
271
raise TypeError ("type {} not supported" .format (type (term )))
340
272
@@ -345,13 +277,8 @@ def add_var(self, var: "mip.Var", coeff: numbers.Real = 1):
345
277
var (mip.Var) : a variable
346
278
coeff (numbers.Real) : coefficient which the variable will be added
347
279
"""
348
- if var in self .__expr :
349
- if - mip .EPS <= self .__expr [var ] + coeff <= mip .EPS :
350
- del self .__expr [var ]
351
- else :
352
- self .__expr [var ] += coeff
353
- else :
354
- self .__expr [var ] = coeff
280
+ self .__expr .setdefault (var , 0 )
281
+ self .__expr [var ] += coeff
355
282
356
283
def set_expr (self : "LinExpr" , expr : Dict ["mip.Var" , numbers .Real ]):
357
284
"""Sets terms of the linear expression
@@ -364,11 +291,7 @@ def set_expr(self: "LinExpr", expr: Dict["mip.Var", numbers.Real]):
364
291
self .__expr = expr
365
292
366
293
def copy (self ) -> "mip.LinExpr" :
367
- copy = LinExpr ()
368
- copy .__const = self .__const
369
- copy .__expr = self .__expr .copy ()
370
- copy .__sense = self .__sense
371
- return copy
294
+ return LinExpr (const = self .__const , sense = self .__sense , expr = self .__expr )
372
295
373
296
def equals (self , other : "mip.LinExpr" ) -> bool :
374
297
"""returns true if a linear expression equals to another,
@@ -439,9 +362,14 @@ def violation(self) -> Optional[numbers.Real]:
439
362
If a solution is available, than this property indicates how much
440
363
the current solution violates this constraint.
441
364
"""
365
+ # No violation can be computed for something that isn't a constraint
366
+ # or has no solution yet
367
+ if self .sense == "" or self .x is None :
368
+ return None
369
+
442
370
lhs = sum (coef * var .x for (var , coef ) in self .__expr .items ())
443
371
rhs = - self .const
444
- viol = None
372
+
445
373
if self .sense == "=" :
446
374
viol = abs (lhs - rhs )
447
375
elif self .sense == "<" :
@@ -666,7 +594,7 @@ def __rmul__(self, other: numbers.Real) -> LinExpr:
666
594
def __truediv__ (self , other : numbers .Real ) -> LinExpr :
667
595
if not isinstance (other , numbers .Real ):
668
596
raise TypeError ("Can not divide with type {}" .format (type (other )))
669
- if isinstance ( other , numbers . Real ) and abs (other ) < mip .EPS :
597
+ if abs (other ) < mip .EPS :
670
598
raise ZeroDivisionError ("Variable division by zero" )
671
599
return self .__mul__ (1.0 / other )
672
600
0 commit comments