@@ -216,18 +216,26 @@ class SolveOutputs:
216216 raw_constraints : list [Any ]
217217 """All constraints in raw format"""
218218
219- def variable (self , label : Label ) -> pd .DataFrame :
219+ def variable (self , label : Label , coerce : bool = True ) -> pd .DataFrame :
220220 """Returns variable results for a given label
221221
222222 The returned dataframe always has a `value` column with the variable's
223223 values (0 values may be omitted). If applicable, it will also have a
224- `dual_value` column.
224+ `reduced_cost` column.
225+
226+ Args:
227+ label: Variable label to retrieve
228+ coerce: Round integral variables
225229 """
226230 for res in self .raw_variables :
227231 if res ["label" ] == label :
232+ outline = self .problem_outline .variables [label ]
228233 return _output_dataframe (
229234 res ["entries" ],
230- self .problem_outline .variables [label ].bindings ,
235+ outline .bindings ,
236+ value_name = "value" ,
237+ dual_value_name = "reduced_cost" ,
238+ round_values = coerce and outline .is_integral ,
231239 )
232240 raise Exception (f"Unknown variable { label } " )
233241
@@ -236,33 +244,39 @@ def constraint(self, label: Label) -> pd.DataFrame:
236244
237245 The returned dataframe always has a `slack` column with the
238246 constraint's slack (0 values may be omitted). If applicable, it will
239- also have a `dual_value ` column.
247+ also have a `shadow_price ` column.
240248 """
241249 for res in self .raw_constraints :
242250 if res ["label" ] == label :
243251 return _output_dataframe (
244252 res ["entries" ],
245253 self .problem_outline .constraints [label ].bindings ,
246254 value_name = "slack" ,
255+ dual_value_name = "shadow_price" ,
247256 )
248257 raise Exception (f"Unknown constraint { label } " )
249258
250259
251260def _output_dataframe (
252261 entries : Sequence [Json ],
253262 bindings : Sequence [SourceBinding ],
254- value_name : str = "value" ,
263+ * ,
264+ value_name : str ,
265+ dual_value_name : str ,
266+ round_values : bool = False ,
255267) -> pd .DataFrame :
256268 df = pd .DataFrame (
257269 data = (
258270 (decode_extended_float (e ["value" ]), e .get ("dualValue" ))
259271 for e in entries
260272 ),
261- columns = [value_name , "dual_value" ],
273+ columns = [value_name , dual_value_name ],
262274 index = _entry_index (entries , bindings ),
263275 )
264- if df ["dual_value" ].isnull ().all ():
265- df .drop ("dual_value" , axis = 1 , inplace = True )
276+ if df [dual_value_name ].isnull ().all ():
277+ df .drop (dual_value_name , axis = 1 , inplace = True )
278+ if round_values :
279+ df [value_name ] = df [value_name ].round (0 ).astype (np .int64 )
266280 df .fillna (0 , inplace = True )
267281 return df
268282
0 commit comments