FICO Xpress OptimizationR

Last update 30 April 2020

36.01

FICO Xpress Optimizer Python interface
R

User’s manual©1983–2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac
Corporation ("FICO"). Receipt or possession of this documentation does not convey rights to disclose,
reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation
purposes to determine whether to purchase a license to the software described in this documentation, oras otherwise set forth in a written software license agreement between you and FICO (or a FICO afﬁliate).
Use of this documentation and the software described in it must conform strictly to the foregoing
permitted uses, and no other use is permitted.
The information in this documentation is subject to change without notice. If you ﬁnd any problems in thisdocumentation, please report them to us in writing. Neither FICO nor its afﬁliates warrant that thisdocumentation is error-free, nor are there any other warranties with respect to the documentation except
as may be provided in the license agreement. FICO and its afﬁliates speciﬁcally disclaim any warranties,
express or implied, including, but not limited to, non-infringement, merchantability and ﬁtness for aparticular purpose. Portions of this documentation and the software described in it may contain copyrightof various authors and may be licensed under certain third-party licenses identiﬁed in the software,
documentation, or both.
In no event shall FICO or its afﬁliates be liable to any person for direct, indirect, special, incidental, or
consequential damages, including lost proﬁts, arising out of the use of this documentation or the software
described in it, even if FICO or its afﬁliates have been advised of the possibility of such damage. FICO and
its afﬁliates have no obligation to provide maintenance, support, updates, enhancements, or modiﬁcations
except as required to licensed users under a license agreement.
FICO is a registered trademark of Fair Isaac Corporation in the United States and may be a registeredtrademark of Fair Isaac Corporation in other countries. Other product and company names herein may be
trademarks of their respective owners.
Xpress Optimizer
Deliverable Version: A
Last Revised: 30 April 2020
Version 36.01

Contents
1

Introduction
1.1 Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Installing the Python Xpress module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.1 Installation from the Python Package Index (PyPI) . . . . . . . . . . . . . . . . . .
1.2.2 Installation from Conda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.3 Troubleshooting the installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1
1
1
2
2
2

2 Modeling an optimization problem
2.1 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Creating a problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Variable names and Python objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4 Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5 Objective function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.6 Compact formulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.7 Special Ordered Sets (SOSs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.8 Indicator constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9 Piecewise linear functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10 General constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11 Using loadproblem for efﬁciency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12 Modeling and solving nonlinear problems . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13 Solving a problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14 Querying a problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.15 Reading and writing a problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16 Hints for building models efﬁciently . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3
3
3
4
5
6
8
8
9
9
10
11
12
13
15
15
18
18
19

3 Using Python numerical libraries
3.1 Using NumPy in the Xpress Python interface . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Products of NumPy arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21
21
23

4 Controls and Attributes
4.1 Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5 Accessing controls and attributes as object members . . . . . . . . . . . . . . . . . . . .

24
24
25
25
26
26

5 Using Callbacks
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29
29

6 Examples of use
6.1 Creating simple problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.1.1 Generating a small Linear Programming problem . . . . . . . . . . . . . . . . . . .
6.1.2 A Mixed Integer Linear Programming problem . . . . . . . . . . . . . . . . . . . . .
6.2 Modeling examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31
31
31
32
33

Fair Isaac Corporation Conﬁdential and Proprietary Informationi

Contents

6.2.1 A simple model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.2 Using IIS to investigate an infeasible problem . . . . . . . . . . . . . . . . . . . . .
6.2.3 Modeling a problem using Python lists and vectors . . . . . . . . . . . . . . . . . .
6.2.4 A knapsack problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.5 A Min-cost-ﬂow problem using NumPy . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.6 A nonlinear model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.7 Finding the maximum-area n-gon . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.8 Solving the n-queens problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.9 Solving Sudoku problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3 Examples using NumPy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.1 Using NumPy multidimensional arrays to create variables . . . . . . . . . . . . . .
6.3.2 Using the dot product to create arrays of expressions . . . . . . . . . . . . . . . . .
6.3.3 Using the Dot product to create constraints and quadratic functions . . . . . . . .
6.3.4 Using NumPy to create quadratic optimization problems . . . . . . . . . . . . . . .
6.4 Advanced examples: callbacks and problem querying, modifying, and analysis . . . . . .
6.4.1 Visualize the branch-and-bound tree of a problem . . . . . . . . . . . . . . . . . . .
6.4.2 Query and modify a simple problem . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4.3 Change a problem after solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4.4 Comparing the coefﬁcients of two equally sized problems . . . . . . . . . . . . . .
6.4.5 Combining modeling and API functions . . . . . . . . . . . . . . . . . . . . . . . . .
6.4.6 A simple Traveling Salesman Problem (TSP) solver . . . . . . . . . . . . . . . . . .
6.4.7 Solving a nonconvex MIQCQP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.5 Translated Mosel examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

33
33
34
34
35
36
36
37
37
38
38
39
39
40
40
40
42
43
44
45
46
48
57

7 Reference Manual
7.1 Using this chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Format of the reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Global methods of the Xpress module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3 Methods of the class problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.4 Methods for branching objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5 Methods for adding/removing callbacks of a problem object . . . . . . . . . . . . . . . . .
7.6 Methods to be used within a callback of a problem object . . . . . . . . . . . . . . . . . .
object.extractLinear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
object.extractQuadratic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.abs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.acos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.addcbmsghandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.And . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.asin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.atan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.cos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.Dot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.erf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.erfc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.evaluate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.exp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.featurequery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.free . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.getbanner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.getcheckedmode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.getdaysleft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.getlasterror . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.getlicerrmsg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.getversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

59
59
60
60
61
63
63
64
65
66
67
68
69
70
71
72
73
74
76
77
78
80
81
82
83
84
85
86
87
88
89

Fair Isaac Corporation Conﬁdential and Proprietary Informationii

Contents

xpress.init . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.log10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.min . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.Or . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.pwl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.Prod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.removecbmsghandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.setarchconsistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.setcheckedmode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.setdefaults . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.setdefaultcontrol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.sign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.sin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.sqrt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.Sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.tan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xpress.vars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbbariteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbbarlog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbchecktime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbchgbranchobject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbcutlog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbdestroymt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbgapnotify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbgloballog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbinfnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbintsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcblplog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbmessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbmipthread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbnewnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbnodecutoff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcboptnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbpreintsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbprenode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcbusersolnotify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcoefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addConstraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.adddfs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addgencons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addIndicator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addmipsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addpwlcons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addqmatrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addsetnames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addSOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addtolsets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.addVariable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Fair Isaac Corporation Conﬁdential and Proprietary Information

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
112
114
115
116
117
118
119
121
122
123
124
125
126
127
128
129
130
131
132
133
135
137
138
139
140
141
142
143
144
145
146
147
148
149

iii

Contents

problem.addvars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.basisstability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.btran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.calcobjective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.calcreducedcosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.calcslacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.calcsolinfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.cascade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.cascadeorder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgbounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgcoef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgcoltype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgcascadenlimit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgccoef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgdeltatype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgdf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgglblimit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgmcoef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgmqobj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgnlcoef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgobj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgobjsense . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgqobj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgqrowcoeff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgrhs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgrhsrange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgrowstatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgrowtype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgrowwt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgtolset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.chgvar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.copycallbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.copycontrols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.crossoverlpsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delcoefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delConstraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delcpcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delgencons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delindicators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delpwlcons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delqmatrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delSOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.deltolsets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delVariable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.delvars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.dumpcontrols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.estimaterowdualranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.evaluatecoef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.evaluateformula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.ﬁxglobals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.ﬁxpenalties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.ftran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Fair Isaac Corporation Conﬁdential and Proprietary Information

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

iv

Contents

problem.getAttrib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getattribinfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getbasis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getbasisval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getccoef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcoef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcoefformula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcoefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcolinfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcoltype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getConstraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getControl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcontrolinfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcpcutlist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcpcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcutlist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcutmap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getcutslack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getdirs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getdf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getDual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getdualray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getgencons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getglobal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getiisdata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getIndex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getIndexFromName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getindicators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getinfeas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getlastbarsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getlasterror . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getlb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getlpsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getlpsolval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getmessagestatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getmipsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getmipsolval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getmqobj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getnamelist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getobj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getObjVal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getpivotorder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getpivots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getpresolvebasis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getpresolvemap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getpresolvesol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getprimalray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getProbStatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getProbStatusString . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getpwlcons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getqobj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getqrowcoeff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getqrowqmatrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getqrowqmatrixtriplets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Fair Isaac Corporation Conﬁdential and Proprietary Information

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

v

Contents

problem.getqrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getRCost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getrhs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getrhsrange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getrowinfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getrowstatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getrowtype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getrowwt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getscaledinfeas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getSlack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getslpsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getSolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getSOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.gettolset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getunbvec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getvar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.getVariable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.globalsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.hasdualray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.hasprimalray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.iisall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.iisclear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.iisﬁrst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.iisisolations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.iisnext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.iisstatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.iiswrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.interrupt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadbasis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadbranchdirs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadcoefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loaddelayedrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loaddfs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loaddirs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadlpsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadmipsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadmodelcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadpresolvebasis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadpresolvedirs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadproblem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadsecurevecs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadtolsets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.loadvars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.lpoptimize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.mipoptimize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.msaddcustompreset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.msaddjob . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.msaddpreset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.msclear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.nlpoptimize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.objsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Fair Isaac Corporation Conﬁdential and Proprietary Information

262
263
264
265
266
267
268
269
270
271
272
273
274
276
277
278
279
280
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
298
299
300
301
302
303
304
305
306
307
309
310
311
313
314
315
316
317
318
319
320
321

vi

Contents

problem.postsolve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.presolve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.presolverow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.printmemory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.printevalinfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.read . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.readbasis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.readbinsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.readdirs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.readslxsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.reﬁnemipsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.reinitialize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbbariteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbbarlog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbchecktime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbchgbranchobject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbcutlog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbdestroymt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbgapnotify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbgloballog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbinfnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbintsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecblplog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbmessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbmipthread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbnewnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbnodecutoff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecboptnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbpreintsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbprenode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.removecbusersolnotify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.repairinfeas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.repairweightedinfeas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.repairweightedinfeasbounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.restore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.rhssa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.save . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setbranchbounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setbranchcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbcascadeend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbcascadestart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbcascadevar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbcascadevarfail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbcoefevalerror . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbconstruct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbdestroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbdrcol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbintsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbiterend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbiterstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbitervar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbmessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Fair Isaac Corporation Conﬁdential and Proprietary Information

322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
355
357
359
360
361
362
363
364
365
366
367
368
369
370
371
372
374
375
376
377
378
379
380

vii

Contents

problem.setcbmsjobend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbmsjobstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbmswinner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcboptnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbprenode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbslpend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbslpnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcbslpstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setControl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setcurrentiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setdefaultcontrol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setdefaults . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setindicators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setlogﬁle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setmessagestatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setObjective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.setprobname . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.solve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.storebounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.storecuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.strongbranch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.strongbranchcb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.tune . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.tunerreadmethod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.tunerwritemethod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.unconstruct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.updatelinearization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.validate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.validatekkt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.validaterow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.validatevector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.write . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.writebasis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.writebinsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.writedirs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.writeprtsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.writeslxsol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
problem.writesol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.addbounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.addbranches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.addcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.addrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.getbounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.getbranches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.getid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.getlasterror . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.getrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.setpreferredbranch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.setpriority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
branchobj.validate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Fair Isaac Corporation Conﬁdential and Proprietary Information

381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

viii

Contents

Appendix432

A Contacting FICO
432
Product support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Product education . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Product documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Sales and maintenance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Related services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
FICO Community . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
About FICO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433

Index

Fair Isaac Corporation Conﬁdential and Proprietary Information

434

ix

CHAPTER 1

Introduction
The Xpress Python interface allows for creating and solving optimization problems using the Python
programming language and the FICO Xpress Optimizer library. This manual describes how to use theXpress Python interface.

1.1

Outline
The following chapters cover:Creating, handling, solving, and querying optimization problems (Chapter 2);

Using Python numerical libraries such as NumPy to create optimization problems (Chapter 3);



Setting and getting the value of parameters (controls and attributes) of a problem (Chapter 4);

Using Python functions as callbacks for the Xpress Optimizer and the Xpress Nonlinear solver(Chapter 5);

Several examples of usage of the Xpress Python interface (Chapter 6);



A reference with all functions and parameters in the Python interface (Chapter 7).

It is assumed here that the reader has basic understanding of the Python programming language.
Ample documentation on Python is available at http://docs.python.org, including a tutorial and areference manual. Unless speciﬁed otherwise, Python 3 is used in all of the examples and code
samples throughout this manual. The current version of the Xpress Python interface works on Python
3.5-3.8 and on Python 2.7.
Other components of the FICO-Xpress Optimization suite can interface with Python, albeit not the same
Python versions. The Mosel module python3, for example, works with Python 3.4.3 or later. See theMosel Language Reference Manual for speciﬁcs, and more in general the Xpress Insight Installation
Guide, Appendix A: Supported Platforms for information on Python support.

1.2

Installing the Python Xpress module
The Xpress Python module can be installed from the two main Python repositories: The Python
Package Index (PyPI) and the Conda repository. Installing the Xpress Python interface does not require
one to install the whole Xpress suite, as all necessary libraries are provided.
The install comes with a copy of the community license, which allows for solving problems with up to
5000 between variables and constraints. If you already have an Xpress license, please make sure to set

Fair Isaac Corporation Conﬁdential and Proprietary Information

1

Introduction

the XPRESS environment variable to the directory where the license ﬁle xpauth.xpr is located. See
also Section 1.2.3 below.
The manual is located in the xpress/doc subdirectory of the Python installation folder, and its
location can be identiﬁed by invoking the xpress.manual() function.

1.2.1

Installation from the Python Package Index (PyPI)The Xpress Python interface is available on the PyPI server and can be installed with the following
command:
pip install xpress

Packages for Python 2.7 and 3.5-3.8 are available, for Windows, Linux, and MacOS. The package
contains the Python interface module, its documentation in PDF format, the Xpress Optimizer’s
libraries, various examples of use, and a copy of the community license (seehttp://subscribe.ﬁco.com/xpress-optimization-community-license). Online documentation can beviewed at the FICO Xpress Optimization Help page.

1.2.2

Installation from Conda
A Conda package is available for download with the following command:conda install -c fico-xpress xpress

The content of the Conda package is the same as that of the PyPI package. Similar to the PyPI
package, Conda packages for Python 2.7 and 3.5-3.8 are available, for Windows, Linux, and MacOS.

1.2.3

Troubleshooting the installation
Whether the Xpress Python module is downloaded from PyPI or from the Conda server, there are a few
remarks that might help ensure that the installation works right away. The advice below is independentof the Python platform (PyCharm, Spyder, etc.) that may be in use.
The Xpress Python interface uses the Python package NumPy for some operation, hence NumPy must
be installed. It is usually installed if a Conda installation is used, nevertheless ensure that a
recent-enough version is installed.
After installation, a license is not strictly necessary as the embedded Community license is used. If you
already have a license (for example, a trial license, a full license, or one from the Academic Partnership
Program), the XPRESS environment variable must be set, regardless of the platform, to the directory
containing the license ﬁle. For example, if the license ﬁle is /home/brian/xpauth.xpr, then XPRESS
must be set to /home/brian in order for the module to pick the right license. A message is printed
upon import if XPRESS is not detected, in order to ensure that the user is using the right license ﬁle.
If you installed the Xpress Optimization suite before downloading the Conda or PyPI package with the
Python interface, then the XPRESS variable is already set and no action is necessary.

Fair Isaac Corporation Conﬁdential and Proprietary Information

2

CHAPTER 2

Modeling an optimization problem
This chapter illustrates the modeling capabilities of the Xpress Python interface. It shows how tocreate variables, constraints of different types, add an objective function, and solving and retrieving aproblem’s solution. It also shows how to read or write a problem from/to a ﬁle.

2.1

Getting started
The Xpress Python module is imported as follows:
import xpress

A complete list of methods and constants available in the module is obtained by running the Python
command dir(xpress). Because all types and methods must be called by prepending "xpress.", itis advisable to alias the module name upon import:
import xpress as xp

We assume that this is the way the module is imported from now on. It is also possible to import all
methods and types to avoid prepending the module name or its alias, but this practice is usuallyadvised against:from xpress import ⁎2.2

Creating a problem
Create an empty optimization problem myproblem as follows:
myproblem = xp.problem()

A name can be assigned to a problem upon creation:
myproblem = xp.problem(name="My first problem")

The problem has no variables or constraint at this point. The synopsis of the xpress.problem
method is as follows:
xpress.problem(⁎args, name='noname', sense=xpress.minimize)

The only two named arguments are name and sense and they denote the problem name and the
optimization sense, respectively. The argument args is a list composed as follows:

Fair Isaac Corporation Conﬁdential and Proprietary Information

3Modeling an optimization problem

zero or more variables declared with xpress.var or xpress.vars;

zero or more constraints created from functions of the variables;at most one function in the variables;at most one string.

The variables and constraints will be added to the problem as if they were with the
problem.addVariable and problem.addConstraint functions, respectively, while the function istreated as the objective function and added to the problem as if with the problem.setObjectivefunction. If the sense parameter is also added, this becomes the optimization sense. Because thearguments are scanned in the order they are received, the user ought to ensure that a constraint or theobjective function are passed only after all of the variables containing them are passed.
Note that indicator constraints (see Section 2.8) cannot be added directly in the problem declaration
but need to be added using problem.addIndicator.
The following is an example of the compact declaration: variables x and y are declared ﬁrst, then the
problem declaration is passed these variables and followed by two constraints and a function to be
used as objective function. Note that because no optimization sense is given, minimization isassumed.
import xpress as xp
x = xp.var()y = xp.var(lb=-1, ub=1)
prob = xp.problem(x, y, 2⁎x + y >= 1, x + 2⁎y >= 1, x + y, name='myproblem')All operations for adding/deleting variables, constraint, SOS and others are allowed on problems
declared this way; note that setting a new objective function with problem.setObjective resets the
optimization sense, and sets it to xpress.minimize if none is given.

2.3

Variables
The Xpress type var allows for creating optimization variables. Note that variables are not tied to a
problem but may exist globally in a Python program. In order for them to be included into a problem,
they have to be explicitly added to that problem. Below is the complete declaration with the list of allparameters (all of them are optional):var (name, lb, ub, threshold, vartype)

The parameters are:1. name is a Python UTF-8 string containing the name of the variable (its ASCII version will be saved
if written onto a ﬁle); a default name is assigned if the user does not specify it;
2. lb is the lower bound (0 by default);
3. ub is the upper bound (+inf is the default);
4. threshold is the threshold for semi-continuous, semi-integer, and partially integer variables; itmust be between its lower and its upper bound; it has no default, so if a variable is deﬁned as
partially integer the threshold must be speciﬁed;
5. vartype is the variable type, one of the six following types:
xpress.continuous for continuous variables;

Fair Isaac Corporation Conﬁdential and Proprietary Information

4Modeling an optimization problem



xpress.binary for binary variables (lower and upper bound are further restricted to 0 and1);

xpress.integer for integer variables;

xpress.semicontinuous for semi-continuous variables;

xpress.semiinteger for semi-integer variables;

xpress.partiallyinteger for partially integer variables.

The features of each variable are accessible as members of the associated object: after declaring avariable with x = xpress.var(), its name, lower and upper bound can be accessed via x.name,x.lb, and x.ub. Note that, after a variable x has been added to one or more problems, a change in its
feature will not be reﬂected in these problems, but only in the problems to which this variable is added
subsequently.
One or more variables (or list of variables) can be added to a problem with the addVariable method:v = xp.var(lb=-1, ub=2)
m.addVariable (v)x = [xp.var(ub=10) for i in range(10)]y = [xp.var(ub=10, vartype=xp.integer) for i in range(10)]m.addVariable (x,y)

By default, variables added to an Xpress problems are constrained to be nonnegative. In order to add afree variable, one must specify its lower bound to be –∞ as follows:v = xp.var(lb=-xp.infinity)

Variable names and Python objects
Variables and, as described below, constraints and other objects of the Xpress Python interface canhave a name. Variable names and constraint names can be useful when saving a problem to a ﬁle andwhen querying the problem for the value of a variable in an optimal solution. If a variable is not given a
name explicitly, it will be assigned a default name that is usually "C" followed by a sequence number.
Python also uses these names when printing expressions, because the variables’ __str__ function isredirected to their name. Therefore, when querying Python for a variable or for an expression
containing that variable, its name will be printed rather than the Python object used in the program, as
in the following example:>>> v = xp.var(lb=-1, ub=2)>>> v
C1>>> v.__str__()'C1'>>> x = xp.var(name='myvar')>>> v + 2 ⁎ x
C1 + 2 myvar>>>

This allows for querying a problem using both the variable object and its name, depending on what ismore convenient. The following example prints twice an optimal solution to a simple problem:x = xp.var(name='var1')
y = xp.var(name='var2')
p = xp.problem(x, y, x + y >= 3, x + 2⁎y)p.solve()

Fair Isaac Corporation Conﬁdential and Proprietary Information

5Modeling an optimization problem
print(p.getSolution([x, y]))print(p.getSolution(['var1', 'var2']))

It can be therefore useful to create xpress.var objects with a meaningful argument, perhaps similar
to the name they have in the Python program one is writing.

2.4

Constraints
Linear, quadratic, and nonlinear constraints can be speciﬁed as follows:
constraint (constraint, body, lb, ub, sense, rhs, name)

The parameters are:
1. constraint is the full-form constraint, such as x1 + 2 ⁎ x2 <= 4;
2. body is the body of the constraint, such as 3 ⁎ x1 + x2 (it may contain constants);
3. lb is the lower bound on the body of the constraint;
4. ub is the upper bound on the body of the constraint;
5. sense is the sense of the constraint, one among xpress.leq, xpress.geq, xpress.eq, andxpress.range; in the ﬁrst three cases, the parameter rhs must be speciﬁed; only in the fourthcase must lb and ub be speciﬁed;
6. rhs is the right-hand side of the constraint;
7. name is the name of the constraint. Parameters lb, ub, and rhs must be constant.
A much more natural way to formulate a constraint is possible though:myconstr = x1 + x2 ⁎ (x2 + 1) <= 4myconstr2 = xp.exp(xp.sin(x1)) + x2 ⁎ (x2⁎⁎5 + 1) <= 4

One or more constraints (or list of constraints) can be added to a problem via the addConstraint
method:m.addConstraint (myconstr)
m.addConstraint(v1 + xp.tan(v2) <= 3)m.addConstraint(x[i] + y[i] <= 2 for i in range(10))
myconstr = x1 + x2 ⁎ (x2 + 1) <= 4m.addConstraint(myconstr)

In order to help formulate compact problems, the Sum operator of the xpress module can be used toexpress sums of expressions. Its argument is a list of expressions:m.addConstraint(xp.Sum([y[i] for i in range(10)]) <= 1)
m.addConstraint(xp.Sum([x[i]⁎⁎5 for i in range(9)]) <= x[9])When handling variables or expressions, it is advised to use the Sum operator in the Xpress module
rather than the native Python operator, for reasons of efﬁciency.
As for variables, an object of type constraint allows for read/write access of its features via its
members name, body, lb, and ub. The same caveat for variables holds here: any change to an object’s
members will only have an effect in the problems to which a constraint is added after the change.

Fair Isaac Corporation Conﬁdential and Proprietary Information

6Modeling an optimization problem

A set of variables or constraint can also be created using Python’s fundamental data structure: lists
and dictionaries, as well as NumPy’s arrays. As described in Section 2.16 below, one can for example
create a list of variables x[i], all with upper bound 10, indexed from 0 to k-1 as follows:k=24
x = [xpress.var(ub=10) for _ in range(k)]If a more elaborate indexing is required, dictionaries can be used. Suppose we want to create an integer
variable x for each item in the list [’Seattle’,’Miami’,’Omaha’,’Charleston’]. Then
L = ['Seattle','Miami','Omaha','Charleston']x = {i: xpress.var(vartype=xpress.integer) for i in L}

This allows one to refer to such variables using the names in L, for instance x[’Seattle’],x[’Charleston’], etc.
Similarly, one can use lists and dictionaries to create constraints, like in the following example on lists:
L = range(20)x = [xpress.var(ub=1) for i in L]
y = [xpress.var(vartype=xpress.binary) for i in L]
constr = [x[i] <= y[i] for in L]
p = xpress.problem()p.addVariable(x,y)
p.addConstraint(constr)

Below is an example with dictionaries. Note that Python allows for conditional indexing on the twoparameters i and j, and each constraint can be referred to with pairs of names, e.g.
cliq[’Seattle’,’Miami’].
L = ['Seattle','Miami','Omaha','Charleston']x = {i: xpress.var(vartype=xpress.binary) for i in L}
cliq = {(i,j): x[i] + x[j] <= 1 for i in L for j in L if i != j}
p = xpress.problem()p.addVariable(x)p.addConstraint(cliq)

There is yet another function for creating an indexed set of variables: the function xpress.vars. It
takes one or more lists, sets, or ranges, and produces as many variables as can be indexed with all
combinations from the provided lists/sets. This allows for creating a set of variables with the same
bounds and type and a similar name, in case the problem is written onto an MPS or LP ﬁle. Its syntax is
as follows:
xpress.vars(⁎indices, name='x', lb=0, ub=xpress.infinity,
threshold = -xpress.infinity, vartype=xpress.continuous)

The parameter ⁎indices stands for one or more arguments, each a Python list, a Python set, or apositive integer. If ⁎indices consists of one list, then the result contains one element for eachelement of the list. In case of more lists, sets, or ranges in ⁎indices, the Cartesian product of theselists/sets provides the indexing space of the result. All other arguments are the same as for thedeclaration of a single variable. Here is an example of use:
myvar = xpress.vars(['a','b','c'], lb=-1, ub=+1)

The result is the three variables myvar[’a’], myvar[’b’], and myvar[’c’], all with -1 as lower
bound and +1 as upper bound. The following is an example of multi-indexed variables:y = xpress.vars(['a','b','c','d'], [100, 120, 150], vartype=xpress.integer)

Fair Isaac Corporation Conﬁdential and Proprietary Information

7

Modeling an optimization problem

The result is the 12 variables y[’a’,100], y[’a’,120], y[’a’,150], y[’b’,100],...,
y[’d’,150].
If argument name is not speciﬁed, a preﬁx "x" is used. The name of each variable resulting from a call to
xpress.vars is the given preﬁx and the comma-separated list of index values between brackets, forexample it will be "x(a,100)", "x(a,120)", "x(a,150)" for the example above. The callx = xpress.vars(['a','b','c','d'], [100, 120, 150], name='var')

produces variables x[’a’,100] whose name is "var(a,120)", etc.
In the ⁎indices argument, in lieu of a list or a set one can also specify an integer positive number k,which is interpreted as the range of numbers 0,1,...,k-1. Thus the call x = xpress.vars(5, 7,
vartype = xpress.integer) creates 35 variables x[0,0], x[0,1], x[0,2],..., x[4,6].
The xpress.vars function, effectively, is a more readable way to create a Python dictionary ofvariables. The instructionx = xpress.vars(['a','b','c','d'], [100, 120, 150], ub=20, name='newvar')

is equivalent to the following:x = {(i,j): xpress.var(ub=20, name='newvar({0},{1})'.format(i,j))
for i in ['a','b','c','d']for j in [100, 120, 150]}

2.5

Objective function
The objective function is any expression, so it can be constructed as for constraints. The method
problem.setObjective can be used to set (or replace if one has been speciﬁed before) the
objective function of a problem. The deﬁnition of setObjective is as follows:
setObjective(objective, sense=xpress.minimize)

where objective is the expression deﬁning the new objective and sense is either
xpress.minimize or xpress.maximize. Examples follow; in the ﬁrst, the objective function is to beminimized as per default, while the second example speciﬁes the optimization sense as maximization.
m.setObjective(xp.Sum ([y[i]⁎⁎2 for i in range (10)]))m.setObjective (v1 + 3 ⁎ v2, sense=xp.maximize)

Finally, a note on efﬁciency. For creating a large number of variables, one can obtain a Numpy
multiarray of any dimension by just specifying numbers as the index arguments, as in the following
example where a 4x7x5 multiarray of variables is created:x = xp.vars(4,7,5)

For added efﬁciency, one can drop variable naming if standard names (such as "C1", "C2", "C3") are
acceptable. This is done by specifying the argument name="" as in the example below.
x = xp.vars(4,7,5, name="")2.6

Compact formulation
The interface allows for a more compact problem formulation where xpress.problem is passed all

Fair Isaac Corporation Conﬁdential and Proprietary Information8Modeling an optimization problem

components of the problem: for instance, consider the code below:
import xpress as xp
x = xp.var(vartype=xp.integer, name='x1', lb=-10, ub=10)
y = xp.var(name='x2')
p = xp.problem(x, y, x⁎⁎2 + 2⁎y, x + 3⁎y <= 4, name='myexample', sense=xp.maximize)p.solve()

The declaration of p is equivalent to the following:
import xpress as xp
x = xp.var(vartype=xp.integer, name='x1', lb=-10, ub=10)
y = xp.var(name='x2')
p = xp.problem(name='myexample')p.addVariable(x, y)p.setObjective(x⁎⁎2 + 2⁎y, sense=xp.maximize)p.addConstraint(x + 3⁎y <= 4)p.solve()

2.7

Special Ordered Sets (SOSs)
A Special Order Set (SOS) is a modeling tool for constraining a small number of consecutive variables
in a list to be nonzero. The Xpress Python interface allows for deﬁning a SOS as follows:sos (indices, weights, type, name)

The ﬁrst argument, indices, is a list of variables, while weights is a list of ﬂoating point numbers.
The type of SOS (either 1 or 2) is speciﬁed by type. While indices and weights are mandatory
parameters, type and name are not; type is set to a default of 1 when not speciﬁed. Examples follow:
set1 = xp.sos(x, [0.5 + i⁎0.1 for i in range(10)], type=2)
set2 = xp.sos([y[i] for i in range(5)], [i+1 for i in range(5)])
set3 = xp.sos([v1, v2], [2, 5], 2)One or more SOS can be added to a problem via the problem.addSOS method:
set1 = xp.sos(x, [0.5 + i⁎0.1 for i in range(10)], type=2)
m.addSOS(set1)
n = 10w = [xp.var() for i in range(n)]m.addSOS([xp.sos([w[i],w[i+1]], [2,3], type=2) for i in range(n-1)])

The name member of a SOS object can be read and written by the user.

2.8

Indicator constraints
Indicator constraints are deﬁned by a binary variable, called the indicator, and a constraint. Dependingon the value of the indicator, the constraint is enforced or relaxed.
For instance, if the constraint x + y ≥ 3 should only be enforced if the binary variable u is equal to 1, then(u = 1 → x + y ≥ 3) is an indicator constraint.
An indicator constraint in Python can be added to a problem with the addIndicator as follows (notethe "==" as the symbol for equality):m.addIndicator(vb == 1, v1 + v2 >= 4)

Fair Isaac Corporation Conﬁdential and Proprietary Information

9Modeling an optimization problem

2.9

Piecewise linear functions
Other types of constraints are available for modelling. Piecewise linear constraints allow to deﬁne avariable as a piecewise linear function of another. The function does not have to be continuous, butplease see the Optimizer’s manual for information on how discontinuities are dealt with.
The most efﬁcient way to model piecewise linear functions is through the API function
problem.addpwlcons.
x = xp.var(lb=-xp.infinity)y = xp.var()
z1 = xp.var(lb=-xp.infinity)z2 = xp.var(lb=-xp.infinity)p = xp.problem(x,y,z1,z2)# Define z1 and z2 as a piecewise linear functions of x. Two functions# are defined.
p.addpwlcons([x, x],# independent variable of each function[z1, z2], # created variables[0,4],# index of the first breakpoints for z1 and z2[0,4, 4 7, -2,-1,1,2],# x values of the breakpoints[4,12,11,20,-2,-2,2,2])# y values
p.setObjective(z1 + 2⁎y)p.addConstraint(z2 <= y)p.solve()

The above example creates variables x, y, z1, and z2, then constrains z1 and z2 to be (piecewise
linear) functions of x, to be used with y in other constraints and in the objective function.
The Xpress Python interface provides another, more intuitive way of specifying such a function with themethod xpress.pwl, which is passed a dictionary associating intervals (deﬁned as tuples of twoelements) with linear functions. The code below exempliﬁes the use of xpress.pwl to construct twofunctions. The ﬁrst, which is included into the objective of the problem, is the piecewise linear function
2x + 4 for x ∈ [0, 4] and 3x – 1 for x ∈ [4, 7]; the second function is constant at –2 for x ≤ –1, it is equal to
2x for x ∈ [–1, 1], and is constant at 2 for x ≥ 2:x = xp.var(lb=-xp.infinity)y = xp.var()p = xp.problem(x, y)# Create objective and constraint directly, without first creating# piecewise linear functions.
p.setObjective(xp.pwl({(0, 4): 2⁎x + 4, (4, 7): 3⁎x - 1}) + 2⁎y)p.addConstraint(xp.pwl({(-xp.infinity, -1): -2,(-1, 1):2⁎x,(1, xp.infinity):2}) <= y)p.solve()

Here the deﬁnition of auxiliary variables z1 and z2 becomes redundant as the calls to xpress.pwl do
not need any extra variable. The dictionary that is used in xpress.pwl has tuples of two elements
each as keys and linear expressions (or constants) as values.
The tuples are treated as (pairwise disjoint) intervals, hence every tuple (a,b) in the set of keys mustbe such that a ≤ b and such that, for any two tuples (a,b) and (c,d) in the keys, either b ≤ c ord ≤ a.
Piecewise linear functions should be deﬁned over the whole domain of the independent variable (x inthe example above); with the syntax of xpress.pwl, it is possible to omit a portion of the domain of
the independent variable; in that case the value of the function is taken to be zero.

Fair Isaac Corporation Conﬁdential and Proprietary Information

10Modeling an optimization problem

Piecewise linear functions can be used as operators when deﬁning an optimization problem. For
instance, one could write the constrainty + 3⁎z⁎⁎2 <= 3⁎xp.pwl({(0, 1): x + 4, (1, 3): 1})

Note that regardless of how a piecewise linear constraint is formulated, there must always be only one
independent variable, i.e., the piecewise linear function is always univariate. In addition, piecewise
constant functions need a further speciﬁcation as a variable does not appear in the values: for thiscase, one can specify the key-value pair None: x as in the example below.
# Set a piecewise CONSTANT objective
p.setObjective(xp.pwl({(0, 1): 4, (1, 2): 1, (2,3): 3, None: x})

2.10

General constraints
The Xpress Python interface allows the user to use the mathematical operators min, max, abs, and thelogical operators and, or without having to explicitly introduce extra variables. The Xpress Optimizer
handles such operators by automatically reformulating them as MIP constraints. These constraints arecalled general constraints by the Optimizer’s library.
The min (resp. max) general operators impose that a variable be the minimum (resp. maximum) of two
or more variables in a list of arguments. The abs constraints link a variable y to another variable x sothat y = |x|.
The And and Or operators express a logical link between two or more binary variables x1 , x2 , ..., xk . The
result of this function is itself a binary expression that can take on value 0 (false) or 1 (true).
The most efﬁcient way, in terms of modelling speed, to formulate a model using the aforementioned
operator is through the function problem.addgencons, which adds a general constraint. In thefollowing example, variables y1, y2, and y3 are constrained to be, respectively, the maximum among
the set x[0], x[1], 46 the absolute value of x[3], and the logical and of x[4], x[5], and x[6].
x = [xp.var() for _ in range(7)]y1 = xp.var()y2 = xp.var()y3 = xp.var()
type = [xpress.gencons_max, xpress.gencons_abs, xpress.gencons_and]resultant = [y1, y2, y3]
colstart = [0, 2, 3]
col = [x[0], x[1], x[3], x[4], x[5], x[6]]valstart = [0,1,1]
val = [46]p = xp.problem(x, y1, y2, y3)prob.addgencons(prob, type, resultant, colstart, col, valstart, val);prob.solve()

A more intuitive way to create problems containing these operators is by using the methods max, min,abs, And, and Or of the xpress module.
x = [xp.var() for _ in range(4)]y1 = xp.var()y2 = xp.var()p = xp.problem(x,y1,y2)
p.addConstraint(y1 == xp.max(x[0], x[1], 46)) # max() accepts a tuple of arguments
p.addConstraint(y2 == xp.abs(x[3]))p.addConstraint(y3 == xp.And(x[4], x[5], x[6]))p.solve()

The methods And and Or can be replaced by the Python binary operators & and |, as in the following

Fair Isaac Corporation Conﬁdential and Proprietary Information

11Modeling an optimization problem

exampley = [xp.var(vartype=xp.binary) for _ in range(5)]p = xp.problem(y)p.addConstraint((y[0] & y[1]) + (y[2] | y[3]) + 2⁎y[4] >= 2)

Note that And and Or have a capital initial as the lower-case correspondents are reserved Python
keywords, and that the & and | operators have a lower precedence than arithmetic operators such as +and should hence be used with parentheses.
We also point out that because the & and | operator have lower operator precedence in Python thanother arithmetic operators (+, ∗, etc.) and even comparison operators (≤, etc.), all uses of & and | should
be enclosed in brackets. as shown in the examples above.

2.11

Using loadproblem for efﬁciency
The high-level functions problem.addConstraint and problem.addVariable allow for efﬁcient,concise, and understandable modeling of any optimization problem. An even faster way to create aproblem is through the problem.loadproblem function, which uses a more direct interface to the
Optimizer’s libraries and is hence preferable with very large problems and when efﬁciency in model
creation is necessary.
The functon problem.loadproblem can be used to create problems with linear and/or quadratic
constraints, a linear and/or quadratic objective function, and with continuous and/or discrete variables.
Its syntax with default parameter values allows for specifying only the components of interest. We refer
the reader to its entry in Chapter 7, and present here a few examples of usages. More examples areshown in Chapter 6.
The ﬁrst example uses loadproblem to create a problem similar to that created earlier in this chapter.
We ﬁrst write the problem using standard modeling functions:
import xpress as xp
x = xp.var(vartype=xp.integer, name='x1', lb=-10, ub=10)
y = xp.var(name='x2')
p = xp.problem(name='myexample')p.addVariable(x, y)p.setObjective(x⁎⁎2 + 2⁎y)p.addConstraint(x + 3⁎y <= 4)p.addConstraint(7⁎x + 4⁎y >= 8)

The following code creates a problem with the same features, including variable names and their types
import xpress as xp
p = xp.problem()p.loadproblem(probname='myexample',qrtypes=['L', 'G'],
rhs=[4, 8],
range=None,obj=[0, 2],mstart=[0, 2, 4],mrwind=[0, 1, 0, 1],
dmatval=[1, 7, 3, 4],mnel=None,
dlb=[-10,0],dub=[10,xp.infinity],
mqcol1=[0],mqcol2=[0],dqe=[2],
qgtype=['I'],
mgcols=[0],Fair Isaac Corporation Conﬁdential and Proprietary Information# constraint senses# right-hand sides# linear obj. coeff.
# start pos. of all columns# row index in each column# coefficients# variable lower bounds#
upper bounds# quadratic obj. terms, column 1#
column 2#
coeff# variable types

12

Modeling an optimization problem
colnames=['x1', 'x2'])

Apart from the intuitive lists qrtypes (for constraint types: ’L’ for "lesser-than", ’G’ for"greater-than", ’E’ for "equal-to"), rhs (constraints’ right-hand sides), obj (objective linear
coefﬁcients), dlb and dub (variables’ lower and upper bounds), a few paramters deserve someattention. The three lists mstart, mrwind, dmatval describe the coefﬁcient matrix: mrwind anddmatval contain, respectively, the row indices and the coefﬁcients, while mstart is a list of n + 1
integers (where n is the number of variables, i.e., the size of obj, dlb, and dub); mstart[i] indicatesthe position, within mrwind and dmatval, of the indices and coefﬁcients of the i-th column. The lastelement mstart[n+1] indicates the number of nonzeros in the matrix.
The following shows two equivalent knapsack problems, again created ﬁrst using the high-level
modeling routines and then the lower-level API function.
import xpress as xp
N = 6
x = [xp.var(vartype=xp.binary) for _ in range(N)]value = [1, 4, 6, 4, 7, 3]
weight = [1, 3, 5, 5, 8, 4]
p = xp.problem(name='knapsack')
p.addVariable(x)p.setObjective(xp.Sum(value[i] ⁎ x[i] for i in range(N)), sense=xp.maximize)p.addConstraint(xp.Sum(weight[i] ⁎ x[i] for i in range(N)) <= 12)

Note that problem.loadproblem assumes that the optimization sense is minimization and hence acall to problem.chgobjsense is necessary to set the sense to maximization.
import xpress as xp
p = xp.problem()N = 6value = [1, 4, 6, 4, 7, 3]
weight = [1, 3, 5, 5, 8, 4]
p.loadproblem(probname='knapsack',
qrtypes=['L'],
rhs=[12],
range=None,
obj=value,
mstart=range(N+1),
mrwind=[0] ⁎ N,
dmatval=weight,
mnel=None,
dlb=[0] ⁎ N,
dub=[1] ⁎ N,
qgtype=['B'] ⁎ N,
mgcols=range(N))
p.chgobjsense(xp.maximize)

2.12# constraint senses# right-hand sides# linear obj. coeff.
# start pos. of all columns# row index in each column (always 0)# coefficients# variable lower bounds#
upper bounds# variable types

Modeling and solving nonlinear problems
Version 8.3 of the Xpress Optimizer suite introduces nonlinear modeling in the Python interface. It
allows for creating and solving nonlinear, possibly nonconvex problems with similar functions as forlinear, quadratic, and conic problems and their mixed integer counterpart.
A nonlinear problem can be deﬁned by creating one or more variables and then adding constraints andan objective function. This can be done using the same Python calls as one would do for otherproblems. The available operators are +, -, ⁎, /, ⁎⁎ (which is the Python equivalent for the power
operator, "ˆ"). Univariate functions can also be used from the following list: sin, cos, tan, asin, acos,
atan, exp, log, log10, abs, sign, and sqrt. Multivariate functions are min and max, which canreceive an arbitrary number of arguments.
Examples of nonlinear constraints are as follows:

Fair Isaac Corporation Conﬁdential and Proprietary Information

13

Modeling an optimization problem
import xpress as xp
import mathx = xp.var()p = xp.problem()p.addVariable(x)# polynomial constraint
p.addConstraint(x⁎⁎4 + 2 ⁎ x⁎⁎2 - 5>= 0)# A terrible way to constrain x to be integer
p.addConstraint(xp.sin (math.pi ⁎ x) == 0)
p.addConstraint(x⁎⁎2 ⁎ xp.sign (x) <= 4)Note that non-native mathematical functions such as log and sin must be preﬁxed with xpress or its
alias, xp in this case. This can be avoided by importing all symbols from xpress using the import ⁎command as follows
from xpress import ⁎x = var()a = sin(x)but this hides namespaces and is usually frowned upon.
User functions are also accepted in the Python interface, and must be speciﬁed with the keyword user
and the function as the ﬁrst argument. They are handled in the Nonlinear solver in a transparent way, so
all is needed is to deﬁne a Python function to be run as the user function and specify it in the problem
with user, as in the following example:
import xpress as xp
import mathdef mynorm(x1, x2):
return (math.sqrt(x1⁎⁎2 + x2⁎⁎2) 2⁎x1, 2⁎x2)
def myfun(v1, v2, v3):
return v1 / v2 + math.cos(v3)x,y = xp.var(), xp.var()p = xp.problem()p.addVariable(x,y)
p.setObjective(xp.user (mynorm, x, y, derivatives=True))p.addConstraint(x+y >= 2)
p.addConstraint(xp.user (myfun, x⁎⁎2, x⁎⁎3, 1/y) <= 3)

Note that user functions can be speciﬁed so that they can return derivatives. If we do not wish to return
derivatives, a Python function in k variables must return a single number. If we want to provide thesolver with derivatives, then the function must return a tuple of k+1 numbers.
When deﬁning a user function that provides derivatives (see mynorm in the example), we must set thederivative=True parameter in the xpress.user call. The derivative parameter is False bydefault. If a function returns a tuple of values but it is deﬁned with derivatives=False or, viceversa,
if it returns a single value but it is deﬁned with derivatives=True, the behaviour is undeﬁned.
As a ﬁnal word of caution, solving nonlinear problem requires a preprocessing step that is transparent
to the user except for two steps: ﬁrst, if the objective function has a nonlinear component f(x) then a
new constraint (called objective transfer row or objtransrow) and a new variable, the objective transfer
column or objtranscol) are called that are deﬁned as follows:

Fair Isaac Corporation Conﬁdential and Proprietary Information

14

Modeling an optimization problem

objtransrow : –objtranscol + f(x) = 0
The resulting problem is equivalent in that the set of optimal (resp. feasible) solutions of this problem
will be the same as those of the original problem. The user, however, will notice an increase by one ofboth the number of rows and of columns when a nonlinear objective function is set.
The second caveat is about yet another variable that may be added to the problem for reasons having
to do with one of the Xpress Nonlinear solvers. This variable is called equalscol and it is ﬁxed to 1. Its
existence and value are therefore of no interest to the user.
It should also be noted that the control xslp_postsolve is set to 1 by default when the solver uses
the SLP nonlinear solver. This is necessary to ensure that the solution retrieved after a solve() or
nlpoptimize() call refers to the original problem and not to a possible reformulation. The reader canﬁnd more information on this in the Xpress Nonlinear reference manual.

2.13

Solving a problem
Simply call solve() to solve an optimization problem that was either built or read from a ﬁle. The typeof solver is determined based on the type of problem: if at least one integer variable was declared, thenthe problem will be solved as a mixed integer (linear, quadratically constrained, or nonlinear) problem,
while if all variables are continuous the problem is solved as a continuous optimization problem. If the
problem is nonlinear in that it contains non-quadratic, non-conic nonlinear constraints, then theappropriate nonlinear solver of the Xpress Optimization suite will be called. Note that in case of anonconvex quadratic problem, the Xpress Nonlinear solver will be applied as the Xpress Optimizer
solver cannot handle such problems.
m.solve ()The status of a problem after solution can be inquired via the functions getProbStatus() and
getProbStatusString() as follows:
import xpress as xp
m = xp.problem()m.read("example3.lp")
m.solve()print("problem status:", m.getProbStatus())
print("problem status, explained: ", m.getProbStatusString())

The meaning of the returned value is explained in the Optimizer’s reference manual. Note that the value
and string returned by the above functions reﬂect the type of problem as input by the user, not the way
the problem was last solved. If the user creates a MILP and then solves it as an LP with the ﬂag "l",then both getProbStatus() and getProbStatusString() yield the status of the MILP rather thanthe LP relaxation. At all effects, the call p.getProbStatus() returns p.attributes.lpstatus if p
has continuous variables and p.attributes.mipstatus if p has integer variables.
The output of the solver when reading and solving a problem is the same as with other interfaces of theXpress Optimizer. The verbosity level is determined by the control outputlog, which is 1 by default. To
turn off the solver’s output, it should be set to zero (see Chapter 4 for how to set a control).

2.14

Querying a problem
It is useful, after solving a problem, to obtain the value of an optimal solution. After solving a continuousor mixed integer problem, the two methods getSolution and getSlack return the list (of portions

Fair Isaac Corporation Conﬁdential and Proprietary Information

15

Modeling an optimization problem

thereof) of an optimal solution or the slack of the constraints, respectively. If an optimal solution was
not found but a feasible solution is available, these methods will return data based on this solution.
Both getSolution and getSlack can be used in multiple ways: if no argument is passed, the wholesolution or slack list is returned. If a range of indices is passed, a list of values is returned
corresponding to the range speciﬁed. One can also pass a list of variables to obtain the value of thesevariables in the solution found.
For getSolution only, there are more possible ways to call it: indices, strings, expressions are thebasic types. An index ind will yield the value of the variable whose index in that problem (i.e. the orderin which it was added to the problem) is ind; if the index is out of range, an error will occur. A string
str will yield the value of the variable whose name is equal to str, if such variable exists, otherwise anerror will occur. Finally, an expression, which can be just a variable, will yield the value of the expression
given the current solution.
These basic types can be combined, even on multiple levels, with Python’s fundamental aggregate
types: getSolution can be passed a list, a dictionary, a tuple, or any sequence, including NumPy
arrays, of indices, strings, expressions, and other aggregate objects thereof. The result will have thesame structure as the argument passed (list, dictionary, etc.) containing the value corresponding to thepassed expressions, variable indices, or variable names.
The uses of getSolution are exempliﬁed in the following code:
import xpress as xp
import numpy as np
v1 = xp.var(name='Var1')
x = [xp.var(lb=-1, ub=1, vartype=xp.integer) for i in range(10)]m = xp.problem()m.addVariable(v1, x)[...] # add constraints and objective
m.solve()print(m.getSolution ())
print("v1 is", m.getSolution(v1))
a = m.getSolution(x)b = m.getSolution(range(4))
c = m.getSolution('Var1')
e = m.getSolution({1: x, 2: 0,
3: 'Var1'})
d = m.getSolution(v1 + 3⁎x)e = m.getSolution(np.array(x))# Prints a list with an optimal solution# Only prints the value of v1# Gets the values of all variables in the list x# Gets the value of v1 and x[0], x[1], x[2], i.e.
# the first four variables of the problem# Gets the value of v1 by its name
# Returns a dictionary containing the same keys as# in the arguments and the values of the# variables/expressions passed# Gets the value of an expression under the# current solution# Gets a NumPy array with the solution of x

Consider the last eight instructions. The ﬁrst of them returns a Python list of ncol ﬂoating point scalars,
where ncol is the number of variables of the problem (nrow is the number of constraints, the size of thelist returned by getSlack) containing the full solution. The second example retrieves the value of thesingle variable v1.
The third example returns an array of the same size as x with the value of all variables of the list x. The
fourth example shows that a range of indices can be speciﬁed in order to obtain a list of values without
specifying the corresponding variables. Recall that the column and row indices begin at 0. The ﬁfth line
shows that a variable can be passed by name, while the sixth line shows that passing a dictionary withvariables, expression, indices, or variable names returns a dictionary with the same keys as thedictionary passed, but with its values set to the values of the corresponding variables/expressions.

Fair Isaac Corporation Conﬁdential and Proprietary Information

16Modeling an optimization problem

The seventh line shows how to request the value of an expression when evaluated with the current
solution found for the problem, and the eight line is equivalent to m.getSolution(x) but the returned
object is a NumPy array with the solution (this can be useful when using NumPy with large vectors bothfor deﬁning a problem and handling solution vectors).
The method getSlack works only with indices, constraint names, constraint objects, and lists ofindices/names/constraints. The following examples illustrate a few possible uses.
import xpress as xp
N = 10x= [xp.var(vartype=xp.binary) for i in range(N)]m= xp.problem()m.addVariable(x)con1 = xp.Sum(x[i] ⁎ i for i in range(N)) <= N)
con2 = (x[i] >= x[i+1] for i in range(N-1))
m.addConstraint(con1, con2)
m.setObjective(xp.Sum(x[i] for i in range(N))
m.solve()print(m.getSlack())# prints a list of slacks for all N constraints
print("slack_1 is", m.getSlack(con1)) # only prints the slack of con1
a = m.getSlack(con2)
b = m.getSlack(range(2))# gets the slack of N-1 constraints con2 as a list of floats# gets the slack of con1 and con2[0]In addition, for problems with only continuous variables, the two methods getDual and getRCost
return the list (or a portion thereof) of dual variables and reduced costs, respectively. Their usage issimilar to that for getSolution and getSlack.
Note that the inner workings of the Python interface obtain a copy of the whole solution, slack, dual, or
reduced cost vectors, even if only one element is requested. It is therefore advisable that instead ofrepeated calls (for instance, in a loop) to getSolution, getSlack, etc. only one call is made and theresult is stored in a list to be consulted in the loop. Hence, in the following example:
import xpress as xp
n = 10000
N = range(n)x = [xp.var() for i in N]
p = xp.problem()p.addVariable(x)m.addConstraint(xp.Sum(x[i] ⁎ i for i in N) <= n))m.setObjective(xp.Sum(x[i] for i in N)
m.solve()for i in N:
if m.getSolution(x[i]) > 1e-3:
print(i)the last three lines should be substituted as follows, as this will prevent repeatedly copying a large(10,000) list:
sol = m.getSolution()
for i in N:

Fair Isaac Corporation Conﬁdential and Proprietary Information17

Modeling an optimization problem
if sol[i] > 1e-3:
print(i)A very similar function of the class problem is evaluate, which allows for running all of the above
evaluation functions while passing, rather than the solution currently available for the problem, any listor any dictionary assigning a float to the variables used in the expressions.

2.15

Reading and writing a problem
After creating an empty problem, one can read a problem from a ﬁle via the read method, which only
takes the ﬁle name as its argument. An already-built problem can be written to a ﬁle with the write
method. Its arguments are similar to those in the Xpress Optimizer API function XPRSwriteprob, towhich we refer.
import xpress as xp
m = xp.problem()m.read("example2.lp")
m.solve()print(m.getSolution())
m2 = xp.problem()
v1 = xp.var()
v2 = xp.var(vartype=xp.integer)
m2.addVariable(v1, v2)
m2.addConstraint(v1 + v2 <= 4)m2.setObjective(v1⁎⁎2 + v2)
m2.write("twovarsproblem", "lp")2.16

Hints for building models efﬁciently
The Xpress Python interface allows for creating optimization models using methods described in thisand other sections. As happens with other interpreted languages, using explicit loops may result in aslow Python script. When using the Xpress Python interface, this can be noticeable in large
optimization models if multiple calls to addVariable, addConstraint, or addSOS are made. For
this reason, the Xpress module allows for generators and list, dictionaries, and sequences asarguments to these methods, to ensure faster execution.
Let us consider an example:
import xpress as xp
N = 100000
S = range(N)x = [xp.var()for i in S]
y = [xp.var(vartype=xp.binary) for i in S]
for i in S:
m.addVariable(x[i])m.addVariable(y[i])for i in S:
m.addConstraint(x[i] <= y[i])m.solve()

Fair Isaac Corporation Conﬁdential and Proprietary Information18

Modeling an optimization problem

While the declaration of x and y is correct and efﬁcient, the two subsequent loops are very inefﬁcient:
they imply 2N calls to addVariable and N calls to addConstraint. Both methods add someoverhead due to the conversion of Python object into data that can be read by the Optimizer, and thetotal overhead can be large.
Most methods of the Xpress Python interface allow for passing sequences (lists, dictionaries, NumPy
arrays, etc.) as parameters, and are automatically recognized as such. Hence the ﬁrst loop can be
replaced by two calls to addVariable:
m.addVariable(x)m.addVariable(y)or, more compact and slightly more efﬁcient:m.addVariable(x, y)

The largest gain in performance, though, comes from replacing the second loop with a single call to
addConstraint:m.addConstraint(x[i] <= y[i] for i in S)

This line is equivalent to the second loop above, and it is much faster and more elegant.
When declaring x and y as NumPy vectors, an equally efﬁcient and even more compact model can be
written:import xpress as xp
import numpy as np
N = 100000
S = range(N)x = np.array([xp.var()for i in S], dtype=xp.npvar)
y = np.array([xp.var(vartype=xp.binary) for i in S], dtype=xp.npvar)
m.addVariable(x, y)m.addConstraint(x <= y)m.solve()

See Chapter 3 for more information on how to use NumPy arrays in the Xpress Python interface.

2.17

Exceptions
The Xpress Python interface raises its own exceptions in the event of a modeling, interface, or solver
issue. There are three types of exceptions:xpress.ModelError: it is raised in case of an issue in modelling a problem, for instance if anincorrect constraint sign is given or if a problem is amended an object that is neither a variable, aconstraint, or a SOS;
xpress.InterfaceError: raised when the issue can be ascribed to the API and the way it isused, for instance when not passing mandatory arguments or specifying incorrect ones in an API
function;
xpress.SolverError: raised when the Xpress Optimizer or Xpress-SLP returns an error that isgiven by the solver even though the model was speciﬁed correctly and the interface functions
were used correctly.

Fair Isaac Corporation Conﬁdential and Proprietary Information

19

Modeling an optimization problem

As always with Python, one can use the try/except construct in order to analyze the raised exception
as in the following example
import xpress as xp
p = xp.problem()x = getVariable() # assume getVariable is defined elsewheretry:p.addVariable(x)except xp.ModelError as e:
print ("Modeling error:", repr(e))

Fair Isaac Corporation Conﬁdential and Proprietary Information

20

CHAPTER 3

Using Python numerical libraries
The NumPy library allows for creating and using arrays of any order and size for efﬁciency andcompactness purposes. This chapter shows how to take advantage of the features of NumPy in thecreation of optimization problems. The Xpress Python interface works with NumPy versions 1.8 andabove.

3.1

Using NumPy in the Xpress Python interface
NumPy arrays can be used as usual when creating variables, functions (linear and quadratic) ofvariables, and constraints. All functions described in this manual that take lists or tuples as arguments
can take array’s, i.e., NumPy array objects, as well, as in the following example:
import numpy as np
import xpress as xp
N = 20S = range(N)x = np.array([xp.var()for i in S], dtype=xp.npvar)
y = np.array([xp.var(vartype=xp.binary) for i in S], dtype=xp.npvar)
constr1 = x <= yp = xp.problem()p.addVariable(x, y)p.addConstraint(constr1)

The above script imports both NumPy and the Xpress Python interface, then declares two arrays ofvariables and creates the set of constraints xi ≤ yi for all i in the set S.
The NumPy arrays must have the attribute dtype equal to xpress.npvar (abbreviated to xp.npvarhere) in order to use the matricial/vectorial form of the comparison (<=, =, >=), arithmetic (+, -, ⁎, /,⁎⁎), and logic (&, |) operators.
NumPy allows for multiarrays with one or more 0-based indices. Given that declaring a NumPy
multiarray of variables can result in a long line of code, the xpress.vars function in its simplest
usage returns a NumPy array of variables with one or more indices. Consider the following three arraydeclarations:
import numpy as np
import xpress as xp
x = np.array([xp.var(name='v({0})'.format(i)) for i in range(20)], dtype=xp.npvar).reshape(5,4)
y = np.array([xp.var(vartype=xp.binary) for i in range(27)], dtype=xp.npvar).reshape(3,3,3)z = np.array([xp.var(lb=-1, ub=1) for i in range(1000)], dtype=xp.npvar)

These can be written equivalently in the compact form asimport numpy as np
import xpress as xp

Fair Isaac Corporation Conﬁdential and Proprietary Information

21

Using Python numerical libraries
x = xp.vars(5, 4, name='v')
y = xp.vars(3, 3, 3, vartype=xp.binary)z = xp.vars(1000, lb=-1, ub=1)

The only side effect is that the assigned names change. In order to preserve the naming convention of
the Xpress library, one can specify the parameter setting name=’’ in the call to xp.vars. This also
makes the creation of large arrays of variables much faster. We use this shorter notation in theremainder of this chapter.
The main advantage of using NumPy operations is the ability to replicate them on each element of anarray, taking into account all broadcasting features. For example, the following script “broadcasts” theright-hand side 1 to all elements of the array, thus creating the set of constraints xi + yi ≤ 1 for all i in theset S.
constr2 = x + y <= 1

All these operations can be carried out on arrays of any number of dimensions, and can be aggregatedat any level. The following example shows two three-dimensional array of variables involved in two
systems of constraints: the ﬁrst has two variables per each of the 200 constraints, while the second
has 10 constraints and 20 variables in each constraint.
z = xp.vars(4, 5, 10)t = xp.vars(4, 5, 10, vartype=xp.binary)p.addVariable(z,t)
p.addConstraint(z⁎⁎2 <= 1 + t)
p.addConstraint(xp.Sum(z[i, j, k] for i in range(4) for j in range(5)) <= 4for k in range(10))

Finally, a note on sums of multi-dimensional NumPy arrays: in keeping with the way NumPy arrays arehandled, the sum of a bi-dimensional array results in a one-dimensional array with the xpress.Sum
operator. The result of such a sum is exempliﬁed by the following code:>>> a = np.array([[1, 2, 3], [4, 5, 6]])>>> aarray([[1, 2, 3],[4, 5, 6]])>>> sum(a)array([5, 7, 9])

For the casual NumPy user, sufﬁce it to say that the sum is done on the ﬁrst dimension. Similarly, whencreating a NumPy array of dimensions k of expressions, xpress.Sum returns a (k – 1)-array resulting
from the sum across the ﬁrst dimension.
It is important to note the following: NumPy does not use the __iadd__ operator when computing
these sums, but rather the __add__ operator. For reasons discussed above and in the entry regarding
the xpress.Sum operator, this can have a huge impact on performance. Consider the following
example:m,n = 1000,10
a = np.random.random((m,n))x = xp.vars(m, n)sum_0d = xp.Sum(xp.Sum(a⁎x))
sum_1d = xp.Sum(a⁎x)

The above example has a poor performance, and it is advised to avoid using xpress.Sum as such on amulti-dimensional array. If a scalar sum of all elements of the array is sought, such as sum(sum(a))
for the numerical array above, we strongly advise to ﬂatten the array ﬁrst, and run instead
xpress.Sum(b.flatten()) if b is a multiarray of expressions. The multiarray has dtype equal toxpress.npexpr in order to be used for array operations. If only one pass is required, then it is betterto explicitly create a vector whose elements are deﬁned with a call to xpress.Sum:

Fair Isaac Corporation Conﬁdential and Proprietary Information

22

Using Python numerical libraries
prod = a⁎xsum_0d = xp.Sum(prod.flatten())
sum_1d = np.array([xp.Sum(prod[i,j] for i in range(m)) for i in range(n)], dtype=xp.npexpr)

3.2

Products of NumPy arrays
The dot product is a useful operator for carrying out aggregate operations on vectors, matrices, andtensors. The dot operator in NumPy allows for reducing, along one axis of a multi-dimensional arrays,
data such as ﬂoating points or integer values.
The application of the dot product of NumPy of two multi-dimensional arrays of dimensions (i1 , i2 , ..., ik0 )and (j1 , j2 , ..., jk00 ), respectively, requires that ik0 = jk00 –1 , i.e., the size of the last dimension of the ﬁrst arraymust match the size of the penultimate dimension of the second vector. For instance, the following dot
product is valid:
import numpy as np
a = np.random.random((4,6))
b = np.random.random((6,2))
c = np.dot(a,b)

and the result is a 4x2 matrix. The Xpress Python interface has its own dot product operator, which canbe used for all similar operations on variables and expression. The rules for applying the Xpress dot
operator are the same as for the native Python dot product, with one extra feature: there is no limit on
the number of arguments, hence the following example is correct as per the restrictions on thedimensions, albeit it yields a nonconvex constraint.
coeff_pre = np.random.random((6,3,7))x = xp.vars(4, 7, 5)
y = xp.vars(2, 5, 8)
coeff_post = np.random.random((6, 8, 7))
p.addConstraint(xp.Dot(coeff_pre, x, y, coeff_post) >= 0)

Similar to the NumPy dot product, the Xpress dot product has an out parameter for deﬁning the output
in which to store the product.
The following script deﬁnes two constraints: the ﬁrst restricts the squared norm ||z|| = z · z of the vector
z of variables to be at most one. It does so by applying the dot operator on the vector itself. The second
constraint (t – z)0 Q(t – z) ≤ 1 restricts the quadratic form on the left-hand side to be at most 1.
p.addConstraint(xp.Dot(z, z) <= 1) # restrict norm of z to 1
Q = np.random.random(N, N)# create a random 20x20 matrix
p.addConstraint(xp.Dot((t-z), Q, (t-z)) <= 1)

As for the Sum operator, when handling variables or expressions, it is advised to use the Dot operator in
the Xpress module rather than the native Python operator, for reasons of efﬁciency.

Fair Isaac Corporation Conﬁdential and Proprietary Information

23

CHAPTER 4

Controls and Attributes
A control is a parameter that can inﬂuence the performance and behavior of the Xpress Optimizer. For
example, the MIP gap, the feasibility tolerance, or the type of root LP algorithms are controls that canbe set. Controls can both be read from and written to an optimization problem.
An attribute is a feature of an optimization problem, such as the number of rows and columns or thenumber of quadratic elements of the objective function. They are read-only parameters in that they can
only be modiﬁed, for example, by functions for adding constraints or variables, or functions for setting
and modifying the objective function.
Both controls and attributes are of three types: integer, ﬂoating point, or string. The Xpress Pythoninterface allows for setting and retrieving the value of all controls of an optimization problem, as well as
getting the value of all of a problem’s attributes.
This reference manual does not describe the meaning of controls and attributes in the Xpress
Optimizer; for a detailed description of each, please refer to the Optimizer’s reference manual.
Following Python’s philosophy, one can set and obtain multiple controls/attributes with one function
call. In other words, one can set either (i) a single control and its value; or (ii) a Python dictionary
coupling a list of control names and their respective value. Similarly, with one function call one canobtain (i) the value of a single attribute or control by specifying it as a parameter; or (ii) a dictionary
associating names to values for each of a list of controls or attributes given as an argument. See theexamples below for more information.

4.1

Controls
Use problem.setControl to set the value of one or more controls. Its synopsis is as follows:
setControl(ctrl, value)
setControl({ctrl1: value1, ctrl2: value2, ..., ctrlk: valuek})

The ﬁrst form is for setting the value of the control ctrl to value. The second form is for setting
ctrl1 to value1, ctrl2 to value2, ..., and ctrlk to valuek.
A list of all controls can be found on the Xpress Optimizer’s reference manual. The control parameters
to be passed in setControl are lower-case strings:
p.setControl('miprelstop', 1e-9)
p.setControl({'miprelstop': 1e-3, 'feastol': 1e-6})

Use the method getControl to retrieve the value of one or more controls. Its synopsis is one of thefollowing:
getControl(ctrl)

Fair Isaac Corporation Conﬁdential and Proprietary Information

24

Controls and Attributes
getControl([ctrl1, ctrl2, ..., ctrlk])
getControl(ctrl1, ctrl2, ..., ctrlk)
getControl()The ﬁrst form is for obtaining the value of the control ctrl. The output will be the value of the control.
The second and third forms are for retrieving ctrl1 , ctrl2 , ..., and ctrlk. Whether the controls are
declared in a list or a tuple does not matter. The result will be a dictionary coupling each control with its
value. The last form is to obtain all controls; the result is a dictionary coupling all controls with theirrespective value.
The control parameters to be passed in getControl are lower-case strings. For a problem p the callwill be as follows:
mrs = p.getControl('miprelstop')
someattr = p.getControl('miprelstop', 'feastol')

4.2

Examplesimport xpress as xp
p = xp.problem()p.setControl({'miprelstop': 1e-5, 'feastol': 1e-4})
p.setControl('miprelstop', 1e-5)
print(p.getControl('miprelstop') )print(p.getControl('maxtime', 'feastol'))# print the current value of miprelstop# print a dictionary with the current# value of miprelstop and feastol
print(p.getControl(['presolve', 'miplog'])) # Same output
print(p.getControl())# print a dictionary with ALL control# Initialize a dictionary with two controls and their value. Then
# change their value conditionally and set their new (possibly# changed) value.
myctrl = p.getControl(['miprelstop', 'feastol'])if (myctrl['miprelstop'] <= 1e-4):
myctrl['miprelstop'] = 1e-3
myctrl['feastol']= 1e-3else:
myctrl['feastol']= 1e-4p.setControl(myctrl)

4.3

Attributes
Use the method getAttrib to retrieve the value of one or more controls. Its synopsis is one of thefollowing:
getAttrib(attr)
getAttrib([attr1, attr2, ..., attrk])
getAttrib(attr1, attr2, ..., attrk)
getAttrib()

The ﬁrst form is for obtaining the value of the attribute attr. The output will be the value of theattribute. The second and third forms are for retrieving attr1 , attr2 , ..., and attrk. Whether theattributes are declared in a list or a tuple does not matter. The result will be a dictionary coupling each
attribute with its value. The last form is to obtain all attributes; the result is a dictionary coupling all
attributes with their respective value.

Fair Isaac Corporation Conﬁdential and Proprietary Information

25

Controls and Attributes

A list of all attributes can be found on the Xpress Optimizer’s reference manual. As for controls, theattribute parameters to be passed in getAttrib are lower-case strings. For a problem p the call will
be as follows:
nrows = p.getAttrib('rows')
problemsize = p.getAttrib('rows', 'cols')

4.4

Examplesimport xpress as xp
p = xp.problem()p.read("example.lp")
print("The problem has",p.getAttrib('rows'), "rows and",p.getAttrib('cols'), "columns")# Obtain dictionary with two entries: the number of rows and# columns of the problem readprint(p.getAttrib(['rows', 'cols']))# produce a Python dictionary with all attributes of problem m, and# hence of LP file example.lp
attributes = p.getAttrib()

4.5

Accessing controls and attributes as object members
An alternative, more "prompt-friendly" way to get controls and attributes is through their direct accessin a problem or, in the case of controls, the Xpress module itself.
The Xpress module has an object, called controls, containing all controls of the Optimizer. Upon
importing the Xpress module, these controls are initialized at their default value. The user can obtain
their value at any point and can also set their value; this new value will be inherited by all problems
created after the modiﬁcation. They can be read and written as follows:
xpress.controls.<controlname>xpress.controls.<controlname> = <new value>

For example, the object xpress.controls.miprelstop contains the value of the control
miprelstop. Controls can be read (and, for example, printed) and set as follows:
import xpress as xp
print(xp.controls.heurstrategy)
xp.controls.feastol = 1e-4 # Set new default to 1e-4

These "global" controls are maintained throughout while the Xpress module is loaded. Note that thecontrols object of the Xpress module does not refer to any speciﬁc problem. All controls havedefault values that are determined by the Optimizer’s library, except for the control xslp_postsolvethat is set to 1, as opposed to its default value of 0 in the Xpress Optimizer’s library.
In addition, every problem has a controls object that stores the controls related to the problem itself.
This is the object the functions getControl and setControl refer to. Similar to the Xpress module’s
controls object, all members of a problem’s object can be read and written. For a problem p, thefollowing shows how to read and write a problem’s control:

Fair Isaac Corporation Conﬁdential and Proprietary Information

26

Controls and Attributes
p.controls.<controlname>p.controls.<controlname> = <new value>

A problem’s controls are independent of the global controls object of the Xpress module. However,when a new problem is created its controls are copied from the current values in the global object. Notethat after creating a new problem, changing the members in xpress.controls does not affect the
problem’s controls. The following examples should clarify this:import xpress as xp# create a new problem whose MIPRELSTOP is ten times smaller# than the default value
p1 = xp.problem("problem1")
p1.controls.miprelstop = 0.1 ⁎ xp.controls.miprelstop
p1.controls.feastol = 1e-5
p1.read("example1.lp")
xp.controls.miprelstop = 1e-8 # Set new default# The new problem will have a MIPRELSTOP of 1e-8
p2 = xp.problem("problem2")
p2.read("example2.lp")# The next problem has a less restrictive feasibility tolerance# (i.e. 1e-6) than problem 2
p2v = xp.problem("problem2 variant")
p2v.read("example2.lp")
p2v.controls.feastol = 100 ⁎ p2.controls.feastol
p1.solve()
p2.solve()# solve "example2.lp" with a less restrictive# feasibility tolerance
p2v.solve()

Attributes can be handled similar as above through a member of the class problem, called
attributes, with two exceptions: ﬁrst, there is no "global" attribute object, as a set of attributes only
makes sense when associated with a problem; second, an attribute cannot be set.
Once a problem p has been created (or read from a ﬁle), its attributes are available asp.attribute.attribute_name. The example in the previous section can be modiﬁed as follows:
import xpress as xp
p = xp.problem()p.read("example.lp")
print("The problem has",p.attributes.rows, "rows and",p.attributes.cols, "columns")

When using the Python prompt in creating problems with the Xpress module, the name of controls andattributes can be auto-completed by pressing TAB (note: this only works in Python 3.4 and subsequentversions). For instance,>>> import xpress>>> p = xp.problem()>>> p.read("example.lp")>>> p.attributes.n<TAB>
p.attributes.namelength p.attributes.nodedepth>>> p.attributes.nodedepth0Fair Isaac Corporation Conﬁdential and Proprietary Information

p.attributes.nodes

p.attributes.numiis

27

Controls and Attributes>>> p.attributes.ma<TAB>
p.attributes.matrixname
p.attributes.maxabsprimalinfeas
p.attributes.maxreldualinfeas>>> p.attributes.matrixname'noname'>>> xp.controls.o<TAB>
xp.controls.oldnames
xp.controls.optimalitytol
xp.controls.outputlog
xp.controls.outputtol>>> xp.controls.omniformat
0Fair Isaac Corporation Conﬁdential and Proprietary Information

p.attributes.maxabsdualinfeas
p.attributes.maxprobnamelength
p.attributes.maxrelprimalinfeas

xp.controls.omniformat
xp.controls.optimalitytoltarget
xp.controls.outputmask

28

CHAPTER 5

Using Callbacks
This chapter shows how to deﬁne and use callback functions from the Xpress Python interface. The
design of this part of the interface reﬂects as closely as possible the design of the callback functions
deﬁned in the C API of the Xpress Optimizer.

5.1

Introduction
Callback functions are a useful tool for adapting the Xpress Optimizer to the solution of various classes
of problems, in particular Mixed Integer Programming (MIP) problems, with linear or nonlinear
constraints. Their main purpose is to provide the user with a point of entry into the branch-and-bound,which is the workhorse algorithm for MIPs.
Using callback functions is simple: the user ﬁrst deﬁnes a function (say myfunction) that is to be run
every time the branch-and-bound reaches a well-speciﬁed point; second, the user calls a function (suchas addcbpreintsol) with myfunction as its argument. Finally, the user runs the solve commandthat launches the branch-and-bound, the simplex solver, or the barrier solver; it is while these are runthat myfunction is called.
A callback function, hence, is passed once as an argument and used possibly many times. It is called
while a solver is running, and it is passed the following:a problem object, of the same class as an object declared with p = xpress.problem();a data object.

The data object is user-deﬁned and is given to the problem when adding the callback function. It can beused to store information that the user can read and/or modify within the callback. For instance, thefollowing code shows how to add a callback function, preintsolcb, that is called every time a new
integer solution is found.
import xpress as xp
class foo:
"Simple class"bar = 0def __init__(self):
self.bar = 1
def update(self):
self.bar += 1
def preintsolcb(prob, data, isheuristic, cutoff):"""
Callback to be used when an integer solution is found. The"data" parameter is of class foo"""

Fair Isaac Corporation Conﬁdential and Proprietary Information

29

Using Callbacks

p = xp.problem()p.read('myprob.lp')# reads in a problem, let's say a MIP

baz = foo()p.addcbpreintsol(preintsolcb, baz, 3)p.solve()

While the function argument is necessary for all addcb⁎ functions, the data object can be speciﬁed as
None. In that case, the callback will be run with None as its data argument. The call also speciﬁes apriority with which the callback should be called: the larger the (positive) priority, the more urgently it iscalled.
Any call to an addcb⁎ function, as the names imply, only adds a function to a list of callback functions
for that speciﬁc point of the BB algorithm. For instance, two calls to addcbpreintsol with twofunctions preint1 and preint2, respectively with priority 3 and 5, puts the two functions in a list. The
two functions will be called (preint2 ﬁrst) whenever the BB algorithm ﬁnds an integer solution.
In order to remove a callback function that was added with addcb⁎, a corresponding removecb⁎
function is provided, for instance removecbpreintsol. This function takes two arguments, i.e., thecallback function and the data object, and deletes all elements of the list of callbacks that were addedwith the corresponding addcb function that match the function and the data.
The None keyword acts as a wildcard that matches any function/data object: if removecb⁎ is calledwith None as the function, then all callbacks matching the data will be deleted. If the data is also None,
all callback functions of that type are deleted; this can be obtained by passing no argument toremovecb⁎.
The arguments and return value of the callback functions reﬂect those in the C API, and this holds forparameter names as well. As for the other API functions of the Python interface, there are a few
exceptions:

If a function in the C API requires a parameter n to indicate the size of an array argument to follow,
n is not required in the corresponding Python function;
If a function in the C API uses passing by reference as a means to allow for modifying a value andreturning it as an output, the Python counterpart will have this as the return value of the function.
Where multiple output values are comprised in the list of parameters, the return value is a tuplecomposed of the returned values. Elements of this tuple can be None if no change was made tothat output value.

Most callback functions refer to a problem, therefore the addcb⁎ method is called from a problem
object. The only exception is the function xpress.addcbmsghandler(), which is called on the
Xpress module itself and allows for providing a function that is called every time any output isproduced within the Optimizer.
We refer to the Reference chapter of this manual for all information regarding callback functions andhow to add/remove them from a problem.

Fair Isaac Corporation Conﬁdential and Proprietary Information30

CHAPTER 6

Examples of use
This chapter discusses some example Python scripts that are part of the Xpress Optimizer’s Pythoninterface. Most of them are well commented so the user can refer directly to the source for guidance.
Most of these scripts have an initial part in common, which we reproduce here but omit in all
explanations below for compactness. These initial lines import the Xpress module itself and the
NumPy module, which is used in some of the examples. The ﬁrst line is to make the print statements,
which are in Python 3 style here, work in Python 2.7 as well.
from __future__ import print_function
import xpress as xp
import numpy as np

6.1

Creating simple problems
Below are a few examples on how to create simple LP, MIP, MIQP, and similar problems. Note that they
make use of API functions that resemble the C API functions for creating problems, and are usedsimilarly here.

6.1.1

Generating a small Linear Programming problem
In this example, we create a problem and load a matrix of coefﬁcients, a rhs, and an objective
coefﬁcient list with the loadproblem function. We also assign names to both rows and columns (bothare optional). These data correspond to the following problem with three variables and four constraints:
minimize:

3 x1 + 4 x2 + 5 x3

subject to:x1 + x3≥-2.4

2x1 + 3x3≥

-3

2x2 + 3x3=

4x2 + x3≤

5-1 ≤ x1 ≤ 3-1 ≤ x1 ≤ 5-1 ≤ x1 ≤ 8
p = xp.problem()p.loadproblem("",# probname['G','G','E', 'L'], # qrtypes[-2.4, -3, 4, 5],
# rhs
None,
# range[3,4,5],# obj

Fair Isaac Corporation Conﬁdential and Proprietary Information

31

Examples of use[0,2,4,8],# mstartNone,# mnel[0,1,2,3,0,1,2,3], # mrwind[1,2,2,1,1,3,3,1], # dmatval[-1,-1,-1],# lb[3,5,8],# ub
colnames = ['X1','X2','X3'],# column names
rownames = ['row1','row2','row3','constr_04']) # row
names
p.write("loadlp", "lp")p.solve()

We then create another variable and add it to the problem, then modify the objective function. Note thatthe objective function is replaced by, not amended with, the new expression. After solving the problem,
it saves it into a ﬁle called update.lp.
x = xp.var()p.addVariable(x)p.setObjective(x⁎⁎2 + 2⁎x + 444)
p.solve()p.write("updated", "lp")

6.1.2

A Mixed Integer Linear Programming problem
This example uses loadproblem to create a Mixed Integer Quadratically Constrained Quadratic
Programming problem with two Special Ordered Sets. Note that data that is not needed is simply set as
None.
The Examples directory provides similar examples for different types of problems.
p = xp.problem()p.loadproblem("",# probname['G','G','L', 'L'], # qrtypes[-2.4, -3, 4, 5],
# rhs
None,
# range[3,4,5],# obj[0,2,4,8],# mstartNone,# mnel[0,1,2,3,0,1,2,3], # mrwind[1,1,1,1,1,1,1,1], # dmatval[-1,-1,-1],# lb[3,5,8],# ub[0,0,0,1,1,2],# mqobj1[0,1,2,1,2,2],# mqobj1[2,1,1,2,1,2],# dqe[2,3],# qcrows[2,3],# qcnquads[1,2,0,0,2],# qcmqcol1[1,2,0,2,2],# qcmqcol2[3,4,1,1,1],# qcdqval['I','S'],# qgtype[0,1],# mgcols[0,2],# dlim['1','1'],# qstype[0,2,4],# msstart[0,1,0,2],# mscols[1.1,1.2,1.3,1.4]) # dref
p.solve()

Fair Isaac Corporation Conﬁdential and Proprietary Information

32

Examples of use

6.2

Modeling examples

6.2.1

A simple modelThis example demonstrates how variables and constraints, or lists/arrays thereof, can be added into a
problem. The script then prints the solution and all attributes/controls of the problem.
N = 4
S = range(N)v = [xp.var(name="y{0}".format(i)) for i in S] # set name of a variable asm = xp.problem()
v1 = xp.var(name="v1", lb=0, ub=10, threshold=5, vartype=xp.continuous)
v2 = xp.var(name="v2", lb=1, ub=7, threshold=3, vartype=xp.continuous)
vb = xp.var(name="vb",vartype=xp.binary)# Create a variable with name yi, where i is an index in S
v = [xp.var(name="y{0}".format(i), lb=0, ub=2⁎N) for i in S]

The call below adds both v, a vector (list) of variables, and v1 and v2, two scalar variables.
m.addVariable(vb, v, v1, v2)
c1 = v1 + v2 >= 5
m.addConstraint(c1, # Adds a list of constraints: three single constraints...
2⁎v1 + 3⁎v2 >= 5,v[0] + v[2] >= 1,# ... and a set of constraints indexed by all {i in# S: i<N-1}(recall that ranges in Python are from 0# to n-1)(v[i+1] >= v[i] + 1 for i in S if i < N-1))# objective overwritten at each setObjective()m.setObjective(xp.Sum([i⁎v[i] for i in S]), sense=xp.minimize)m.solve()print("status: ", m.getProbStatus())
print("string: ", m.getProbStatusString())
print("solution:", m.getSolution())

6.2.2

Using IIS to investigate an infeasible problem
The problem modeled below is infeasible,
import xpress as xp
x0 = xp.var()
x1 = xp.var()x2 = xp.var(vartype=xp.binary)c1 =x0 + 2 ⁎ x1 >= 1
c2 = 2 ⁎ x0 +x1 >= 1c3 =x0 +x1 <= .5
c4 = 2 ⁎ x0 + 3 ⁎ x1 >= 0.1

The three constraints c1, c2, and c3 above are incompatible as can be easily veriﬁed. Adding all ofthem to a problem will make it infeasible. We use the functions to retrieve the Irreducible Infeasible
Subsystems (IIS).

Fair Isaac Corporation Conﬁdential and Proprietary Information

33

Examples of use
minf = xp.problem("ex-infeas")minf.addVariable(x0,x1,x2)
minf.addConstraint(c1,c2,c3,c4)
minf.solve()
minf.iisall()print("there are ", minf.attributes.numiis, " iis's")
miisrow = []miiscol = []constrainttype = []colbndtype = []duals = []rdcs = []isolationrows = []isolationcols = []# get data for the first IIS
minf.getiisdata(1, miisrow, miiscol, constrainttype, colbndtype,
duals, rdcs, isolationrows, isolationcols)
print("iis data:", miisrow, miiscol, constrainttype, colbndtype,
duals, rdcs, isolationrows, isolationcols)# Another way to check IIS isolations
print("iis isolations:", minf.iisisolations(1))
rowsizes = []colsizes = []suminfeas = []numinfeas = []print("iisstatus:", minf.iisstatus(rowsizes, colsizes, suminfeas, numinfeas))
print("vectors:", rowsizes, colsizes, suminfeas, numinfeas)

6.2.3

Modeling a problem using Python lists and vectors
We create a convex QCQP problem. We use a list of N=5 variables and sets constraints and objective.
We deﬁne all constraints and the objective function using a Python aggregate type.
import xpress as xp
N = 5
S = range(N)v = [xp.var(name="y{0}".format(i)) for i in S]
m = xp.problem("problem 1")
print("variable:", v)
m.addVariable(v)m.addConstraint(v[i] + v[j] >= 1 for i in range(N-4) for j in range(i,i+4))m.addConstraint(xp.Sum([v[i]⁎⁎2 for i in range(N-1)]) <= N⁎⁎2 ⁎ v[N-1]⁎⁎2)
m.setObjective(xp.Sum([i⁎v[i] for i in S]) ⁎ (xp.Sum([i⁎v[i] for i in S])))m.solve()print("solution: ", m.getSolution())

6.2.4

A knapsack problem
Here follows an example of a knapsack problem formulated using lists of numbers. All data in the

Fair Isaac Corporation Conﬁdential and Proprietary Information

34

Examples of use

problem are lists, and so are the variables.
import xpress as xp
S = range(5)# that's the set {0,1,2,3,4}
value = [102, 512, 218, 332, 41] # or just read them from fileweight = [ 21, 98, 44, 59, 9]
x = [xp.var(vartype=xp.binary) for i in S]
profit = xp.Sum(value[i] ⁎ x[i] for i in S)
p = xp.problem("knapsack")
p.addVariable(x)p.addConstraint(xp.Sum(weight[i] ⁎ x[i] for i in S) <= 130)p.setObjective(profit, sense=xp.maximize)p.solve()

Note that the same result could have been achieved using NumPy arrays and the Xpress module’s dot
product as follows:
value = np.array([102, 512, 218, 332, 41])weight = np.array([ 21, 98, 44, 59, 9])x = np.array([xp.var(vartype=xp.binary) for i in S], dtype=xp.npvar)
profit = xp.Dot(value, x)
p = xp.problem("knapsack")
p.addVariable(x)p.addConstraint(xp.Dot(weight, x) <= 130)p.setObjective(profit, sense=xp.maximize)p.solve()

6.2.5

A Min-cost-ﬂow problem using NumPy
This example solves a min-cost-ﬂow problem using NumPy and the incidence matrix of the graph. It
uses the networkx package, which might have to be installed using, for example, pip.
import networkx as netx
import xpress as xp# digraph definition
V = [1,2,3,4,5]# vertices
E = [[1,2], [1,4], [2,3], [3,4], [4,5], [5,1]] # arcs
n = len(V) # number of nodes
m = len(E) # number of arcs
G = netx.DiGraph(E)# Get NumPy representation
A = (netx.incidence_matrix(G, oriented=True).toarray())

We use NumPy vectors and the Xpress interface’s dot product, the xpress.Dot operator. Note that
although NumPy has a dot operator, especially for large models it is strongly advised to use the Xpress
interface’s Dot function for reasons of efﬁciency.
demand = np.array([3, -5, 7, -2, -3])
cost = np.array([23, 62, 90, 5, 6, 8])
flow = np.array([xp.var() for i in E], dtype=xp.npvar)# flow variables declared on arcs

p = xp.problem('network flow')

Fair Isaac Corporation Conﬁdential and Proprietary Information

35

Examples of use

p.addVariable(flow)
p.addConstraint(xp.Dot(A, flow) == - demand)
p.setObjective(xp.Dot(cost, flow))p.solve()for i in range(m):print('flow on', E[i], ':', p.getSolution(flow[i]))6.2.6

A nonlinear model
Let’s solve a classical nonlinear problem: ﬁnding the minimum of the Rosenbrock function. For
parameters a and b, minimize (a – x)2 + b(y – x2 )2 .
import xpress as xp
a,b = 1,100x = xp.var(lb=-xp.infinity)y = xp.var(lb=-xp.infinity)p = xp.problem()p.addVariable(x,y)
p.setObjective((a-x)⁎⁎2 + b⁎(y-x⁎⁎2)⁎⁎2)p.controls.xslp_solver = 0 # solve it with SLP, not Knitro
p.solve()print("status: ", p.getProbStatus())
print("string: ", p.getProbStatusString())
print("solution:", p.getSolution())

6.2.7

Finding the maximum-area n-gon
The problem asks, given n, to ﬁnd the n-sided polygon of largest area inscribed in the unit circle.
While it is natural to prove that all vertices of a global optimum reside on the unit circle, the problem isformulated so that every vertex i is at distance rhoi from the center, and at angle thetai . We would
expect that the local optimum found has all rho’s are equal to 1. The example ﬁle contains instructions
for drawing the resulting polygon using matplotlib.
The objective function is the total area of the polygon. Considering the segment S[i] joining the center
to the i-th vertex and A(i,j) the area of the triangle deﬁned by the two segments S[i] and S[j], theobjective function is A(0,1) + A(1,2) + ... + A(N–1,0) , where A(i,j) = 1/2 ∗ rhoi ∗ rhoj ∗ sin(thetai – thetaj ). We
ﬁrst deﬁne the set Vertices as the set of integers from 0 to n – 1.
rho = [xp.var(lb=1e-5,
ub=1.0)for i in Vertices]
theta = [xp.var(lb=-math.pi, ub=math.pi) for i in Vertices]p = xp.problem()p.addVariable(rho, theta)
p.setObjective(
0.5⁎(xp.Sum(rho[i]⁎rho[i-1]⁎xp.sin(theta[i]-theta[i-1]) for i in Vertices if i != 0)+
rho[0]⁎rho[N-1]⁎xp.sin(theta[0]-theta[N-1])), sense=xp.maximize)

We establish that the angles must be increasing in order to obtain a sensible solution:

Fair Isaac Corporation Conﬁdential and Proprietary Information

36

Examples of use
p.addConstraint(theta[i] >= theta[i-1] + 1e-4 for i in Vertices if i != 0)

Note also that we enforce that the angles be different as otherwise they might form a local optimum
where all of them are equal.

6.2.8

Solving the n-queens problem
In chess, the queen can move in all directions (even diagonally) and travel any distance. The problem of
the n queens consists in placing n queens on an n × n chessboard so that none of them can be eaten in
one move.
We ﬁrst create a dictionary of variables, mapping each cell of the chessboard to one variable so that we
can refer to it later. All variables are clearly binary as they indicate whether a given cell has a queen ornot.
n = 10 # the size of the chessboard
N = range(n)x = {(i,j): xp.var(vartype=xp.binary, name='q{0}_{1}'.format(i,j))
for i in N for j in N}
vertical= [xp.Sum(x[i,j] for i in N) <= 1 for j in N]
horizontal = [xp.Sum(x[i,j] for j in N) <= 1 for i in N]
diagonal1
diagonal2= [xp.Sum(x[k-j,j] for j in range(max(0,k-n+1), min(k+1,n))) <= 1for k in range(1,2⁎n-2)]= [xp.Sum(x[k+j,j] for j in range(max(0,-k),min(n-k,n))) <= 1for k in range(2-n,n-1)]

p = xp.problem()p.addVariable(x)p.addConstraint(vertical, horizontal, diagonal1, diagonal2)# Objective, to be maximized: number of queens on the chessboard
p.setObjective(xp.Sum(x), sense=xp.maximize)p.solve()

As a rudimentary form of visualization, we print the solution on the chessboard with different symbols
for variables at one or zero.
for i in N:
for j in N:
if p.getSolution(x[i,j]) == 1:
print('@', sep='', end='')else:
print('.', sep='', end='')print('')

6.2.9

Solving Sudoku problems
The well-known Sudoku puzzles ask one to place numbers from 1 to 9 into a 9 × 9 grid such that nonumber repeats in any row, in any column, and in any 3x3 sub-grid. For a more general version of thegame, replace 3 with q and 9 with q2 .
We model this problem as an assignment problem where certain conditions must be met for all
numbers in the columns, rows, and sub-grids.
These subgrids are lists of tuples with the coordinates of each subgrid. In a 9 × 9 sudoku, for instance,
subgrids[0,1] has the 9 elements in the middle top square.

Fair Isaac Corporation Conﬁdential and Proprietary Information

37

Examples of use

The input is a starting grid where the unknown numbers are replaced by zero. The example ﬁle contains
a relatively hard 9 × 9 sudoku, which we show below, and also a 16 × 16 variant of the same game.
q = 3
starting_grid = \[[8,0,0,0,0,0,0,0,0],[0,0,3,6,0,0,0,0,0],[0,7,0,0,9,0,2,0,0],[0,5,0,0,0,7,0,0,0],[0,0,0,0,4,5,7,0,0],[0,0,0,1,0,0,0,3,0],[0,0,1,0,0,0,0,6,8],[0,0,8,5,0,0,0,1,0],[0,9,0,0,0,0,4,0,0]]n = q⁎⁎2 # the size must be the square of the size of the subgrids
N = range(n)x = {(i,j,k): xp.var(vartype=xp.binary, name='x{0}_{1}_{2}'.format(i,j,k))
for i in N for j in N for k in N}# define all q^2 subgrids
subgrids = {(h,l): [(i,j) for i in range(q⁎h, q⁎h + q)
for j in range(q⁎l, q⁎l + q)]
for h in range(q) for l in range(q)}vertical= [xp.Sum(x[i,j,k] for i in N) == 1 for j in N for k in N]
horizontal = [xp.Sum(x[i,j,k] for j in N) == 1 for i in N for k in N]
subgrid= [xp.Sum(x[i,j,k] for (i,j) in subgrids[h,l]) == 1
for (h,l) in subgrids.keys() for k in N]# Assign exactly one number to each cell
assign = [xp.Sum(x[i,j,k] for k in N) == 1 for i in N for j in N]

Then we ﬁx those variables that are non-zero in the input grid. We don’t need an objective function as
this is a feasibility problem. After computing the solution, we print it to the screen.
init = [x[i,j,k] == 1 for k in N for i in N for j in N
if starting_grid[i][j] == k+1]
p = xp.problem()p.addVariable(x)p.addConstraint(vertical, horizontal, subgrid, assign, init)
p.solve()print('Solution:')for i in N:
for j in N:
l = [k for k in N if p.getSolution(x[i,j,k]) >= 0.5]
assert(len(l) == 1)
print('{0:2d}'.format(1 + l[0]), end='', sep='')print('')

6.3

Examples using NumPy

6.3.1

Using NumPy multidimensional arrays to create variables
Use NumPy arrays for creating a 3-dimensional array of variables, then use it to create a mode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

38

Examples of use
S1 = range(2)S2 = range(3)S3 = range(4)m = xp.problem()h = np.array([[[xp.var(vartype=xp.binary)
for i in S1]for j in S2]for k in S3], dtype=xp.npvar)
m.addVariable(h)m.setObjective (h[0][0][0] ⁎ h[0][0][0] +h[1][0][0] ⁎ h[0][0][0] +h[1][0][0] ⁎ h[1][0][0] +xp.Sum(h[i][j][k] for i in S3 for j in S2 for k in S1))
cons00 = - h[0][0][0] ⁎⁎ 2 +xp.Sum(i ⁎ j ⁎ k ⁎ h[i][j][k]for i in S3 for j in S2 for k in S1) >= 11
m.addConstraint(cons00)
m.solve()

The ﬁnal part of the code retrieves the matrix representation of the quadratic part of the only
constraint.
mstart1=[]
mclind1=[]
dqe1=[]
m.getqrowqmatrix(cons00, mstart1, mclind1, dqe1, 29, h[0][0][0], h[3][2][1])print("row 0:", mstart1, mclind1, dqe1)

6.3.2

Using the dot product to create arrays of expressions
Here we use NumPy arrays to print the product of a matrix by a random vector, and the xpress.Dot
function on a matrix and a vector. Note that the NumPy dot operator works perfectly ﬁne here, butshould be avoided for reasons of performance, especially when handling large arrays where at least
one contains optimization variables or expressions.
x = np.array([xp.var() for i in range(5)], dtype=xp.npvar)
p = xp.problem()p.addVariable(x)p.addConstraint(xp.Sum(x) >= 2)
p.setObjective(xp.Sum(x[i]⁎⁎2 for i in range(5)))
p.solve()A= np.array(range(30)).reshape(6,5) # A is a 6x5 matrix
sol = np.array(p.getSolution()) # a vector of size 5
columns = A⁎sol# not a matrix-vector product!
v = np.dot(A,sol)# an array: matrix-vector product A⁎sol
w = xp.Dot(A,x)# an array of expressions
print(v,w)

6.3.3

Using the Dot product to create constraints and quadratic functions
This is an example of a problem formulation that uses the xpress.Dot operator to formulate
constraints in a concise fashion. Note that the NumPy dot operator is not suitable here as the result is
an expression in the Xpress variables.

Fair Isaac Corporation Conﬁdential and Proprietary Information

39

Examples of use
A = np.random.random(30).reshape(6,5) # A is a 6x5 matrix
Q = np.random.random(25).reshape(5,5) # Q is a 5x5 matrix
x = np.array([xp.var() for i in range(5)], dtype=xp.npvar)
x0 = np.random.random(5) # random vector# vector of variables

Q += 4 ⁎ np.eye(5) # add 5 ⁎ the identity matrix
Lin_sys = xp.Dot(A,x)<= np.array([3,4,1,4,8,7])
Conv_c = xp.Dot(x,Q,x) <= 1

# 6 constraints (rows of A)# one quadratic constraint

p = xp.problem()p.addVariable(x)p.addConstraint(Lin_sys, Conv_c)p.setObjective(xp.Dot(x-x0, x-x0)) # minimize distance from x0
p.solve()

6.3.4

Using NumPy to create quadratic optimization problems
This example creates and solves a simple quadratic optimization problem. Given an n × n matrix Q anda point x0 , minimize the quadratic function xT (Q + n3 I)x subject to the linear system (x – x0 )T Q + e = 0,
where e is the vector of all ones, the inequalities Qx ≥ 0, and nonnegativity on all variables. Reportsolution if available.
n = 10Q = np.arange(1, n⁎⁎2 + 1).reshape(n, n)
x = np.array([xp.var() for i in range(n)], dtype=xp.npvar)
x0 = np.random.random(n)p = xp.problem()p.addVariable(x)c1 = xp.Dot((x - x0), Q) + 1 == 0
c2 = xp.Dot(Q, x) >= 0
p.addConstraint(c1,c2)
p.setObjective(xp.Dot(x, Q + N⁎⁎3 ⁎ np.eye(N), x))p.solve('')
print("nrows, ncols:", p.attributes.rows, p.attributes.cols)
print("solution:", p.getSolution())
p.write("test5-qp", "lp")6.4

Advanced examples: callbacks and problem querying, modifying, andanalysis

6.4.1

Visualize the branch-and-bound tree of a problem
This example shows how to visualize the BB tree of a problem after (partially) solving it. It is assumed
here that all branches are binary.
We ﬁrst deﬁne a message callback for running code whenever the Optimizer wants to print a message.
The callback receives four arguments: the problem and callback data and, most importantly, themessage to be printed and an information number. The callback prints the output message preﬁxed bya time stamp related to the creation of the problem. As the message could be on multiple lines, it issplit into multiple substrings, one per line.

Fair Isaac Corporation Conﬁdential and Proprietary Information

40

Examples of use
import networkx as nx
import timefrom matplotlib import pyplot as plt
def message_addtime (prob, data, msg, info):"""Message callback example: print a timestamp before the message from the optimizer"""
if msg:for submsg in msg.split('\n'):print("{0:6.3f}: [{2:+4d}] {1}".format(time.time() - start_time, submsg, info))

We then deﬁne a recursive function that computes the cardinality of a subtree rooted at a node i. This isnecessary as the visualization of the BB tree is more balanced when the subtree size is taken into
account. The card_subtree array, which is ﬁlled here, is used then for computing the width of eachvisualized subtree.
def postorder_count(node):"""
Recursively count nodes to compute the cardinality of a subtree foreach node"""card = 0
if node in left.keys(): # see if node has a left key
postorder_count(left[node])card += card_subtree[left[node]]
if node in right.keys():postorder_count(right[node])card += card_subtree[right[node]]
card_subtree[node] = 1 + card

We also deﬁne a function that determines the position of each node depending on the cardinality of thesubtree rooted at the node.
def setpos(T, node, curpos, st_width, depth):"""
Set position depending on cardinality of each subtree"""# Special condition: we are at the root
if node == 1:
T.add_node(node, pos=(0.5, 1))alpha = .1 # use a convex combination of subtree comparison and# depth to assign a width to each subtree
if node in left.keys():# X position in the graph should not just depend on depth,# otherwise we'd see a long and thin subtree and it would just# look like a pathleftwidth = st_width ⁎ (alpha ⁎ .5 + (1 - alpha) ⁎ card_subtree[left[node]]/ card_subtree[node])
leftpos = curpos - (st_width - leftwidth) / 2
T.add_node(left[node], pos=(leftpos, - depth))
T.add_edge(node, left[node])
setpos(T, left[node], leftpos, leftwidth, depth + 1)
if node in right.keys():rightwidth = st_width ⁎ (alpha ⁎ .5 + (1 - alpha) ⁎ card_subtree[right[node]]

Fair Isaac Corporation Conﬁdential and Proprietary Information

41

Examples of use/ card_subtree[node])rightpos = curpos + (st_width - rightwidth) / 2
T.add_node(right[node], pos=(rightpos, - depth))
T.add_edge(node, right[node])
setpos(T, right[node], rightpos, rightwidth, depth + 1)

This is the only operation we need to be carried out at every node: given a node number, newnode, andits parent, parent, we store the information in the left and right arrays so that at the end of the BB
we have an explicit BB tree stored in these arrays.
def storeBBnode(prob, Tree, parent, newnode, branch):# Tree is the callback data, and it's equal to T
if branch == 0:
left[parent] = newnodeelse:right[parent] = newnode

We now set up the BB tree data and create a problem. We read it from a local ﬁle, but any user problem
can be read and analyzed. We set the node callback with addcbnewnode so that we can collectinformation at each new node. We also save the initial time for use by message_addtime, the functionthat is called every time the problem prints out a message.
T = nx.Graph()
left = {}right = {}card_subtree = {}pos = {}
start_time = time.time()p = xp.problem()p.addcbmessage(message_addtime)p.read('sampleprob.mps.gz')
p.addcbnewnode(storeBBnode, T, 100)p.controls.maxnode=40000 # Limit the number of nodes inserted in the graphp.solve()postorder_count(1)# assign card_subtree to each node
setpos(T, 1, 0.5, 1, 0) # determine the position of each node
# depending on subtree cardinalities
pos = nx.get_node_attributes(T, 'pos')nx.draw(T, pos) # create BB tree representation
plt.show()# display it; you can zoom indefinitely and see all subtrees

6.4.2

Query and modify a simple problem
This example shows how to change an optimization problem using the Xpress Python interface.
x = xp.var()y = xp.var()cons1=
x + y >= 2
upperlim = 2⁎x + y <= 3
p = xp.problem()p.addVariable(x,y)
p.setObjective((x-4)⁎⁎2 + (y-1)⁎⁎2)

Fair Isaac Corporation Conﬁdential and Proprietary Information

42

Examples of use
p.addConstraint(cons1, upperlim)
p.write('original', 'lp')

After saving the problem to a ﬁle, we change two of its coefﬁcients. Note that the same operations canbe carried out with a single call to p.chgmcoef([cons1,1],[x,0],[3,4]).
p.chgcoef(cons1, x, 3) # coefficient of x in cons1
becomes 3
p.chgcoef(1, 0, 4)# coefficient of y in upperlim becomes 4
p.write('changed', 'lp')

6.4.3

Change a problem after solution
Construct a problem using addVariable and addConstraint, then use the Xpress API routines to amend
the problem with rows and quadratic terms.
import xpress as xp
p = xp.problem()
N = 5
S = range(N)x = [xp.var(vartype=xp.binary) for i in S]
p.addVariable(x)# Vectors of variables can be used whole or addressed with an index or# index range
c0 = xp.Sum(x) <= 10cc = [x[i]/1.1 <= x[i+1]⁎2 for i in range(N-1)]
p.addConstraint(c0, cc)
p.setObjective(3 - x[0])mysol = [0, 0, 1, 1, 1, 1.4]
# add a variable with its coefficientsp.addcols([4], [0,3], [c0,4,2], [-3, 2.4, 1.4], [0], [2], ['Y'], ['B'])p.write("problem1", "lp")# load a MIP solution
p.loadmipsol([0,0,1,1,1,1.4])

We now add a quadratic term x02 – 2x0 x3 + x13 to the second constraint. Note that the -2 coefﬁcient for
an off-diagonal element must be passed divided by two.
p.addqmatrix(cc[0], [x[0],x[3],x[3]], [x[0],x[0],x[3]], [1,-1,1])

As constraint list cc was added after c0, it is the latter which has index 0 in the problem, while cc[0]has index 1.
We then add the seventh and eighth constraints:
subject to:x0 + 2 x1 + 3x2≥

4

4x0 + 5x1 + 6x2 + 7 x3 + 8 x4 -3 y≤

4.4

Note the new column named ’Y’ is added with its index 5 (variables’ indices begin at 0). The same
would happen if 5 were substituted by Y.

Fair Isaac Corporation Conﬁdential and Proprietary Information

43

Examples of use
p.addqmatrix(1, [x[0],x[3],x[3]], [x[0],x[0],x[3]], [1,-1,1])
p.addrows(qrtype=['G', 'L'],
rhs=[4, 4.4],
mstart=[0, 3, 9],mclind=[x[0],x[1],x[2], x[0],x[1],x[2],x[3],x[4], 5],dmatval=[1,2,3,4,5,6,7,8,-3],
names=['newcon1', 'newcon2'])p.solve()p.write("amended", "lp")slacks = []p.calcslacks(solution=mysol, calculatedslacks=slacks)
print("slacks:", slacks)

The code below ﬁrst adds ﬁve columns, then solves the problem and prints the solution, if one has beenfound.
p.addcols([4], [0,3], [c0,4,2], [-3, -2,1], [0], [2], ['p1'], ['I'])
p.addcols([4], [0,3], [c0,4,2], [-3, 2.4, 1.4], [0], [10], ['p2'], ['C'])
p.addcols([4], [0,3], [c0,4,2], [-3,2,1], [0], [1], ['p3'], ['S'])
p.addcols([4], [0,3], [c0,4,2], [-3, 2.4,4], [0], [2], ['p4'], ['P'])
p.addcols([4], [0,3], [c0,4,2], [-3,2,1], [0], [2], ['p5'], ['R'])
p.solve()try:
print("new solution:", p.getSolution())
except:print("could not get solution, perhaps problem is infeasible")

Note that the single command below has the same effect as the four addcols calls above, and is to bepreferred when adding a large number of columns for reasons of efﬁciency.
p.addcols([4,4,4,4,4],[0,3,6,9,12,15],[c0,4,2,c0,4,2,c0,4,2,c0,4,2,c0,4,2],[3, -2, 1, -3, 2.4, 1.4, 3, 2, 1, -3, 2.4, 4, 3, 2, 1],[0,0,0,0,0],[2,10,1,2,2],['p1','p2','p3','p4','p5'],['I','C','S','P','R'])

6.4.4

Comparing the coefﬁcients of two equally sized problems
Given two problems with the same number of variables, we read their coefﬁcient matrices into Scipy so
as to compare each row for discrepancies in the coefﬁcients. We begin by creating two Xpress
problems and reading them from two ﬁles, prob1.lp and prob2.lp, though p1 and p2 might havebeen created with the module’s modeling features.
import xpress as xp
import scipy.sparse
p1 = xp.problem()
p2 = xp.problem()
p1.read('prob1.lp')
p2.read('prob2.lp')

Next we obtain the matrix representation of the coefﬁcient matrix for both problems. Let us suppose
that, for memory reasons, we can only retrieve one million coefﬁcients.

Fair Isaac Corporation Conﬁdential and Proprietary Information

44

Examples of use
coef1, ind1, beg1 = [], [], []coef2, ind2, beg2 = [], [], []p1.getrows(beg1, ind1, coef1, 1000000, 0, p1.attributes.rows - 1)
p2.getrows(beg2, ind2, coef2, 1000000, 0, p2.attributes.rows - 1)

The function problem.getrows provides a richer output by ﬁlling up ind1 and ind2 with the Python
objects (i.e. Xpress variables) corresponding to the variable indices rather than the numerical indices.
We need to convert them to numerical indices using the problem.getIndex function.
ind1n = [p1.getIndex(v) for v in ind1]ind2n = [p2.getIndex(v) for v in ind2]

The next step is to create a Compressed Sparse Row (CSR) format matrix, deﬁned in the
scipy.sparse module, using the data from problem.getrows plus the numerical indices.
Then we convert the CSR matrix to a NumPy array of arrays, so that each row is a (non-compressed)
array to be compared in the loop below.
A1 = scipy.sparse.csr_matrix((coef1, ind1n, beg1))A2 = scipy.sparse.csr_matrix((coef2, ind2n, beg2))
M1 = A1.toarray()
M2 = A2.toarray()for i in range(min(p1.attributes.rows, p2.attributes.rows)):
print(M1[i] != M2[i])The result is a few vectors of size COLS with an element-wise comparison of the coefﬁcient vector ofeach row, with True indicating discrepancies. A more meaningful representation can be given using
other functions in NumPy.
[False False True False False][False False False False False][False False False False True][ True True False False False][False False False False False]

6.4.5

Combining modeling and API functions
This is an example where a problem is loaded from a ﬁle, solved, then modiﬁed by adding a Global
Upper Bound (GUB) constraint. Note that we do not know the structure of the problem when reading it,
yet we can simply extract the list of variables and use them to add a constraint.
import xpress
p = xpress.problem()p.read("example.lp")
p.solve()print("solution of the original problem: ", p.getVariable(), "==>", p.getSolution())

After solving the problem, we obtain its variables through getVariable and add a constraints so that
their sum cannot be more than 1.1.
x = p.getVariable()p.addConstraint(xpress.Sum(x) <= 1.1)
p.solve()print("New solution: ", p.getSolution())

Fair Isaac Corporation Conﬁdential and Proprietary Information

45

Examples of use

6.4.6

A simple Traveling Salesman Problem (TSP) solver
A classical example of use of callbacks is the development of a simple solver for the well-known TSP
problem. The aim here is not to create an efﬁcient solver (there are far better implementations), butrather a simple solver where the user only needs to specify two callbacks: one for checking whether agiven solution forms a Hamiltonian tour and one for separating a subtour elimination constraint fromthe current node solution.
After a successful solve (or an interrupted one with a feasible solution), the best Hamiltonian tour isdisplayed. Note that this section omits unnecessary details (checks of return values, exceptions, etc.)of the actual code, which can be found in the Examples/ directory.
import networkx as nx
import xpress
as xp
import re, math, sysfrom matplotlib import pyplot as plt
import urllib.request as ul
filename = 'dj38.tsp'
ul.urlretrieve('http://www.math.uwaterloo.ca/tsp/world/' + filename, filename)instance = open(filename, 'r')coord_section = False
points = {}G = nx.Graph()

We have downloaded an instance of the TSP and now it must be read and interpreted as it does nothave a format that we know. We save in cx and cy the coordinates of all nodes in the graph, which isassumed to be complete, i.e., all nodes are connected to one another.
for line in instance.readlines():
if re.match('NODE_COORD_SECTION.⁎', line):coord_section = Truecontinueelif re.match('EOF.⁎', line):break
if coord_section:
coord = line.split(' ')index = int(coord[0])cx= float(coord[1])cy= float(coord[2])points[index] = (cx, cy)
G.add_node(index, pos=(cx, cy))

The next step is to deﬁne a callback function for checking if the solution forms a Hamiltonian tour, i.e.,
if it connects all nodes of the graph. The callback will be passed with the method addcbpreintsol,
therefore it needs to return a tuple of two values: the ﬁrst value is True if the solution should be
rejected, and the second is the new cutoff in case it has to be changed. This is not the case here, so
None can be safely returned.
After obtaining the integer solution to be checked, the function scans the graph from node 1 to see if
the solutions at one form a tour.
def check_tour(prob, G, isheuristic, cutoff):s = []

Fair Isaac Corporation Conﬁdential and Proprietary Information

46

Examples of use
prob.getlpsol(s, None, None, None)
orignode = 1
nextnode = 1
card= 0
while nextnode != orignode or card == 0:
FS = [j for j in V if j != nextnodeand s[prob.getIndex(x[nextnode,j])] == 1] # forward starcard += 1
if len(FS) < 1:
return (True, None) # reject solution if we can't close the loop
nextnode = FS[0]# If there are n arcs in the loop, the solution is feasible
return (card < n, None) # accept the cutoff: return second element as None

The second callback to be deﬁned is a separator for subtour elimination constraints. It must return anonzero value if the node is deemed infeasible by the function, zero otherwise. The function addcuts
is used to insert a subtour elimination constraint.
The function works as follows: Starting from node 1, gather all connected nodes of a loop in connset.
If this set contains all nodes, then the solution is valid if integer, otherwise the function adds a subtour
elimination constraint in the form of a clique constraint with all arcs (i, j) for all i, j in connset.
def eliminate_subtour(prob, G):s = [] # initialize s as an empty list to provide it as an output parameterprob.getlpsol(s, None, None, None)
orignode = 1
nextnode = 1
connset= []while nextnode != orignode or len(connset) == 0:
connset.append(nextnode)
FS = [j for j in V if j != nextnodeand s[prob.getIndex(x[nextnode, j])] == 1] # forward star
if len(FS) < 1:
return 0
nextnode = FS[0]if len(connset) < n:# Add a subtour elimination using the nodes in connset (or, if# card(connset) > n/2, its complement)
if len(connset) <= n/2:
columns = [x[i,j] for i in connset for j in connset
if i != j]nArcs = len(connset)
else:
columns = [x[i,j] for i in
V for j inV
if not i in connset and not j in connset and i != j]nArcs = n - len(connset)
nTerms = len(columns)

Fair Isaac Corporation Conﬁdential and Proprietary Information

47

Examples of use

prob.addcuts([1], ['L'], [nArcs - 1], [0, nTerms], columns, [1] ⁎ nTerms)
return 0

We now formulate the problem with the degree constraints on each node and the objective function(the cost of each arc (i, j) is assumed to be the Euclidean distance between i and j).
n = len(points)# number of nodes
V = range(1, n+1)
# set of nodes
A = [(i,j) for i in V for j in V if i != j] # set of arcs (i.e. all pairs)
x = {(i,j): xp.var(name='x_{0}_{1}'.format(i,j), vartype=xp.binary) for (i,j) in A}
conservation_in = [xp.Sum(x[i,j] for j in V if j != i) == 1 for i in V]
conservation_out = [xp.Sum(x[j,i] for j in V if j != i) == 1 for i in V]
p = xp.problem()p.addVariable(x)p.addConstraint(conservation_in, conservation_out)
xind = {(i,j): p.getIndex(x[i,j]) for (i,j) in x.keys()}# Objective function: total distance travelled
p.setObjective(xp.Sum(math.sqrt((points[i][0] - points[j][0])⁎⁎2 +(points[i][1] - points[j][1])⁎⁎2) ⁎x[i,j]for (i,j) in A))
p.controls.maxtime = -2000 # negative for "stop even if no solution is found"p.addcboptnode(eliminate_subtour, G, 1)
p.addcbpreintsol(check_tour,
G, 1)

We now solve the problem, and if a solution is found it is displayed using the Python library
matplotlib.
p.solve()sol = p.getSolution()# Read solution and store it in the graphfor (i,j) in A:
if sol[p.getIndex(x[i,j])] > 0.5:
G.add_edge(i,j)# Display best tour foundpos = nx.get_node_attributes(G, 'pos')nx.draw(G, points) # create a graph with the tour
plt.show()# display it interactively

Another solver for TSP problems is available in example_tsp_numpy.py. The two main differences
consist in the problem generation, which is now random, and in the fact that most data structures are
NumPy vectors and matrices: the optimization variables, the LP solution obtained from theBranch-and-Bound, and the data used to check feasibility of the solutions.

6.4.7

Solving a nonconvex MIQCQP
In this example we turn the Xpress Optimizer into a solver for nonconvex MIQCQPs, i.e. problems with
nonconvex quadratic objective and/or nonconvex quadratic constraints.

Fair Isaac Corporation Conﬁdential and Proprietary Information48

Examples of use

In order to handle nonconvex quadratic constraints, we have to reformulate the problem to a MILP sothat the simplest nonlinear terms, i.e. the products of variables, are transformed into new, so-called
auxiliary variables.
Product xi xj is assigned to a new variable wij so that every occurrence of that product in the problem isreplaced by wij . Assuming li and ui are the lower and upper bound on xi , respectively, we add the linear
McCormick inequalities:

wij ≥ lj xi + li xj - lj li

wij ≥ uj xi + ui xj - uj ui

wij ≤ lj xi + ui xj - lj ui

wij ≤ uj xi + li xj - uj li

The bounds on the new auxiliary variable wij are a function of the bounds on xi and xj .
Below is the code that takes care of reformulating the problem. We ﬁrst have to identify all terms xi xj
and create a dictionary linking each pair (i,j) to an auxiliary variable wij . The dictionary aux is usedthroughout the solver and contains this information. The function create_prob checks all bilinear
terms and creates aux and the McCormick inequalities.
def create_prob(filename):[...]x = p.getVariable()aux = {}# Dictionary containing the map (x_i,x_j) --> y_ij[...]
p.addConstraint([aux[i, j] >= lb[j]⁎x[i] + lb[i]⁎x[j] - lb[i] ⁎ lb[j]for (i, j) in aux.keys() if max(-lb[i], -lb[j]) < xp.infinity],[aux[i, j] >= ub[j]⁎x[i] + ub[i]⁎x[j] - ub[i] ⁎ ub[j]for (i, j) in aux.keys() if max(ub[i], ub[j]) < xp.infinity],[aux[i, j] <= ub[j]⁎x[i] + lb[i]⁎x[j] - lb[i] ⁎ ub[j]for (i, j) in aux.keys() if max(-lb[i], ub[j]) < xp.infinity],[aux[i, j] <= lb[j]⁎x[i] + ub[i]⁎x[j] - ub[i] ⁎ lb[j]for (i, j) in aux.keys() if max(ub[i], -lb[j]) < xp.infinity])

We also needs to tell the Optimizer that the newly created auxiliary variables and the variables thatused to appear in bilinear terms should be protected against deletion by the presolver.
securecols = list(aux.values())
secureorig = set()
for i, j in aux.keys():secureorig.add(i)secureorig.add(j)securecols += list(secureorig)
p.loadsecurevecs(mrow=None, mcol=securecols)

The creation of a single auxiliary variable is done in addaux, where its bounds are created and,depending on whether it is the product of two variables or the square of one, it receives a different
treatment.
def addaux(aux, p, i, j, lb, ub, vtype):

Fair Isaac Corporation Conﬁdential and Proprietary Information

49

Examples of use# Find bounds of auxiliary first
if i != j:# bilinear terml, u = bdprod(lb[i], ub[i], lb[j], ub[j])elif lb[i] >= 0:l, u = lb[i]⁎⁎2, ub[i]⁎⁎2elif ub[i] <= 0:l, u = ub[i]⁎⁎2, lb[i]⁎⁎2
else:l, u = 0, max([lb[i]⁎⁎2, ub[i]⁎⁎2])

After setting the bounds on wij , we determine its type and create the corresponing xp.var object.
if vtype[i] == 'B' and vtype[j] == 'B':t = xp.binary
elif (vtype[i] == 'B' or vtype[i] == 'I') and \(vtype[j] == 'B' or vtype[j] == 'I'):t = xp.integerelse:
t = xp.continuous# Add auxiliaries
aux[i, j] = xp.var(lb=l, ub=u, vartype=t,
name='aux_{0}_{1}'.format(
p.getVariable(i).name,p.getVariable(j).name))
return aux[i, j]

Quadratic constraints and the quadratic objective (if any) are converted in convQaux, where they are
replaced by a linear expression containing auxiliary variables.
def convQaux(p, aux, mstart, ind, coef, row, lb, ub, vtype):rcols = []rrows = []rcoef = []for i,__ms in enumerate(mstart[:-1]):
for j in range(mstart[i], mstart[i+1]):
J = p.getIndex(ind[j])if (i, J) not in aux.keys():y = addaux(aux, p, i, J, lb, ub, vtype)p.addVariable(y)else:
y = aux[i, J]
if row < 0: # objective
mult = .5
else:
mult = 1
if i != J:
coe = 2 ⁎ mult ⁎ coef[j]
else:
coe =
mult ⁎ coef[j]if row < 0:p.chgobj([y], [coe])else:
rcols.append(y)rrows.append(row)rcoef.append(coe)if row >= 0:

Fair Isaac Corporation Conﬁdential and Proprietary Information50

Examples of use# This is a quadratic constraint, not the objective function# Add linear coefficients for newly introduced variables
p.chgmcoef(rrows, rcols, rcoef)# Remove quadratic matrix
p.delqmatrix(row)else:# Objective: Remove quadratic part
indI = []for i in range(len(mstart) - 1):
indI.extend([i] ⁎ (mstart[i+1] - mstart[i]))# Set all quadratic elements to zerop.chgmqobj(indI, ind, [0] ⁎ mstart[-1])The new problem, called a reformulation, is then solved as a MILP with a few callbacks. Given that the
problem is nonconvex, we need to branch on continuous variables, those that appear in bilinear terms,
and we also need to keep adding McCormick inequalities when the bounds change. This is because inbranch-and-bound algorithms for nonconvex problems the linear relaxation should be exact at theextremes of the variable bound ranges.
Another callback is to decide whether to accept or not a solution that was found by thebranch-and-bound: because the constraints linking w to x are missing, we must make sure that they aresatisﬁed by a solution, and must refuse a solution that does not satisfy wij = xi xj .
def solveprob(p, aux):p.addcbpreintsol(cbchecksol, aux, 1)
p.addcboptnode(cbaddcuts, aux, 3)
p.addcbchgbranchobject(cbbranch, aux, 1)
p.mipoptimize()

The callback functions are fundamental. The branch callback checks whether the auxiliary variables wij
are satisﬁed, and if not it creates a branching object on either xi or xj . Due to the presolved nature of the
problem at this point in the branch-and-bound, care must be applied in handling the variable indices, as
they might have changed by the presolver to allow for a smaller problem.
def cbbranch(prob, aux, branch):lb, ub = getCBbounds(prob, len(sol))x = prob.getVariable()# presolved variables

rowmap = []colmap = []prob.getpresolvemap(rowmap, colmap)
invcolmap = [-1 for _ in lb]
for i, m in enumerate(colmap):
invcolmap[m] = i# Check if all auxiliaries are equal to their respective bilinear# term. If so, we have a feasible solution
sol = np.array(sol)discr = sol[Aux_ind] - sol[Aux_i] ⁎ sol[Aux_j]
discr[Aux_i == Aux_j] = np.maximum(0, discr[Aux_i == Aux_j])
maxdiscind = np.argmax(np.abs(discr))
if abs(discr[maxdiscind]) < eps:
return branch

Fair Isaac Corporation Conﬁdential and Proprietary Information

51

Examples of use

i,j = Aux_i[maxdiscind], Aux_j[maxdiscind]
yind = prob.getIndex(aux[i, j])

For terms of the form wii = xi 2 , branching might still be necessary as the curve deﬁning it is anonconvex set.
if i == j:# Test of violation is done on the original# space. However, the problem variables are scrambled with invcolmap
if sol[i] > lb[i] + eps and \sol[i] < ub[i] - eps and \sol[yind] > sol[i]⁎⁎2 + eps and \sol[yind] - lb[i]⁎⁎2 <= (ub[i] + lb[i]) ⁎ (sol[i] - lb[i]) - eps:
# Can't separate, must branch. Otherwise OA or secant# cut separated above should be enoughbrvarind = invcolmap[i]brpoint = sol[i]brvar = x[brvarind]
brleft = brpoint
brright = brpoint
assert(brvarind >= 0)
if brvar.vartype in [xp.integer, xp.binary]:
brleft = math.floor(brpoint + 1e-5)
brright = math.ceil(brpoint - 1e-5)
b = xp.branchobj(prob, isoriginal=False)b.addbranches(2)addrowzip(prob, b, 0, 'L', brleft, [i], [1])addrowzip(prob, b, 1, 'G', brright, [i], [1])# New variable bounds are not enough, add new McCormick# inequalities for y = x⁎⁎2: suppose x0,y0 are the current# solution values for x,y, yp = x0⁎⁎2 and xu,yu = xu⁎⁎2 are their# upper bound, and similar for lower bound. Then these two# rows must be added, one for each branch:## y - yp <= (yl-yp)/(xl-x0) ⁎ (x - x0) <===># (yl-yp)/(xl-x0) ⁎ x - y >= (yl-yp)/(xl-x0) ⁎ x0 - yp#
# y - yp <= (yu-yp)/(xu-x0) ⁎ (x - x0) <===># (yu-yp)/(xu-x0) ⁎ x - y >= (yu-yp)/(xu-x0) ⁎ x0 - yp#
# Obviously do this only for finite bounds
ypl = brleft⁎⁎2
ypr = brright⁎⁎2
if lb[i] > -1e7 and sol[i] > lb[i] + eps:yl = lb[i]⁎⁎2coeff = (yl - ypl) / (lb[i] - sol[i])if coeff != 0:
addrowzip(prob, b, 0, 'G', coeff⁎sol[i] - ypl,[i, yind], [coeff, -1])
if ub[i] < 1e7 and sol[i] < ub[i] - eps:
yu = ub[i]⁎⁎2

Fair Isaac Corporation Conﬁdential and Proprietary Information

52

Examples of use
coeff = (yu - ypr) / (ub[i] - sol[i])if coeff != 0:
addrowzip(prob, b, 1, 'G', coeff⁎sol[i] - ypr,[i, yind], [coeff, -1])
return b

Similarly for bilinear terms, we must choose where to branch and on which variable.
else:
lbi0, ubi0 = lb[i], ub[i]lbi1, ubi1 = lb[i], ub[i]lbj0, ubj0 = lb[j], ub[j]lbj1, ubj1 = lb[j], ub[j]# No cut violated, must branch
if min(sol[i] - lb[i], ub[i] - sol[i]) / (1 + ub[i] - lb[i]) > \min(sol[j] - lb[j], ub[j] - sol[j]) / (1 + ub[j] - lb[j]):lbi1 = sol[i]ubi0 = sol[i]brvar = ielse:
lbj1 = sol[j]ubj0 = sol[j]brvar = jalpha = 0.2
brvarind = invcolmap[brvar]
brpoint = sol[brvar]
brleft = brpoint
brright = brpoint
if x[brvarind].vartype in [xp.integer, xp.binary]:
brleft = math.floor(brpoint + 1e-5)
brright = math.ceil(brpoint - 1e-5)
b = xp.branchobj(prob, isoriginal=False)b.addbranches(2)addrowzip(prob, b, 0, 'L', brleft, [brvar], [1])addrowzip(prob, b, 1, 'G', brright, [brvar], [1])# As for the i==j case, the variable branch is# insufficient, so add updated McCormick inequalities.
# There are two McCormick inequalities per changed bound:## y >= lb[j] ⁎ x[i] + lb[i] ⁎ x[j] - lb[j] ⁎ lb[i] ---> add to branch 1# y >= ub[j] ⁎ x[i] + ub[i] ⁎ x[j] - ub[j] ⁎ ub[i] ---> add to branch 0# y <= lb[j] ⁎ x[i] + ub[i] ⁎ x[j] - lb[j] ⁎ ub[i] ---> add to branch 1 if x[brvarind] == j,# y <= ub[j] ⁎ x[i] + lb[i] ⁎ x[j] - ub[j] ⁎ lb[i] ---> add to branch 1 if x[brvarind] == i,addrowzip(prob, b, 0, 'G', - ubi0 ⁎ ubj0, [yind, i, j], [1, -ubj0, -ubi0])
addrowzip(prob, b, 1, 'G', - lbi1 ⁎ lbj1, [yind, i, j], [1, -lbj1, -lbi1])
if brvarind == i:addrowzip(prob, b, 0, 'L', - lbj0 ⁎ ubi0, [yind, i, j], [1, -lbj0, -ubi0])
addrowzip(prob, b, 1, 'L', - ubj1 ⁎ lbi1, [yind, i, j], [1, -ubj1, -lbi1])
else:
addrowzip(prob, b, 0, 'L', - ubj0 ⁎ lbi0, [yind, i, j], [1, -ubj0, -lbi0])
addrowzip(prob, b, 1, 'L', - lbj1 ⁎ ubi1, [yind, i, j], [1, -lbj1, -ubi1])
return b# If no branching rule was found, return none

Fair Isaac Corporation Conﬁdential and Proprietary Information

53

Examples of use
return branch

The callback for checking a solution is straightforward: for all pairs ij, check if the corresponding
identity wij = xi xj is satisﬁed, and if not, simply reject the solution.
def cbchecksol(prob, aux, soltype, cutoff):
global Aux_i, Aux_j, Aux_ind
if (prob.attributes.presolvestate & 128) == 0:
return (1, cutoff)
sol = []
# Retrieve node solution
try:
prob.getlpsol(x=sol)
except:return (1, cutoff)
sol = np.array(sol)# Check if all auxiliaries are equal to their respective bilinear# term. If so, we have a feasible solution
refuse = 1 if np.max(np.abs(sol[Aux_i] ⁎ sol[Aux_j] - sol[Aux_ind])) > eps else 0# Return with refuse != 0 if solution is rejected, 0 otherwise;# and same cutoff
return (refuse, cutoff)

An important part of this nonconvex solver is a function that computes a new feasible solution. The
one we attempt here is rather trivial and probably not able to ﬁnd good solutions, but one could add
other algorithms, which for example might just use an alternative solver, and ﬁnd a feasible solution,
regardless of how good.
def cbfindsol(prob, aux):sol = []
try:

prob.getlpsol(x=sol)
except:return 0
xnew = sol[:]# Round solution to nearest integer
for i,t in enumerate(var_type):
if t == 'I' or t == 'B' and \xnew[i] > math.floor(xnew[i] + prob.controls.miptol) + prob.controls.miptol:
xnew[i] = math.floor(xnew[i] + .5)
for i, j in aux.keys():yind = prob.getIndex(aux[i, j])xnew[yind] = xnew[i] ⁎ xnew[j]prob.addmipsol(xnew)
return 0

The function for adding McCormick inequalities is perhaps the most important as it allows for the
lower bound in the branch-and-bound to get tighter at every node. All violated inequalities are added forall pairs ij.

Fair Isaac Corporation Conﬁdential and Proprietary Information

54

Examples of use
def cbaddmccormickcuts(prob, aux, sol):lb, ub = getCBbounds(prob, len(sol))cuts = []# Check if all auxiliaries are equal to their respective bilinear# term. If so, we have a feasible solution
for i, j in aux.keys():yind = prob.getIndex(aux[i, j])
if i == j:# Separate quadratic term
if sol[yind] < sol[i]⁎⁎2 - eps and \abs(sol[i]) < xp.infinity / 2:
xk = sol[i]ox = xkoy = ox ⁎⁎ 2
# Add Outer Approximation cut y >= xs^2 + 2xs⁎(x-xs)# <===> y - 2xs⁎x >= -xs^2
cuts.append((TYPE_OA, 'G', - ox⁎⁎2, [yind, i],[1, -2⁎ox]))# Otherwise, check if secant can be of help: y0 - xl⁎⁎2 ># (xu⁎⁎2 - xl⁎⁎2) / (xu - xl) ⁎ (x0 - xl)
elif sol[yind] > sol[i]⁎⁎2 + eps and \sol[yind] - lb[i]⁎⁎2 > (ub[i] + lb[i]) ⁎ (sol[i] - lb[i]) \+ eps and abs(lb[i] + ub[i]) < xp.infinity / 2:
cuts.append((TYPE_SECANT, 'L',
lb[i]⁎⁎2 - (ub[i] + lb[i]) ⁎ lb[i],[yind, i], [1, - (lb[i] + ub[i])]))
elif abs(sol[yind] - sol[i]⁎sol[j]) > eps:
# Separate bilinear term, where i != j.
# least one cut violated

There might be at

if sol[yind] < lb[j]⁎sol[i] + lb[i]⁎sol[j] - lb[i]⁎lb[j] - eps:
if lb[i] > -xp.infinity / 2 and lb[j] > -xp.infinity / 2:
cuts.append((TYPE_MCCORMICK, 'G', - lb[i] ⁎ lb[j],[yind, i, j], [1, -lb[j], -lb[i]]))elif sol[yind] < ub[j]⁎sol[i] + ub[i]⁎sol[j] - ub[i]⁎ub[j] - eps:
if ub[i] < xp.infinity / 2 and ub[j] < xp.infinity / 2:
cuts.append((TYPE_MCCORMICK, 'G', - ub[i] ⁎ ub[j],[yind, i, j], [1, -ub[j], -ub[i]]))elif sol[yind] > lb[j]⁎sol[i] + ub[i]⁎sol[j] - ub[i]⁎lb[j] + eps:
if ub[i] < xp.infinity / 2 and lb[j] > -xp.infinity / 2:
cuts.append((TYPE_MCCORMICK, 'L', - ub[i] ⁎ lb[j],[yind, i, j], [1, -lb[j], -ub[i]]))elif sol[yind] > ub[j]⁎sol[i] + lb[i]⁎sol[j] - lb[i]⁎ub[j] + eps:
if lb[i] > -xp.infinity / 2 and ub[j] < xp.infinity / 2:
cuts.append((TYPE_MCCORMICK, 'L', - lb[i] ⁎ ub[j],[yind, i, j], [1, -ub[j], -lb[i]]))# Done creating cuts. Add them to the problem
for (t, s, r, I, C) in cuts: # cuts might be the empty list
mcolsp, dvalp = [], []drhsp, status = prob.presolverow(s, I, C, r, prob.attributes.cols,
mcolsp, dvalp)
if status >= 0:
prob.addcuts([t], [s], [drhsp], [0, len(mcolsp)], mcolsp, dvalp)
return 0

Fair Isaac Corporation Conﬁdential and Proprietary Information

55

Examples of use

Another useful component of any nonconvex solver is a procedure to tighten the variable bounds basedon information that is known on other variables. For example, if new bounds are inferred on wij ,possible tighter lower or upper bounds can be deduced on xi and/or xj .
def cbboundreduce(prob, aux, sol):cuts = []lb, ub = getCBbounds(prob, len(sol))# Check if bounds on original variables can be reduced based on# bounds on auxiliary ones. The other direction is already taken# care of by McCormick and tangent/secant cuts.
feastol = prob.controls.feastol
for (i,j),a in aux.items():
auxind = prob.getIndex(a)lbi = lb[i]ubi = ub[i]lba = lb[auxind]
uba = ub[auxind]
if i == j:# check if upper bound is tight w.r.t. bounds on# x[i]# Forward propagation: from new independent variable# bounds, infer new bound for dependent variable.
if uba > max(lbi⁎⁎2, ubi⁎⁎2) + feastol:cuts.append((TYPE_BOUNDREDUCE, 'L', max(lbi⁎⁎2, ubi⁎⁎2), [auxind], [1]))if lbi > 0 and lba < lbi⁎⁎2 - feastol:cuts.append((TYPE_BOUNDREDUCE, 'G', lbi⁎⁎2, [auxind], [1]))elif ubi < 0 and lba < ubi⁎⁎2 - feastol:cuts.append((TYPE_BOUNDREDUCE, 'G', ubi⁎⁎2, [auxind], [1]))if uba < -feastol:
return 1 # infeasible nodeelse:
if uba < lbi⁎⁎2 - feastol:
if lbi > 0:
return 1 # infeasible node
else:
cuts.append((TYPE_BOUNDREDUCE, 'G', -math.sqrt(uba), [i], [1]))if uba < ubi⁎⁎2 - feastol:
if ubi < - feastol:
return 1
else:
cuts.append((TYPE_BOUNDREDUCE, 'L', math.sqrt(uba), [i], [1]))if lba > prob.controls.feastol and lbi > 0 and lbi⁎⁎2 < lba - feastol:cuts.append((TYPE_BOUNDREDUCE, 'G', math.sqrt(lba), [i], [1]))else:tlb, tub = bdprod(lb[i], ub[i], lb[j], ub[j])if lba < tlb - feastol:cuts.append((TYPE_BOUNDREDUCE, 'G', tlb, [auxind], [1]))if uba > tub + feastol:cuts.append((TYPE_BOUNDREDUCE, 'L', tub, [auxind], [1]))# For simplicity let's just assume lower bounds are nonnegative
lbj = lb[j]Fair Isaac Corporation Conﬁdential and Proprietary Information

56

Examples of use
ubj = ub[j]if lbj >= 0 and lbi >= 0:
if lbi⁎ubj < lba - feastol:cuts.append((TYPE_BOUNDREDUCE, 'G', lba / ubj, [i], [1]))if lbj⁎ubi < lba - feastol:cuts.append((TYPE_BOUNDREDUCE, 'G', lba / ubi, [j], [1]))if lbi⁎ubj > uba + feastol:cuts.append((TYPE_BOUNDREDUCE, 'L', uba / lbi, [j], [1]))if lbj⁎ubi > uba + feastol:cuts.append((TYPE_BOUNDREDUCE, 'L', uba / lbj, [i], [1]))# Done creating cuts. Add them to the problem
for (t, s, r, I, C) in cuts:# cuts might be the empty list

mcolsp, dvalp = [], []drhsp, status = prob.presolverow(s, I, C, r, prob.attributes.cols,
mcolsp, dvalp)
if status >= 0:
if len(mcolsp) == 0:
continueelif len(mcolsp) == 1:
if s == 'G':
btype = 'L'
elif s == 'L':
btype = 'U'else: # don't want to add an equality bound reduction
continue
assert(dvalp[0] > 0)
prob.chgbounds(mcolsp,[btype],[drhsp/dvalp[0]])else:prob.addcuts([t], [s], [drhsp], [0, len(mcolsp)], mcolsp, dvalp)
return 0

There are a few other functions not shown here that are used in the example. These are functions for
retrieving bounds withing a callback and other service functions. The example ﬁle provides commented
code that can be used to improve the solver.

6.5

Translated Mosel examples
The subdirectory mosel_examples of the Python examples directory contains a few examples from
the Mosel distribution that were adapted to the Xpress Python interface:

blend.py, blend2.py: variants of an oil blending optimization model;
burglari.py, burglar.py, burglarl.py, burglar_rec.py: several variants of the
knapsack problem

catenary.py: optimization model for ﬁnding the position of all elements of a hanging chainchess.py, chess2.py: two variants on the simple problem of production management;coco.py: Multiperiod production planning problem;complex_test.py: an example of complex numbers (a native type in Python



fstns.py: the problem of ﬁrestation siting;Fair Isaac Corporation Conﬁdential and Proprietary Information

57

Examples of use

date_test.py: an example of dates using the datatime module;pplan.py: a production planning example;trans.py: a transportation problem.

Fair Isaac Corporation Conﬁdential and Proprietary Information

58

CHAPTER 7

Reference Manual
7.1

Using this chapter
This chapter provides a list of functions available through the Xpress Python interface. For eachfunction, the synopsis and an example are given.
In keeping with the Xpress Optimizer’s C API, the name and order of the parameters used in thesefunctions has been retained. However, in order to make optimal use of the greater ﬂexibility provided by
Python, the argument lists and the return value of some functions has been modiﬁed so as to obtain amore compact notation.
For example, for functions with a list as an argument, the number of elements of the list is not part of
the arguments. Compare the call to the C function XPRSaddrows, where the parameters newrow andnewnz must be passed, to its Python counterpart:(C)

result = XPRSaddrows (prob, n, nnz, type,rhs, NULL, mstart, indices, values);(Python) p.addrows (type, rhs, None, mstart, indices, values)
In the Python version, the prob pointer is not provided as obviously addrows is a method of the
problem class. The C variables n and nnz, which are assigned to arguments newrow and newnz,
respectively, of the call to XPRSaddrows, are not necessary in the Python call as the length of rhs,
mstart, etc. is inferred from the passed lists. If the lengths of all lists passed as arguments are notconsistent with one another, an error will be returned.
Because lists (or tuples, generators, iterators, sequences) can be used as parameters of all functions inthis manual, their size does not need to be passed explicitly as it is detected from the parameter itself.
The interface will check the consistency and the content if the vector is referred to the variables orconstraints, and will return an error in case of a mismatch.
When passing (lists, arrays, dictionaries of) variables, constraints, or SOSs, there are three ways ofreferring to these entities: by numerical index, by Python object, and by name. For instance, consider
the problem.getSolution method, which admits both an empty argument and one or a list ofvariables. If we deﬁne a variable with a name as follows
x = xpress.var(name='myvar')p = xpress.problem()p.addVariable (x)then we can refer to its index (which will be 0 here as it is the ﬁrst variable added to the problem), by its
object name, i.e., x, and by its given name "myvar", in the three following (equivalent) ways:
print('x is ', p.getSolution(x))

Fair Isaac Corporation Conﬁdential and Proprietary Information

59

Reference Manual

print('x is ', p.getSolution(0))
print('x is ', p.getSolution('myvar'))Another difference between the Python methods and their C API counterpart is that some output
arguments are no longer passed (by reference) as arguments to the Python functions but rather are(part of) the value returned by the function. Where multiple scalar output parameters are returned by
the C API function, some Python functions return a tuple containing all such output values.
The non-scalar parameters can instead be speciﬁed as lists, NumPy arrays, sequences, or generators
when applicable. The output non-scalar parameters are stored as lists.
Optional parameters can be speciﬁed as None or skipped, provided the subsequent arguments are
explicitly declared with their parameter name as Python allows:p.addrows(qrtype=type, rhs=rhs, mstart=mstart,
mclind=indices, dmatval=values)
Because the Python interface relies on the Xpress Optimizer C Application Program Interface, it isadvisable to complement the knowledge in this reference manual with that of the Xpress Optimizerreference manual.

Format of the reference
The descriptions in the following pages report, for each function:


Name;



A short description of its purpose;

Its synopsis, i.e., how it must be called. If it returns a value, then it will be presented as an
assignment Python command, otherwise it will be just shown as a call without a returned value;also, if it is a module function rather than a problem-speciﬁc function, it will be preﬁxed by
xpress;

A description of its arguments and whether each argument is optional;

Error values;

Associated controls;A sample usage of the function;

Further useful information about the function;

Related functions, parameters.

Note that all arguments deﬁned in the following as "array" can be many other Python non-scalarobjects: lists, generators, and NumPy arrays are admissible as parameters, except when speciﬁed (e.g.
getControl). However, for simplicity we refer to non-scalar arguments as array.
Finally, some attributes and controls are referred to as uppercase words for clarity. For example, ROWS
indicates the attribute "rows" of a problem, hence it is equivalent to problem.attributes.rows.

7.2

Global methods of the Xpress module
Below is a list of functions that are invoked from the Xpress module, i.e., they are not methods of the
problem or the branchobj class and can be invoked after the import command. The invocation istherefore as in the example that follows:

Fair Isaac Corporation Conﬁdential and Proprietary Information

60Reference Manual

import xpress as xp
print(xp.getlasterror())

xpress.init

xpress.free

xpress.addcbmsghandler

xpress.getbanner

xpress.getcheckedmodexpress.getdaysleft

xpress.getlasterror

xpress.getlicerrmsg

xpress.getversion

xpress.Sum

xpress.Dot

xpress.setcheckedmodexpress.And

xpress.Or

xpress.pwl

xpress.setdefaultcontrol

xpress.setdefaults

xpress.featurequery

xpress.removecbmsghandler

xpress.setarchconsistency

xpress.manualxpress.examples

7.3

Methods of the class problem
The tables below show all methods of the class problem of the Xpress Python interface, with the
exception of callbacks, which are listed separately. Their invocation is therefore to be preceded by aproblem object (the class preﬁx problem. is omitted in the table for compactness), as follows:
import xpress as xp
x = xp.var()p = xp.problem()p.setObjective(x + 3 ⁎ x⁎⁎2 + 2)

addcols

addConstraint

addgencons

addIndicatoraddmipsol

addpwlcons

addqmatrix

addrows

addsetnames

addSOS

addVariablebasisstability

btran

calcobjective

calcreducedcosts

calcslacks

calcsolinfo

chgbounds

chgcoefchgcoltype

chgglblimit

chgmcoef

chgmqobj

chgobjchgobjsense

chgqobjchgqrowcoeffchgrhschgrhsrange

chgrowtype

copy

copycontrols

crossoverlpsol

delConstraint

delgencons

delpwlcons

delqmatrix
estimaterowdualranges

delSOS
fixglobals

delVariable
ftran

dumpcontrols

Fair Isaac Corporation Conﬁdential and Proprietary Information

61

Reference Manual

getAttrib

getbasisgetbasisval

getcoefgetcols

getcoltype

getConstraint

getControl

getdirs

getDualgetdualraygetgencons

getglobal

getiisdata

getIndex

getIndexFromName

getindicators

getinfeas

getlastbarsol

getlasterror

getlb

getlpsol

getlpsolval

getmessagestatus

getmipsol

getmipsolval

getmqobj

getnamelist

getobjgetObjVal

getpivotorder

getpivots

getpresolvebasis

getpresolvemap

getpresolvesol

getprimalray

getProbStatus

getProbStatusString

getpwlcons

getqobjgetqrowcoeff

getqrowqmatrix

getqrowqmatrixtriplets

getqrows

getRCost

getrhsgetrhsrange

getrows

getrowtype

getscaledinfeas

getSlack

getSolution

getSOS

getub

getunbvec

getVariablehasdualrayhasprimalray

iisalliisclear

iisfirst

iisisolations

iisnext

iisstatus

iiswriteloadbasisloadbranchdirs

loaddelayedrows

loaddirs

loadlpsolloadmipsol

loadmodelcuts

loadpresolvebasis

loadpresolvedirs

loadproblem

loadsecurevecs

lpoptimize

mipoptimize

name

objsa

postsolve

presolverow

read

readbasis

readbinsol

readdirs

readslxsol

refinemipsol

repairinfeas

repairweightedinfeas

repairweightedinfeasbounds

restore

reset

rhssa

save

scale

setControl

setdefaults

setindicators

setlogfile

setmessagestatus

setObjective

setprobname

solvestrongbranchwrite

writebasis

writebinsol

writedirs

writeprtsol

writeslxsol

writesol

The following table contains the problem functions to be called for nonlinear problems.

Fair Isaac Corporation Conﬁdential and Proprietary Information

62

Reference Manual

7.4

addcoefs

adddfsaddtolsets

addvars

cascadecascadeorderchgcascadenlimit

chgccoef

chgnlcoef

chgdeltatype

chgdf

chgrowstatuschgrowwt

chgtolset

chgvarconstructdelcoefs

deltolsets

delvars

evaluatecoef

evaluateformula

fixpenalties

getccoef

getcoefformula

getcoefs

getcolinfo

getdf

getrowinfo

getrowstatus

getrowwt

getslpsol

gettolset

getvarglobalsol

loadcoefs

loaddfs

loadtolsets

loadvars

msaddcustompreset

msaddjob

msaddpreset

msclearpresolve

printmemory

printevalinfo

reinitialize

scaling

setcurrentiv

unconstruct

updatelinearization

validate

validatekkt

validaterowvalidatevector

Methods for branching objects
The following pages present the methods of the branchobj class, i.e., the methods used whencreating and manipulating branching objects. Their invocation can be as follows:
import xpress as xp
b = xp.branchobj()
b.addbranches(3)branchobj.addbounds

branchobj.addbranches

branchobj.addcuts

branchobj.addrows

branchobj.getbounds

branchobj.getbranches

branchobj.getid

branchobj.getlasterror

branchobj.getrows

branchobj.setpreferredbranchbranchobj.setpriority

branchobj.store

branchobj.validate

7.5

Methods for adding/removing callbacks of a problem object
The following pages present methods that can be called from a problem before optimization has
started, to add or remove callbacks. All these methods are part of the problem class and have to beinstantiated from a problem object.

Fair Isaac Corporation Conﬁdential and Proprietary Information

63

Reference Manual

7.6

addcbbariteration

removecbbariteration

addcbbarlog

removecbbarlog

addcbchgbranchobject

removecbchgbranchobject

addcbchecktime

removecbchecktime

addcbcutlog

removecbcutlog

addcbdestroymt

removecbdestroymt

addcbgapnotify

removecbgapnotify

addcbgloballog

removecbgloballog

addcbinfnoderemovecbinfnodeaddcbintsol

removecbintsol

addcblplog

removecblplog

addcbmessage

removecbmessage

addcbmipthread

removecbmipthread

addcbnewnoderemovecbnewnodeaddcbnodecutoff

removecbnodecutoff

addcboptnoderemovecboptnodeaddcbpreintsol

removecbpreintsol

addcbprenoderemovecbprenodeaddcbusersolnotify

removecbusersolnotify

Methods to be used within a callback of a problem object
The following methods can be called from within a callback function that has been passed in one of the
problem.addcb⁎ methods. Calling these functions outside of a callback may result in an error andtrigger termination of the optimization process. We provide two tables: one is for the Optimizer andanother for the nonlinear solvers.
copycallbacks

delcpcutsdelcuts

getcpcutlist

getcpcuts

getcutlist

getcutmap

getcutslack

interrupt

loadcuts

setbranchbounds

setbranchcuts

storebounds

storecuts

strongbranchcb

addcuts
setcbcascadeend

setcbcascadestart

setcbcascadevar

setcbcascadevarfail

setcbcoefevalerror

setcbconstruct

setcbdestroy

setcbdrcol

setcbintsol

setcbiterend
setcbmessage

setcbiterstart
setcbmsjobend

setcbitervar
setcbmsjobstart

setcbmswinner

setcboptnodesetcbprenodesetcbslpend

setcbslpnodesetcbslpstart

Fair Isaac Corporation Conﬁdential and Proprietary Information

64Reference Manual

object.extractLinear
Purpose
Synopsis

Returns the variables and coefﬁcients of the linear part of any expression.
vars, coef = a.extractLinear()Arguments
a
vars
coef
ExampleAn expression or variable.
A list containing the variable objects composing the linear expression in a.
A list containing the corresponding coefﬁcients in the linear expression.

The following code snippets show what is the expected result of applying extractLinear:
import xpress as xp
x = xp.var()y = xp.var(name='myvar')a = x + 2⁎yb = 3⁎xc = y⁎⁎2 + x⁎⁎2 - 6⁎x
d = x⁎⁎5 - 7⁎x # nonlinear expression
print (a.extractLinear()) # will print "([C1, myvar], [1, 2])"
assert (a.extractLinear() == ([x, y], [1, 2]))
print (b.extractLinear())
print (c.extractLinear())
print (d.extractLinear())# will print "([C1], [3])"# will print "([C1], [-6])"# will print "([C1], [-7])"

Further information
1. Note that this operator returns variable objects, not indices, in the vars portion of the output tuple. To
obtain indices, use the problem.getIndex function. Printing these lists will show the name of theassociated variables, as determined by the user when creating the variable with the name argument or,
if name was not provided, it will show the name as determined by the Optimizer’s library (default
variable names are "C"+index). See also the Modelling chapter.
2. This operator is most useful only for linear expressions with more than one element. For nonlinear
expressions, the function attempts to extract as much linear information it can, but will not be able toinfer linearity apart from the most obvious cases. For example, for the expression x⁎⁎4 +xp.log(xp.exp(y)), which contains the linear term y, the function will return ([],[]).

Fair Isaac Corporation Conﬁdential and Proprietary Information

65

Reference Manual

object.extractQuadratic
Purpose
Synopsis

Returns the variables and coefﬁcients of the quadratic part of any expression.
vars1, vars2, coef = a.extractQuadratic()

Argumentsa
An expression or variable.
vars1 A list containing the ﬁrst variables of each bilinear term composing the quadratic expression
in a.
vars2 A list containing the second variables of each bilinear term of the quadratic expression in a.
coef A list containing the corresponding coefﬁcients in the quadratic expression.
ExampleThe following code snippets show what is the expected result of applying extractQuadratic:
import xpress as xp
x = xp.var()y = xp.var()z = xp.var()a = x + 2⁎y + x⁎y + 8 ⁎ x⁎⁎2
b = 3⁎x⁎⁎2 + z + 4
c = y⁎⁎2 + x⁎⁎2 - 6⁎x⁎yd = x⁎⁎5 - 7⁎x⁎y - 4⁎x⁎y⁎z # nonlinear expressione = x⁎y + y⁎x # note: same bilinear term added twice. This is compressed to 2⁎
print (a.extractQuadratic()) # will print "([C1, C1], [C2,C1], [1,8])"
assert (a.extractQuadratic() == ([x,x], [y,x], [1,8]))
print (b.extractQuadratic())
print (c.extractQuadratic())
print (d.extractQuadratic())
print (e.extractQuadratic())# will print "([C1], [C1], [3])"# will print "([C2, C1], [C2, C1], [1, 1])"# will print "([C1], [C2], [-7])"# will print "([C1], [C2], [2])"Further information
1. Similar to object.extractLinear, this operator returns variable objects, not indices, in the vars
portion of the output tuple. To obtain indices, use the problem.getIndex function. Printing theselists will show the name of the associated variables, as determined by the user when creating thevariable with the name argument or, if name is not provided, it will show the name as determined by the
Optimizer’s library (default variable names are "C"+index). See also the Modelling chapter.
2. This operator is most useful only for quadratic expressions with more than one element. For nonlinear,
non-quadratic expressions, the function attempts to extract as much quadratic information it can, butwill not be able to detect quadratic/bilinear expressions apart from the most obvious cases. For
example, for the expression x⁎⁎4 + xp.sqrt(y⁎⁎4), which contains the quadratic term y⁎⁎2, thefunction will return ([],[]).

Fair Isaac Corporation Conﬁdential and Proprietary Information

66

Reference Manualxpress.abs
Purpose
Synopsis

Returns the absolute value of a given expressiona = xpress.abs(t)Argumentt

Argument of the abs() function.

Further information
Python’s native abs operator is equivalent to xpress.abs for arguments that are functions ofvariables.

Fair Isaac Corporation Conﬁdential and Proprietary Information

67

Reference Manualxpress.acos
Purpose
Synopsis

Returns the arccosine of a given expression.
a = xpress.acos(t)Argumentt

Argument of the arccosine function.

Further information
Using Python’s math library operator math.acos is only advisable when the argument is not an
expression that depends on variables.
Related topics
xpress.sin, xpress.cos, xpress.tan, xpress.asin, xpress.atan.

Fair Isaac Corporation Conﬁdential and Proprietary Information

68Reference Manualxpress.addcbmsghandler
Purpose

Synopsis

Declares an output callback function in the global environment, called every time a line of message text
is output by any object in the library. This callback function will be called in addition to any output
callbacks already added by xpress.addcbmsghandler.
xpress.addcbmsghandler(msghandler, data, priority)
ret = f_msghandler(vObject, vUserContext, vSystemThreadId, sMsg, iMsgType,
iMsgNumber)Arguments
msghandler The callback function which takes six arguments, vObject, vUserContext,
vSystemThreadId, sMsg, iMsgType and iMsgNumber. Use None to cancel a
callback function.
vObject
The object sending the message.
vUserContext The user-deﬁned object passed to the callback function.
vSystemThreadId The system id of the thread sending the message cast to a void ⁎.
sMsg
A string containing the message, which may simply be a new line. When the callback iscalled for the ﬁrst time sMsg will be empty.
iMsgType
Indicates the type of output message:
1
information messages;
2(not used);3
warning messages;
4
error messages.
When the callback is called for the ﬁrst time iMsgType will be a negative value.
iMsgNumber The number associated with the message. If the message is an error or a warning then
you can look up the number in the section Optimizer Error and Warning Messages foradvice on what it means and how to resolve the associated issue.
data
A user-deﬁned object to be passed to the callback function.
priority
An integer that determines the order in which multiple message handler callbacks will
be invoked. The callback added with a higher priority will be called before a callbackwith a lower priority. Set to 0 if not required.
Further information
To send all messages to a log ﬁle the built in message handler logfilehandler can be used. Thiscan be done with:xpress.addcbmsghandler(logfilehandler, 'log.txt', 0)Related topics
xpress.removecbmsghandler.

Fair Isaac Corporation Conﬁdential and Proprietary Information

69

Reference Manualxpress.And
Purpose
Synopsis

Returns a logical AND of two or more binary variables or expressions.
xpress.And(variables)

Argument
variables
ExampleA list/array of binary variables or binary expressions

The following example shows how to use and to model various logical constraints:
N = 10x = xp.vars(N, vartype=xp.binary)# Creates N binary variablesc = [1, 4, 7, 3, 5, 7, 8, 4, 4, 9]
p = xp.problem(x)# Creates a problem with x, y

# Sets a linear objective
p.setObjective (xp.Sum(c[i] ⁎ x[i] for i in range(N))# Linear constraint
p.addConstraint (xp.Sum(x) <= 6)# Constrains the first x variable to be the conjunction of all other x's
p.addConstraint (x[0] == xp.And(x[1:]))# Forces the logical AND between some logical expressions to# be zero, i.e., at least one of them must be zerop.addConstraint (xp.And([x[1] | x[4], x[2] | x[1], x[3] | x[6]]) == 0)
Further information
1. For AND functions, all variables and expressions must be binary; an error will be generated otherwise.
2. A function call xpress.And(x1,x2,...,xk) is equivalent to x1 and (x2 and (x3 and ...
xk))...).
3. Note that since x1, x2, ..., xk, are binary variables, xpress.And(x1,x2,...,xk) is equivalent toxpress.min(x1,x2,...,xk).
Related topics
problem.addgencons, problem.delgencons, problem.getgencons, xpress.Or.

Fair Isaac Corporation Conﬁdential and Proprietary Information

70Reference Manualxpress.asin
Purpose
Synopsis

Returns the arcsine of a given expression.
a = xpress.asin(t)Argumentt

Argument of the arcsine function.

Further information
Using Python’s math library operator math.asin is only advisable when the argument is not an
expression that depends on variables.
Related topics
xpress.sin, xpress.cos, xpress.tan, xpress.acos, xpress.atan.

Fair Isaac Corporation Conﬁdential and Proprietary Information

71Reference Manualxpress.atan
Purpose
Synopsis

Returns the arctangent of a given expression.
a = xpress.atan(t)Argumentt

Argument of the arctangent function.

Further information
Using Python’s math library operator math.atan is only advisable when the argument is not an
expression that depends on variables.
Related topics
xpress.sin, xpress.cos, xpress.tan, xpress.asin, xpress.acos.

Fair Isaac Corporation Conﬁdential and Proprietary Information

72

Reference Manualxpress.cos
Purpose
Synopsis

Returns the cosine of a given expression.
a = xpress.cos(t)Argumentt

Argument of the cosine function.

Further information
Using Python’s math library operator math.cos is only advisable when the argument is not an
expression that depends on variables.
Related topics
xpress.sin, xpress.tan, xpress.asin, xpress.acos, xpress.atan.

Fair Isaac Corporation Conﬁdential and Proprietary Information73

Reference Manualxpress.Dot
Purpose

Synopsis

Alternative dot-product operator for an arbitrary number of NumPy single- or multi-dimensional arrays.
Following the convention for dot-product, the result of Dot for a list of k objects T1 , T2 , ..., Tk of
d1 , d2 , ..., dk dimensions is an object of d1 + d2 + ... + dk – 2(k – 1) dimensions. For each i-th factor in[1,2,...,k – 1], the arity of the last dimension of Ti must match the arity of the penultimate dimension of
Ti+1 (or its arity if Ti+1 is single-dimensional, i.e., a vector).
a = xpress.Dot(t1, t2, ..., out)

Argumentout
Example(optional) NumPy array of the correct dimension and arity where the result is stored. If notprovided, the dot product is returned.

The following code shows some possible uses of the Dot operator:
import numpy as np
import xpress as xp
N = 10M = 20S = range(N)x = np.array([xp.var() for i in S], dtype=xp.npvar)
x0 = np.random.random(N) # creates an N-vector of random numbers
p = xp.problem()# objective function is the squared Euclidean distance of the# variable vector x from a fixed point x0
p.setObjective(xp.Dot((x-x0),(x-x0)))
A = np.random.random((M,N))b = np.random.random(M)# constraint Ax = b, random MxN matrix A and M-vector bp.addConstraint(xp.Dot(A, x) == b)# Create a single quadratic constraint with
# a positive semidefinite matrix Q + N^3 ⁎ I
Q = np.random.random((N,N))p.addConstraint(xp.Dot(x, Q + N⁎⁎3 ⁎ np.eye(N), x) <= 1)# Create four quadratic constraints using an order-three# tensor, i.e., a three-dimensional array.
k = 4
T = np.random.random((k,N,N))q = np.random.random(k)p.addConstraint(xp.Dot(x, T, x) <= q)

Fair Isaac Corporation Conﬁdential and Proprietary Information

74

Reference Manual

Further information
From an operational standpoint, the dot product of k multi-dimensional arrays is the result of k – 1 dot
products of two factors each, and proceeds as in the following Python code:
result = T[0]for i in range(1,k):
result = xpress.Dot(result, T[i])The dot product of two multi-dimensional array T 0 and T 00 of dimensions d0 and d00 and of arities(n1 , n2 , ..., nd0 ) and (m1 , m2 , ..., md00 ), respectively, is a multi-dimensional array of dimension d0 + d00 – 2,
whose arity vector is (n1 , n2 , ..., nd0 –1 , m1 , m2 , ..., md00 –2 , md00 ) and whose generic element isP
vi1 ,i2 ,...,id0 –1 ,j1 ,j2 ,...,jd00 –2 ,jd00 = 1≤h≤n 0 ti0 ,i ,...,i 0 ,h · tj00 ,j ,...,j 00 ,h,j 00 .
d

1 2

d –1

1 2

d –2

d

It is assumed here that nd0 = md00 –1 . Two simple cases may help understand the behavior of theoperator: for two single-dimensional arrays v0 and v00 of size n, the result is the inner productP
000
1≤h≤n vh · vh .
For two matrices A and B of sizes m × n and n × p respectively, the result is the m × p matrix C whose
generic element isP
Cij = 1≤h≤n Aih · Bhj .
The Dot operator is functionally equivalent to Python’s dot operator from the NumPy package.
However, the Xpress Dot operator is the only one that can work on variables and expressions
containing variables.

Fair Isaac Corporation Conﬁdential and Proprietary Information

75Reference Manualxpress.erf
Purpose
Synopsis

Returns the error function with an expression as its argument.
a = xpress.erf(t)Argumentt

Argument of the function.

Further information
For reasons related to compilers and math libraries, on Windows machines this function can only be
used with Python 3.
Related topics
xpress.erfc.

Fair Isaac Corporation Conﬁdential and Proprietary Information76

Reference Manualxpress.erfc
Purpose
Synopsis

Returns the complementary error function with an expression as its argument.
a = xpress.erfc(t)Argumentt

Argument of the function.

Further information
For reasons related to compilers and math libraries, on Windows machines this function can only be
used with Python 3.
Related topics
xpress.erf.

Fair Isaac Corporation Conﬁdential and Proprietary Information

77Reference Manualxpress.evaluate
Purpose

Synopsis

Returns the evaluation of one or more expressions for a given assignment of values to optimization
variables.
v = xpress.evaluate(⁎args, problem=None, solution=None)

Argumentsargs

One or more objects to be evaluated. These can be variables, linear or nonlinear expressions;they can also be tuples, lists, dictionaries, or NumPy arrays of variables and expressions.
problem The xpress.problem object this function is referring to. If problem is not None, thensolution is either None (in which case the current solution is used) or it is to be intendedreferred to the indices of variables in problem. If problem is None, solution must provide
this information directly, i.e. it must be a dictionary mapping variable objects to their value
solution Either a list or NumPy array of values (in which case problem must not be None) or adictionary mapping variable objects to their value. As mentioned above, if it is None thenproblem must be passed and the assignment for the function is assumed to be the solution
as retrieved via problem.getSolution

Further information
1. Variables assignment do not have to correspond to a feasible solution.
2. At least one of the arguments problem and solution must be speciﬁed, because the objects in⁎args contain variables, and all variables could be used in zero or more problems. Only the following
cases are allowed:
3. problem=None and solution is a dictionary mapping variables to values; the dictionary must have a
key for each variable appearing in ⁎args;
4. problem is not None but solution=None; then solution is taken as the result of
problem.getSolution; this call is equivalent to p.getSolution(⁎args);
5. problem is not None and solution is either a list or a NumPy array; then the size of solution mustmatch the number of variables of problem and the order of values in the list/array is the same order inwhich the variables were added to problem.
ExampleThe following examples are valid uses of xpress.evaluate:
import xpress as xp
x = xp.var()y = xp.var(vartype=xp.binary)# Uses evaluate without a problem but by assigning the variables# explicitly. Note that the dictionary is necessary as no problem is# defined. The result should be [5.4, 124.71633781453677].
v1 = xp.evaluate([x + y, x⁎⁎3 - xp.cos(x)], solution={x:5, y:0.4})
p = xp.problem(x, y)# Create a problem and add variables x and y# Similar to the computation of v1 but with a vector of numbers; the# order in which the variables were added to p means that this x=2,
# y=3 here. The result should be {'exp1':11, 'exp2':6, 'exp3':9}.

Fair Isaac Corporation Conﬁdential and Proprietary Information

78

Reference Manual

v2 = xp.evaluate({'exp1':x + 3⁎y, 'exp2':x⁎y, 'exp3':y⁎⁎2},
problem=p, solution=[2,3])
p.addConstraint(x + y >= 3)
p.setObjective(x + 2⁎y)p.solve()l = np.array([x⁎⁎2 ⁎ y, x ⁎ y⁎⁎2, x⁎⁎3], dtype=xp.npexpr)# No solution is passed, so the solution of p as computed with solve()# above is used. It is easy to show that the solution is x=3, y=0, so# the result is np.array([0, 0, 27]).
v3 = xp.evaluate(l, problem=p)Related topics
problem.getSolution.

Fair Isaac Corporation Conﬁdential and Proprietary Information

79

Reference Manualxpress.examples
Purpose
Synopsis

Returns the full path to the directory of examples of the Xpress Python interface module.
xpress.examples()Further information
The mosel_examples/ subdirectory contains some of the Mosel examples translated into their
Python counterpart.

Fair Isaac Corporation Conﬁdential and Proprietary Information

80Reference Manualxpress.exp
Purpose
Synopsis

Returns the exponential of a given expression.
a = xpress.exp(t)Argumentt

Exponent.

Further information
Using Python’s math library operator math.exp is only advisable when the argument is not an
expression that depends on variables.

Fair Isaac Corporation Conﬁdential and Proprietary Information

81

Reference Manualxpress.featurequery
Purpose

Synopsis

Returns True if the provided feature is available in the current license used by the optimizer, False
otherwise.
xpress.featurequery(feature)

Argument
featureThe feature string to be checked in the license.

Fair Isaac Corporation Conﬁdential and Proprietary Information82

Reference Manualxpress.free
Purpose

Synopsis
ExampleReleases the Xpress environment, thus freeing up one license. The subsequent creation of a problem
automatically triggers a call to xpress.init.
Note that it is unnecessary to call this function upon exiting a block that uses the Xpress module, or
when the optimizer is no longer used, as Python will release the Xpress environment when freeing theXpress module. This function might be useful when a license is needed by another user or program,and one wishes to release the license.
xpress.free ()The following example shows how to call xpress.free and a possible use:x = xp.var()y = xp.var()p = xp.problem() # This would imply a call to xp.init()
p.addVariable(x, y)p.addConstraint(x+y <= 1)
p.setObjective(x+2⁎y, sense=xp.maximize)p.solve()
xp.free() # from this point on, the license# can be claimed by other users
Note that xpress.init is only useful when the user wants to claim a license that might be used byanother program or user.

Further information
Similar to a call to XPRSfree() of the C API, calling xpress.free cleans the Xpress environment.
Any problem created prior to a call to xpress.free is no longer available, and referring to it may leadto errors. For instance, the following code results in an aborted run:
import xpress
p = xpress.problem()
xpress.free()
xpress.init()
p.solve()
Related topics
xpress.init

Fair Isaac Corporation Conﬁdential and Proprietary Information

83Reference Manualxpress.getbanner
Purpose
Synopsis

Returns the banner and copyright message.
i = xpress.getbanner()

Exampleprint(xpress.getbanner())

Fair Isaac Corporation Conﬁdential and Proprietary Information

84

Reference Manualxpress.getcheckedmodePurpose

Synopsis

Returns whether checking & validation of all Optimizer function calls is enabled for the current process.
Checking & validation is enabled by default but can be disabled by xpress.setcheckedmode.
i = xpress.getcheckedmode()

Related topics
xpress.setcheckedmode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

85

Reference Manualxpress.getdaysleft
Purpose
Synopsis
ExampleReturns the number of days left until an evaluation license expires.
d = xpress.getdaysleft()
The following calls getdaysleft to print information about the license:try:
ndays = xpress.getdaysleft()
except RuntimeError:
print("Not an evaluation license")
else
print("Evaluation license expires in {0} days".format(ndays))

Further information
This function can only be used with evaluation licenses, and, if called when a normal license is in use, it
returns an error. The expiry information for evaluation licenses is also included in the Optimizer banner
message.

Fair Isaac Corporation Conﬁdential and Proprietary Information

86Reference Manualxpress.getlasterror
Purpose
Synopsis

Returns the last error encountered during a call to the Xpress global environment.
(i,s) = xpress.getlasterror()

ArgumentsisError code
Error message relating to the global environment will be returned.

Exampleimport xpress as xp# last error referring to the global environment
print(xp.getlasterror())

Fair Isaac Corporation Conﬁdential and Proprietary Information

87Reference Manualxpress.getlicerrmsg
Purpose
Synopsis
ExampleReturns the error message string describing the last licensing error, if any occurred.
m = xpress.getlicerrmsg()
The following calls getlicerrmsg to ﬁnd out why the import of the Xpress Python module failed:try:
import xpress
except RuntimeError:
print(xpress.getlicerrmsg())
else:
print("all good")

Fair Isaac Corporation Conﬁdential and Proprietary Information

88Reference Manualxpress.getversion
Purpose

Synopsis

Returns the full Optimizer version number as a string of the form 15.10.03, where 15 is the major
release, 10 is the minor release, and 03 is the build number.
v = xpress.getversion()

Exampleprint("Using Xpress Optimizer version", xpress.getversion())

Fair Isaac Corporation Conﬁdential and Proprietary Information

89

Reference Manualxpress.init
Purpose

Synopsis
ExampleInitializes the Xpress environment prior to creating or reading a problem.
Note that it is not necessary to call this function after importing the Xpress module and before creatingor solving a problem, as Python will claim a license automatically. This function might be useful when
the user wants to reserve a license and prevent that it is claimed by another user or program.
xpress.init()
The following example shows how to call xpress.init and why it could be useful:
xp.init() # reserves the license before creating variables
x = xp.var()y = xp.var()p = xp.problem() # This would imply a call to xp.init()
p.addVariable(x, y)p.addConstraint(x+y <= 1)
p.setObjective(x+2⁎y, sense=xp.maximize)p.solve()
Note that the call to xpress.init is not necessary and should only be made when the user wants toclaim a license that might be used by another program or user before the call to xpress.problem.

Related topics
xpress.free

Fair Isaac Corporation Conﬁdential and Proprietary Information

90Reference Manualxpress.log
Purpose
Synopsis

Returns the natural logarithm of a given expression.
a = xpress.log(t)Argumentt

Argument of the log function.

Further information
Using Python’s math library operator math.log is only advisable when the argument is not an
expression that depends on variables.

Fair Isaac Corporation Conﬁdential and Proprietary Information

91

Reference Manualxpress.log10
Purpose
Synopsis

Returns the base-10 logarithm of a given expression.
a = xpress.log10(t1)Argumentt

Argument.

Further information
Using Python’s math library operator math.log10 is only advisable when the argument is not an
expression that depends on variables.
Related topics
xpress.log.

Fair Isaac Corporation Conﬁdential and Proprietary Information

92

Reference Manualxpress.manual
Purpose
Synopsis

Returns the full path to the PDF reference manual of the Python interface.
xpress.manual()

Further information
Note that only the manual of the Python interface (in PDF format) is included in the PyPI and conda
package downloaded from these repositories; the PDF version of all other Xpress-related
documentation is contained in the Xpress distribution, and the on-line, HTML format documentation isavailable on the FICO web pages.

Fair Isaac Corporation Conﬁdential and Proprietary Information

93

Reference Manualxpress.max
Purpose
Synopsis

Returns the maximum of one or more expressions.
a = xpress.max(t1, t2, ..., tn)

Argument
t1, t2...

Arguments.

Further information
Using Python’s operator max is only advisable when the argument is not an expression that depends onvariables.
Related topics
xpress.min.

Fair Isaac Corporation Conﬁdential and Proprietary Information

94

Reference Manualxpress.min
Purpose
Synopsis

Returns the minimum of one or more expressions.
a = xpress.min(t1, t2, ..., tn)

Argument
t1, t2...

Arguments.

Further information
Using Python’s operator min is only advisable when the argument is not an expression that depends onvariables.
Related topics
xpress.max.

Fair Isaac Corporation Conﬁdential and Proprietary Information

95

Reference Manualxpress.Or
Purpose
Synopsis

Returns a logical OR of two or more binary variables or expressions.
xpress.Or(variables)

Argument
variables
ExampleA list/array of binary variables or binary expressions

The following example shows how to use or to model various logical constraints:
N = 10x = xp.vars(N, vartype=xp.binary)# Creates N binary variablesc = [1, 4, 7, 3, 5, 7, 8, 4, 4, 9]
p = xp.problem(x)# Creates a problem with x, y

# Sets a linear objective
p.setObjective (xp.Sum(c[i] ⁎ x[i] for i in range(N))# Linear constraint
p.addConstraint (xp.Sum(x) <= 6)# Constrains the first x variable to be the conjunction of all other x's
p.addConstraint (x[0] == xp.Or(x[1:]))# Forces the logical OR between some logical expressions to# be one, i.e., at least one of them must be one
p.addConstraint (xp.Or([x[1] & x[4], x[2] & x[1], x[3] & x[6]]) == 1)
Further information
1. For OR functions, all variables and expressions must be binary; an error will be generated otherwise.
2. A function call xpress.Or(x1,x2,...,xk) is equivalent to x1 or (x2 or (x3 or ...
xk))...).
3. Note that since x1, x2, ..., xk, are binary variables, xpress.Or(x1,x2,...,xk) is equivalent toxpress.max(x1,x2,...,xk).
Related topics
problem.addgencons, problem.delgencons, problem.getgencons, xpress.And.

Fair Isaac Corporation Conﬁdential and Proprietary Information

96

Reference Manualxpress.pwl
Purpose
Synopsis

Returns a piecewise linear function over a variable.
xpress.pwl(dict)Argument
dict

ExamplePython dictionary containing, as keys, two-elements tuples, and, as values, linear
expressions in a variable. If the piecewise linear function has only constantvalues (i.e. it is a piecewise constant function), the independent variable can be
speciﬁed with the key-value pair None: x.

The following example shows various usages of xpress.pwl to model nonlinear functions as
piecewise-linear functions :x = xp.var() # Nonnegative variabley = xp.var(lb=-xp.infinity) # dependent variable, unrestrictedt = xp.var()w = xp.var()p = xp.problem(x, y)# Sets a piecewise linear objective: a ramp function
p.setObjective (xp.pwl({(-xp.infinity, -1): -2,(-1, 1):2⁎x,(1, xp.infinity)]:2}))
p.addConstraint (t == xp.pwl({(1,2): 4⁎x, (2,4): 2, (4,5): -1}))# Piecewise CONSTANT function: add a key-value pair None: x to specify# independent variablep.addConstraint (t == xp.pwl({(1,2): 4, (2,4): 2, (4,5): -1, None: x}))p.addConstraint (xp.pwl({(-1,0): x, (0,1): 2⁎x, (1,10): 2}) <=xp.pwl({(0,10): 2⁎z, (10,20): z+2, (20,xp.infinity): 4}))Further information
1. A piecewise linear function must use only one variable in all of the dictionary’s values;
2. All values in the dictionary must be either constants or linear functions;3. The intervals, speciﬁed as two-element tuples in the dictionary’s keys, must be pairwise disjoint, i.e.,they must not overlap.
4. Discontinuities in the function are allowed, i.e., one can declare a function as follows: xp.pwl((1,2): 2⁎x + 4, (2,3): x - 1), which is obviously discontinuous at 2. The value of the function if
the optimal solution has x=2 will be then either 8 or 1.
Related topics
problem.addpwlcons, problem.delpwlcons, problem.getpwlcons.

Fair Isaac Corporation Conﬁdential and Proprietary Information

97

Reference Manualxpress.Prod
Purpose
Synopsis
ExampleReturns the product of a sequence of one or more expressions.
a = xpress.Prod(t1, t2, ...)
The following are allowed uses of the Prod operator:n = 10x = [xp.var() for i in range(n)]prod = xp.Prod(x)polynomial = xp.Sum(i ⁎ xp.Prod(x[i:i+4]) for i in range(n-4))

Further information
While n-ary product operators may exist in Python and/or NumPy, it is advisable to use xpress.Prod
when creating products of many expressions as it is the most efﬁcient alternative.

Fair Isaac Corporation Conﬁdential and Proprietary Information

98

Reference Manualxpress.removecbmsghandler
Purpose

Synopsis

Removes a message callback function previously added by xpress.addcbmsghandler. The
speciﬁed callback function will no longer be called after it has been removed.
xpress.removecbmsghandler(msghandler, data)

Arguments
msghandler The callback function to remove. If None then all message callback functions addedwith the given user-deﬁned object value will be removed.
data
The object value that the callback was added with. If None, then the object value will not
be checked and all message callbacks with the function msghandler will be removed.
Related topics
xpress.addcbmsghandler.

Fair Isaac Corporation Conﬁdential and Proprietary Information99

Reference Manualxpress.setarchconsistency
Purpose

Synopsis

Sets whether to force the same execution path on various CPU architecture extensions, in particular(pre-)AVX and AVX2.
xpress.setarchconsistency(ifArchConsistent=False)

Argument
ifArchConsistent

Whether to force the same execution path:
False Do not force the same execution path (default behavior);
True Force the same execution path.

Further information
Note that using this general environment API function is different from setting thexpress.controls.cpuplatform control. Setting this control selects a vectorization instruction set
for the barrier method.

Fair Isaac Corporation Conﬁdential and Proprietary Information

100Reference Manualxpress.setcheckedmodePurposeDisable/enable some of the checking & validation of function calls & function call parameters for calls
to the Xpress Optimizer API. This checking is relatively lightweight but disabling it can improve
performance in cases where non-intensive Xpress Optimizer functions are called repeatedly in a shortspace of time.
Please note: after disabling checking and validation for function calls, invalid usage of Xpress
Optimizer functions may not be detected and may cause the Xpress Optimizer process to behave
unexpectedly or crash. It is not recommended to disable function call checking & validation during
application development.

Synopsisxpress.setcheckedmode(checked_mode)

Argument
checked_mode

Pass as False or 0 to disable much of the validation for all Xpress function callsfrom the current process. Pass True or 1 to re-enable validation. By default,
validation is enabled.

Related topics
xpress.getcheckedmode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

101Reference Manualxpress.setdefaults
Purpose

Synopsis
ExampleSets the module’s controls to their default values. This affects all problems created after calling
setdefaults, not before.
xpress.setdefaults()
The following creates two problems, one before and one after calling setdefaults():
xpress.controls.presolve = 0
p1 = xpress.problem()
xpress.setdefaults()
p2 = xpress.problem()print('Check p1.controls.presolve is 0:', p1.controls.presolve)
print('Check p2.controls.presolve is its default:', p2.controls.presolve)

Related topics
xpress.setdefaultcontrol, problem.setdefaults, problem.setdefaultcontrol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

102

Reference Manualxpress.setdefaultcontrol
Purpose

Synopsis

Sets one of the module’s controls to its default values. This affects all problems created after calling
setdefaults, not before.
xpress.setdefaultcontrol(control)

Argument
control
ExampleName of the control to be set to default.

The following creates two problems, one before and one after calling
setdefaultcontrol(xpress.presolve):
xpress.controls.presolve = 0
p1 = xpress.problem()
xpress.setdefaultcontrol('presolve')p2 = xpress.problem()print('I bet p1.controls.presolve is 0:', p1.controls.presolve)
print('I bet p2.controls.presolve is its default:', p2.controls.presolve)

Related topics
xpress.setdefaults, problem.setdefaults, problem.setdefaultcontrol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

103

Reference Manualxpress.sign
Purpose
Synopsis

Returns the sign of an expression: 1 if positive, -1 if negative, 0 if zero.
a = xpress.sign(t)Argumentt

Argument of the sign function.

Fair Isaac Corporation Conﬁdential and Proprietary Information

104

Reference Manualxpress.sin
Purpose
Synopsis

Returns the sine of a given expression.
a = xpress.sin(t)Argumentt

Argument of the sine function.

Further information
Using Python’s math library operator math.sin is only advisable when the argument is not an
expression that depends on variables.
Related topics
xpress.cos, xpress.tan, xpress.asin, xpress.acos, xpress.atan.

Fair Isaac Corporation Conﬁdential and Proprietary Information

105

Reference Manualxpress.sqrt
Purpose
Synopsis

Returns the square root of an expression.
a = xpress.sqrt(t)Argumentt

Radicand of the function.

Further information
Using Python’s math library operator math.sqrt is only advisable when the argument is not an
expression that depends on variables.

Fair Isaac Corporation Conﬁdential and Proprietary Information

106

Reference Manualxpress.Sum
Purpose

Synopsis
ExampleAlternative sum operator for an arbitrary number of objects created by a list, tuple, generator, NumPy
array, dictionary, etc.
a = xpress.Sum(t1, t2, ...)
The following are allowed uses of the Sum operator:
import math
N = 20S = range(S)x = [xpress.var() for i in S]
y = [xpress.var(vartype=xpress.binary) for i in S]
p = xpress.problem()p.addVariable(x, y)p.setObjective(x[0] + xpress.Sum(x[i]⁎⁎2 for i in S))
p.addConstraint(xpress.Sum(x,y) <= 100)p.addConstraint(xpress.Sum(x[:i]) + xpress.Sum(y[:i])<= math.log(10 + i) for i in S)

Further information
The Sum operator is functionally equivalent to Python’s native sum operator. However, it is strongly
advised to use the Xpress’ Sum operator when constructing large expressions involving variables, as
doing otherwise might slow down the execution signiﬁcantly.

Fair Isaac Corporation Conﬁdential and Proprietary Information

107

Reference Manualxpress.tan
Purpose
Synopsis

Returns the tangent of a given expression.
a = xpress.tan(t)Argumentt

Argument of the tangent function.

Further information
Using Python’s math library operator math.tan is only advisable when the argument is not an
expression that depends on variables.
Related topics
xpress.sin, xpress.cos, xpress.asin, xpress.acos, xpress.atan.

Fair Isaac Corporation Conﬁdential and Proprietary Information

108

Reference Manualxpress.user
Purpose

SynopsisCreates an expression that is computed by means of a user-speciﬁed function. The user function canbe deﬁned to either provide or not provide the value of all derivatives w.r.t. the variables.
def f(a1, a2, ..., an):[...]a = xpress.user(f, t1, t2, ..., tn, derivatives=False)

Argumentsft1,...,tn
derivatives
ExampleUser function; must be a Python function with as many (possibly optional)
arguments as speciﬁed in the declaration.
Arguments of the user function.
True if f returns the derivatives w.r.t. all variables, False otherwise.

The following code shows how to deﬁne user functions and use them in an optimization problem:
import mathdef mynorm(v):return math.sqrt(sum(v[i] for i in range(len(v)))
def weighted_sum(t1, t2, t3=0):
return (2⁎t1 + 3⁎t2 + 4⁎t1⁎t3,
2 + 4⁎t3, 3, 4⁎t1)
x = [xp.var() for i in range(20)]
f1 = xp.user(mynorm, x)
f2 = xp.user(weighted_sum, x[0], x[1], x[2], derivative=True)# Doesn't use optional arg
f3 = xp.user(weighted_sum, x[0], x[1], derivative=True)
p = xp.problem()p.addVariable(x)p.addConstraint(f3 <= 4)p.setVariable(f1)p.solve()

Further information
User functions must return a Float, as the behaviour is otherwise undeﬁned. If the derivatives
parameter (which is False by default) is set to True, then the function must return a tuple consistingof the objective function value and the derivatives of the function w.r.t. all variables in the list ofarguments. If derivatives=False, then the function must return a single ﬂoat, i.e. the function
value.

Fair Isaac Corporation Conﬁdential and Proprietary Information

109

Reference Manualxpress.vars
Purpose

SynopsisCreates an indexed set or map of variables. Similar to the creation of a single variable withxpress.var, vars allows for using one or more index sets, speciﬁed as sets, lists, range objects, or
any iterable object. Specifying a number k as an argument is equivalent to range(k) but can be used
to create NumPy multiarrays of variables, and allows for more efﬁcient creation. The result is otherwisea Python dictionary of variables, whose keys are tuple of indices. A collection of variables x that iscreated with vars can be indexed, for instance, as x[i,j] where i and j are indices in the lists
provided.
x = xpress.vars(⁎indices, name="x", lb=0, ub=xpress.infinity, threshold=0,vartype=xpress.continuous)

Arguments
indices

namelbub
thresholdvartype
ExampleOne or more lists, sets, ranges, or iterable objects to be combined; in alternative, one
can specify one or more numbers k to signify the range 0..k-1. Using only numbers asargument will yield a NumPy multiarray with the dimensions as speciﬁed by thearguments themselves.
Preﬁx name for each variable, to be amended with the tuple of indices.
Lower bound for all variables in the map.
Upper bound for all variables in the map.
Threshold for all variables in the map; only used if the variables are partially integer.
Type of all variables in the map, similar to the deﬁnition of single variables.

The following creates a variable map with 6 variables whose indices vary in the set(0,’a’),(0,’b’),(0,’c’),(1,’a’),(1,’b’),(1,’c’):x = xpress.vars([0,1],['a','b','c'])
The following creates a variable map with 6 variables whose indices vary in the set(0,0),(0,1),(0,2),(1,0),(1,1),(1,2):x = xpress.vars(2,3)
The code below creates a variable map with 5 integer variables with names ’y(a)’, ’y(b)’,’y(c)’, ’y(d)’, ’y(e)’ and creates a constraint to bound their sum:x = xpress.vars(['a','b','c','d','e'],name='y', vartype=xpress.integer)con1 = xpress.Sum(x) <= 4
The code below creates a variable map using the range operator in Python:x = xpress.vars(range(5),name='y', vartype=xpress.integer)con1 = xpress.Sum(x) <= 4
The following example creates a Numpy multiarray of dimensions 3,7,4 with default (i.e.,interface-provided) names:x = xpress.vars(3,7,4, name="", lb=-1, ub=1)
Note that specifying anything other than a number yields a dictionary rather than a Numpy multiarray.
The above mode can be used when creating large arrays of variables because specifying name=""allows for more efﬁcient creation. Finally, the following creates a variable indexed by the set deﬁned
right before:

Fair Isaac Corporation Conﬁdential and Proprietary Information

110Reference Manual

S = set()S.add('john')
S.add('cleese')x = xpress.vars(S, name='y', vartype=xpress.integer)
Further information
All lists must contain non-repeated elements to avoid having variables with equal names. If a list in theargument is, for instance, [’a’,’b’,’a’], an error is returned.
Related topics
xpress.var

Fair Isaac Corporation Conﬁdential and Proprietary Information

111

Reference Manual

problem.addcbbariteration
Purpose

Synopsis

Declares a barrier iteration callback function, called after each iteration during the interior point
algorithm, with the ability to access the current barrier solution/slack/duals or reduced cost values, andto ask barrier to stop. This callback function will be called in addition to any callbacks already added by
addcbbariteration.
problem.addcbbariteration(callback, data, priority)
barrier_action = callback(my_prob, my_object)Arguments
callback

The callback function itself. This takes two arguments, my_prob and my_object, andreturns an integer return value. This function is called at every barrier iteration.
my_prob
The problem passed to the callback function, fubi.
my_object The user-deﬁned object passed as object when setting up the callback withaddcbbariteration.
barrier_action Deﬁnes a return value controlling barrier:<0
continue with the next iteration;=0
let barrier decide (use default stopping criteria)
1barrier stops with status not deﬁned;
2
barrier stops with optimal status;
3
barrier stops with dual infeasible status;
4barrier stops wih primal infeasible status;
data
A user-deﬁned object to be passed to the callback function, f_bariteration.
priority
An integer that determines the order in which callbacks of this type will be invoked. The
callback added with a higher priority will be called before a callback with a lower priority.
Set to 0 if not required.

ExampleThis simple example demonstrates how the solution might be retrieved for each barrier iteration.
# Barrier iteration callback
def BarrierIterCallback(my_prob, my_object):current_iteration = my_prob.attributes.bariter
PrimalObj = my_prob.attributes.barprimalobj
DualObj= my_prob.attributes.bardualobj
Gap = DualObj - PrimalObj
PrimalInf= my_prob.attributes.barprimalinf
DualInf= my_prob.attributes.bardualinf
ComplementaryGap = my_prob.attributes.barcgap# decide if stop or continue
barrier_action = 0
if(current_iteration >= 50 or
Gap <= 0.1 ⁎ max(abs(PrimalObj), abs(DualObj))):barrier_action = 2
return barrier_action

Fair Isaac Corporation Conﬁdential and Proprietary Information

112

Reference Manual# To set callback:prob.addcbbariteration(BarrierIterCallback, myobj, 0)
Further information
1. Only the following functions are expected to be called from the callback: problem.getlpsol and theattribute/control value retrieving and setting routines.
2. Please note that these values refer to the scaled and presolved problem used by barrier, and may differ
from the ones calculated from the postsolved solution returned by problem.getlpsol.
Related topics
problem.removecbbariteration.

Fair Isaac Corporation Conﬁdential and Proprietary Information

113

Reference Manual

problem.addcbbarlog
Purpose

Synopsis

Declares a barrier log callback function, called at each iteration during the interior point algorithm. This
callback function will be called in addition to any barrier log callbacks already added by addcbbarlog.
problem.addcbbarlog(callback, data, priority)
ret = callback(my_prob, my_object)Arguments
callback

my_prob
my_object
data
priority

ExampleThe callback function itself. This takes two arguments, my_prob and my_object, andhas an integer return value. If the value returned by callback is nonzero, the solution
process will be interrupted. This function is called at every barrier iteration.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbbarlog.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple barrier log callbacks will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

This simple example prints a line to the screen for each iteration of the algorithm.
prob.addcbbarlog(barLog, None, 0)prob.lpoptimize('b')
The callback function might resemble:
def barLog(prob, object):print('Next barrier iteration')

Further information
If the callback function returns a nonzero value, the Optimizer run will be interrupted.
Related topics
problem.removecbbarlog, problem.addcbgloballog, problem.addcblplog,
problem.addcbmessage.

Fair Isaac Corporation Conﬁdential and Proprietary Information

114

Reference Manual

problem.addcbchecktime
Purpose

Synopsis

Declares a callback function which is called every time the Optimizer checks if the time limit has beenreached. This callback function will be called in addition to any callbacks already added by
addcbchecktime.
problem.addcbchecktime(callback, data, priority) ret = callback(prob, data)

Arguments
prob
callback

prob
data
priority

The current problem.
The callback function which takes two arguments, prob and data, and has an integer
return value. This function is called every time the Optimizer checks against the time
limit.
The problem passed to the callback function, callback.
The user-deﬁned object passed as data when setting up the callback withaddcbchecktime.
An integer that determines the order in which multiple checktime callbacks will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

Further information
If the callback function returns a nonzero value the solution process will be interrupted.
Related topics
problem.removecbchecktime.

Fair Isaac Corporation Conﬁdential and Proprietary Information

115

Reference Manual

problem.addcbchgbranchobject
Purpose

Synopsis

Declares a callback function that will be called every time the Optimizer has selected a global entity forbranching. Allows the user to inspect and override the Optimizer’s branching choice. This callback
function will be called in addition to any callbacks already added byproblem.addcbchgbranchobject.
problem.addcbchgbranchobject(callback, data, priority)
newobject = callback(my_prob, my_object, obranch)

Arguments
callback

my_prob
my_objectobranchnewobject
data
priority

The callback function, which takes three arguments: my_prob, my_object, andobranch. This function is called every time the Optimizer has selected a candidate
entity for branching.
The problem passed to the callback function, callback.
The user deﬁned object passed as object when setting up the callback withaddcbchgbranchobject.
The candidate branching object selected by the Optimizer.
New branching object to replace the Optimizer’s selection. Can be None.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple callbacks of this type will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

Further information
1. The branching object given by the Optimizer provides a linear description of how the Optimizer intends
to branch on the selected candidate. This will often be one of standard global entities of the current
problem, but can also be e.g. a split disjunction or a structural branch, if those features are turned on.
2. The functions branchobj.getbranches, branchobj.getbounds and branchobj.getrows canbe used to inspect the given branching object.
3. Refer to the branchobj class to learn how to create a new branching object to replace the Optimizer’s
selection. Note that the new branching object should be created with a priority value no higher than thecurrent object to guarantee it will be used for branching.
Related topics
problem.removecbchgbranchobject.

Fair Isaac Corporation Conﬁdential and Proprietary Information

116

Reference Manual

problem.addcbcutlog
Purpose

Synopsis

Declares a cut log callback function, called each time the cut log is printed. This callback function will
be called in addition to any callbacks already added by problem.addcbcutlog.
problem.addcbcutlog(callback, data, priority)
ret = callback(my_prob, my_object)Arguments
callback
my_prob
my_object
data
priority

The callback function which takes two arguments, my_prob and my_object, and has
an integer return value.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbcutlog.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple cut log callbacks will be invoked.
The callback added with a higher priority will be called before a callback with a lower
priority. Set to 0 if not required.

Further information
The callback callback should return a non-zero value to stop cutting on the current node.
Related topics
problem.removecbcutlog.

Fair Isaac Corporation Conﬁdential and Proprietary Information

117

Reference Manual

problem.addcbdestroymt
Purpose

Synopsis

Declares a callback function that is called every time a MIP thread is destroyed by the parallel MIP code.
This callback function will be called in addition to any callbacks already added by addcbdestroymt.
problem.addcbdestroymt(callback, data, priority)
callback(my_prob, my_object)Arguments
callback
my_prob
my_object
data
priority

The callback function which takes two arguments, my_prob and my_object, and has
no return value.
The thread problem passed to the callback function.
The user-deﬁned object passed as object when setting up the callback withaddcbdestroymt.
A user-deﬁned object to be passed to the callback function.
An integer that determines the order in which multiple callbacks of this type will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

Further information
This callback is useful for freeing up any user data created in the MIP thread callback.
Related topics
problem.removecbdestroymt, problem.addcbmipthread.

Fair Isaac Corporation Conﬁdential and Proprietary Information

118

Reference Manual

problem.addcbgapnotify
Purpose

Synopsis

Declares a gap notiﬁcation callback, to be called when a MIP solve reaches a predeﬁned target, set
using the miprelgapnotify, mipabsgapnotify, mipabsgapnotifyobj, and/or
mipabsgapnotifybound controls.
problem.addcbgapnotify(callback, data, priority)(RelGapNotify, AbsGapNotify, AbsGapNotifyObj, AbsGapNotifyBound) =callback(my_prob, my_object)Arguments
callback
objectpriority

The callback function.
A user-deﬁned object that wil be passed into the callback callback.
An integer that determines the order in which multiple gap notiﬁcation callbacks will be
invoked. The callback added with the higher priority will be called before a callback witha lower priority. Set to 0 if not required.
my_prob
The current problem.
my_object The user-deﬁned object passed as object when setting up the callback withaddcbgapnotify.
RelGapNotify The value the miprelgapnotify control will be set to after this callback. May be
modiﬁed within the callback in order to set a new notiﬁcation target.
AbsGapNotify The value the mipabsgapnotify control will be set to after this callback. May be
modiﬁed within the callback in order to set a new notiﬁcation target.
AbsGapNotifyObj The value the mipabsgapnotifyobj control will be set to after this callback.
May be modiﬁed within the callback in order to set a new notiﬁcation target.
AbsGapNotifyBound The value the mipabsgapnotifybound control will be set to after thiscallback. May be modiﬁed within the callback in order to set a new notiﬁcation target.
data
A user-deﬁned object to be passed to the callback function, callback.
priority
An integer that determines the order in which multiple estimate callbacks will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

ExampleThe following example prints a message when the gap reaches 10% and 1%
def gapnotify(prob, object):obj = prob.attributes.mipobjval
bound = prob.attributes.bestboundrelgap = abs((obj - bound) / obj)
newRelGapNotifyTarget = -1
if relgap <= 0.1:
print('Gap reached 10%')
newRelGapNotifyTarget = 0.1
if relgap <= 0.01:
print('Gap reached 1%')
newRelGapNotifyTarget = -1 # Don't call gapnotify again

Fair Isaac Corporation Conﬁdential and Proprietary Information

119

Reference Manual# return a quadruple with new values, or# None for those that should not be set
return (newRelGapNotifyTarget, None, None, None)prob.controls.miprelgapnotify = 0.1
prob.addcbgapnotify(gapnotify, None, 0)prob.mipoptimize('')
Further information
The target values that caused the callback to be triggered will automatically be reset to prevent thesame callback from being ﬁred again.
Related topics
MIPRELGAPNOTIFY, MIPABSGAPNOTIFY, MIPABSGAPNOTIFYOBJ, MIPABSGAPNOTIFYBOUND,
problem.removecbgapnotify.

Fair Isaac Corporation Conﬁdential and Proprietary Information

120

Reference Manual

problem.addcbgloballog
Purpose

Synopsis

Declares a global log callback function, called each time the global log is printed. This callback function
will be called in addition to any callbacks already added by addcbgloballog.
problem.addcbgloballog(callback, data, priority)
ret = callback(my_prob, my_object)Arguments
callback

my_prob
my_object
data
priority

ExampleThe callback function which takes two arguments, my_prob and my_object, and has
an integer return value. This function is called whenever the global log is printed asdetermined by the MIPLOG control.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbgloballog.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple global log callbacks will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

The following example prints at each node of the global search the node number and its depth:
prob.controls.miplog = 3
prob.addcbgloballog(globalLog, None, 0)prob.mipoptimize('')
The callback function may resemble:
def globalLog(prob, object):
nodedepth = prob.attributes.nodedepth
node= prob.attributes.currentnode
print('Node {0} with depth {1} has been processed'.format(node, nodedepth))
return 0

Further information
If the callback function returns a nonzero value, the global search will be interrupted.
Related topics
problem.removecbgloballog, problem.addcbbarlog, problem.addcblplog,
problem.addcbmessage.

Fair Isaac Corporation Conﬁdential and Proprietary Information

121

Reference Manual

problem.addcbinfnode
Purpose

Synopsis

Declares a user infeasible node callback function, called after the current node has been found to be
infeasible during the Branch and Bound search. This callback function will be called in addition to any
callbacks already added by addcbinfnode.
problem.addcbinfnode(callback, data, priority)
callback(my_prob, my_object)Arguments
callback

my_prob
my_object
data
priority

ExampleThe callback function which takes two arguments, my_prob and my_object, and has
no return value. This function is called after the current node has been found to be
infeasible.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbinfnode.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple user infeasible node callbacks
will be invoked. The callback added with a higher priority will be called before a callbackwith a lower priority. Set to 0 if not required.

The following notiﬁes the user whenever an infeasible node is found during the global search:prob.addcbinfnode(nodeInfeasible, None, 0)prob.mipoptimize("")
The callback function may resemble:
def nodeInfeasible(prob, object):node = prob.attributes.currentnode
print("Node {0} infeasible".format(node))

Related topics
problem.removecbinfnode, problem.addcboptnode, problem.addcbintsol,
problem.addcbnodecutoff.

Fair Isaac Corporation Conﬁdential and Proprietary Information

122

Reference Manual

problem.addcbintsol
Purpose

Synopsis

Declares a user integer solution callback function, called every time an integer solution is found byheuristics or during the Branch and Bound search. This callback function will be called in addition to
any callbacks already added by addcbintsol.
problem.addcbintsol(callback, data, priority)
callback(my_prob, my_object)Arguments
callback

my_prob
my_object
data
priority

ExampleThe callback function which takes two arguments, my_prob and my_object, and has
no return value. This function is called if the current node is found to have an integer
feasible solution, i.e. every time an integer feasible solution is found.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbintsol.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple integer solution callbacks will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

The following example prints integer solutions as they are discovered in the global search:prob.addcbintsol(printsol, None, 0)prob.mipoptimize("")
The callback function might resemble:
def printsol(my_prob, object):cols = my_prob.attributes.originalcols
objval = my_prob.attributes.lpobjval
x = []
my_prob.getlpsol(x, None, None, None)
print("Integer solution found:", objval, "; values:")
print(x)Further information
1. This callback is useful if the user wants to retrieve the integer solution when it is found.
2. To retrieve the integer solution, use either problem.getlpsol or problem.getpresolvesol.
problem.getmipsol always returns the last integer solution found and, if called from the intsol
callback, it will not necessarily return the solution that caused the invocation of the callback (forexample, it is possible that when solving with multiple MP threads, another thread ﬁnds a new integer
solution before the user calls problem.getmipsol).
3. This callback is called after a new integer solution was found by the Optimizer. Use a callback set byproblem.addcbpreintsol in order to be notiﬁed before a new integer solution is accepted by the
Optimizer, which allows for the new solution to be rejected.
Related topics
problem.removecbintsol, problem.addcbpreintsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

123

Reference Manual

problem.addcblplog
Purpose

Synopsis

Declares a simplex log callback function which is called after every LPLOG iterations of the simplex
algorithm. This callback function will be called in addition to any callbacks already added by
addcblplog.
problem.addcblplog(callback, data, priority)
ret = callback(my_prob, my_object)Arguments
callback

my_prob
my_object
data
priority

ExampleThe callback function which takes two arguments, my_prob and my_object, and has
an integer return value. This function is called every LPLOG simplex iterations including
iteration 0 and the ﬁnal iteration.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcblplog.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple lplog callbacks will be invoked.
The callback added with a higher priority will be called before a callback with a lower
priority. Set to 0 if not required.

The following code sets a callback function, lpLog, to be called every 10 iterations of the optimization:
prob.controls.lplog = 10
prob.addcblplog(lpLog, None, 0)prob.read("problem", "")prob.mipoptimize("")
The callback function may resemble:
def lpLog(my_prob, object):iter = my_prob.attributes.simplexiter
obj = my_prob.attributes.lpobjval
print("At iteration {0} objval is {1}".format(iter, obj))
return 0

Further information
If the callback function returns a nonzero value, the solution process will be interrupted.
Related topics
problem.removecblplog, problem.addcbbarlog, problem.addcbgloballog,
problem.addcbmessage.

Fair Isaac Corporation Conﬁdential and Proprietary Information

124

Reference Manual

problem.addcbmessage
Purpose

Synopsis

Declares an output callback function, called every time a text line relating to the given prob is output by
the Optimizer. This callback function will be called in addition to any callbacks already added by
addcbmessage.
problem.addcbmessage(callback, data, priority)
callback(my_prob, my_object, msg, msgtype)

Arguments
callback
my_prob
my_objectmsg
msgtypedata
priority

ExampleThe callback function which takes ﬁve arguments, my_prob, my_object, msg, len andmsgtype, and has no return value. Use a None value to cancel a callback function.
The problem passed to the callback function.
The user-deﬁned object passed as object when setting up the callback withaddcbmessage.
A null terminated character array (string) containing the message, which may simply bea new line.
Indicates the type of output message:
1
information messages;
2(not used)3
warning messages;
4
error messages.
A negative value indicates that the Optimizer is about to ﬁnish and the buffers should be
ﬂushed at this time if the output is being redirected to a ﬁle.
A user-deﬁned object to be passed to the callback function.
An integer that determines the order in which callbacks of this type will be invoked. The
callback added with a higher priority will be called before a callback with a lower priority.
Set to 0 if not required.

The following example simply sends all output to the screen (stdout):
prob.addcbmessage(Message, None, 0)
The callback function might resemble:
def Message(my_prob, object, msg, msgtype):
print('{0}: {1}'.format(msgtype, msg))

Further information
1. Screen output is automatically created by the Optimizer Console only. To produce output when using
the Optimizer library, it is necessary to deﬁne this callback function and use it to print the messages tothe screen (stdout).
2. This function offers one method of handling the messages which describe any warnings and errorsthat may occur during execution. Other methods are to check the return values of functions and thenget the error code using the errorcode attribute, obtain the last error message directly using
problem.getlasterror, or send messages direct to a log ﬁle using problem.setlogfile.
Related topics
problem.removecbmessage, problem.addcbbarlog, problem.addcbgloballog,
problem.addcblplog, problem.setlogfile.

Fair Isaac Corporation Conﬁdential and Proprietary Information

125Reference Manual

problem.addcbmipthread
Purpose

Synopsis

Declares a MIP thread callback function, called every time a MIP worker problem is created by theparallel MIP code. This callback function will be called in addition to any callbacks already added by
addcbmipthread.
problem.addcbmipthread(callback, data, priority)
callback(my_prob, my_object, thread_prob)

Arguments
callback

The callback function which takes three arguments, my_prob, my_object andthread_prob, and has no return value.
my_prob
The problem passed to the callback function.
my_object The user-deﬁned object passed to the callback function.
thread_prob The problem for the MIP threaddata
A user-deﬁned object to be passed to the callback function.
priority
An integer that determines the order in which multiple callbacks of this type will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

ExampleThe following example clears the message callback for each of the MIP threads:
prob.addcbmipthread(mipthread, None, 0)
def mipthread(my_prob, my_object, mipthread):my_prob.removecbmessage(mipthread, None)

Further information
This function will be called when a new MIP worker problem is created. Each worker problem receives aunique identiﬁer that can be obtained through the MIPTHREADID attribute. Worker problems can bematched with different system threads at different points of a solve, so the system thread that is
responsible for executing the callback is not necessarily the same thread used for all subsequentcallbacks for the same worker problem. On the other hand, worker problems are always assigned to asingle thread at a time and the same nodes are always solved on the same worker problem in repeatedruns of a deterministic MIP solve. A worker problem therefore acts as a virtual thread through the node
solves.
Related topics
problem.removecbmipthread, problem.addcbdestroymt.

Fair Isaac Corporation Conﬁdential and Proprietary Information

126

Reference Manual

problem.addcbnewnode
Purpose

Synopsis

Declares a callback function that will be called every time a new node is created during the branch andbound search. This callback function will be called in addition to any callbacks already added by
addcbnewnode.
problem.addcbnewnode(callback, data, priority)
callback(my_prob, my_object, parentnode, newnode, branch)

Arguments
callback

The callback function, which takes ﬁve arguments: myprob, my_object, parentnode,
newnode and branch. This function is called every time a new node is created throughbranching.
my_prob
The problem passed to the callback function, callback.
my_object The user-deﬁned object passed as object when setting up the callback withaddcbnewnode.
parentnode Unique identiﬁer for the parent of the new node.
newnodeUnique identiﬁer assigned to the new node.
branchThe sequence number of the new node amongst the child nodes of parentnode. For
regular branches on a global entity this will be either 0 or 1.
data
A user-deﬁned object to be passed to the callback function.
priority
An integer that determines the order in which callbacks of this type will be invoked. The
callback added with a higher priority will be called before a callback with a lower priority.
Set to 0 if not required.

Further information
1. For regular branches on a global entity, branch will be either zero or one, depending on whether the
new node corresponds to branching the global entity up or down.
2. When branching on a branchobject, branch refers to the given branch index of the object.
Related topics
problem.removecbnewnode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

127

Reference Manual

problem.addcbnodecutoff
Purpose

Synopsis

Declares a user node cutoff callback function, called every time a node is cut off as a result of an
improved integer solution being found during the branch and bound search. This callback function will
be called in addition to any callbacks already added by addcbnodecutoff.
problem.addcbnodecutoff(callback, data, priority)
callback(my_prob, my_object, node)

Arguments
callback

my_prob
my_object
node
data
priority

ExampleThe callback function, which takes three arguments, my_prob, my_object and node,and has no return value. This function is called every time a node is cut off as the resultof an improved integer solution being found.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbnodecutoff.
The number of the node that is cut off.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple node-optimal callbacks will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

The following notiﬁes the user whenever a node is cutoff during the global search:prob.addcbnodecutoff(Cutoff, None, 0)
mipoptimize(prob, "")The callback function might resemble:
def Cutoff(prob, object, node):
print("Node {0} cutoff".format(node))

Further information
This function allows the user to keep track of the eligible nodes. Note that the LP solution will not be
available from this callback.
Related topics
problem.removecbnodecutoff, problem.addcboptnode, problem.addcbinfnode,
problem.addcbintsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

128

Reference Manual

problem.addcboptnode
Purpose

Synopsis

Declares an optimal node callback function, called during the branch and bound search, after the LP
relaxation has been solved for the current node, and after any internal cuts and heuristics have been
applied, but before the Optimizer checks if the current node should be branched. This callback function
will be called in addition to any callbacks already added by addcboptnode.
problem.addcboptnode(callback, data, priority)
feas = callback(my_prob, my_object)Arguments
callback
my_prob
my_objectfeas
data
priority

ExampleThe callback function which takes three arguments, my_prob, my_object and feas,and has no return value.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcboptnode.
The feasibility status. If set to a nonzero value by the user, the current node will bedeclared infeasible.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple node-optimal callbacks will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

The following prints the optimal objective value of the node LP relaxations:prob.addcboptnode(nodeOptimal, None, 0)prob.mipoptimize("")
The callback function might resemble:
def nodeOptimal(prob, object):node = prob.attributes.currentnode
print("NodeOptimal: node number", node)
objval = prob.attributes.lpobjval
print("Objective function value =", objval)
return 0

Related topics
problem.removecboptnode, problem.addcbinfnode, problem.addcbintsol,
problem.addcbnodecutoff, CALLBACKCOUNT_OPTNODE.

Fair Isaac Corporation Conﬁdential and Proprietary Information

129

Reference Manual

problem.addcbpreintsol
Purpose

Synopsis

Declares a user integer solution callback function, called when an integer solution is found by heuristics
or during the branch and bound search, but before it is accepted by the Optimizer. This callback
function will be called in addition to any integer solution callbacks already added by addcbpreintsol.
problem.addcbpreintsol(callback, data, priority)(ifreject, newcutoff) = callback(my_prob, my_object, soltype, cutoff)

Arguments
callback

my_prob
my_objectsoltypeifrejectcutoffnewcutoff
data
priority

The callback function which takes ﬁve arguments, my_prob, my_object,isheuristic, ifreject and cutoff, and has no return value. This function is called
when an integer solution is found, but before the solution is accepted by the Optimizer,
allowing the user to reject the solution.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbpreintsol.
The type of MIP solution that has been found: Set to 1 if the solution was found using aheuristic. Otherwise, it will be the global feasible solution to the current node of the
global search.
0
The continuous relaxation solution to the current node of the global search,which has been found to be global feasible.
1
A MIP solution found by a heuristic.
2
A MIP solution provided by the user.
3
A solution resulting from reﬁnement of primal or dual violations of a previous
MIP solution.
Set this to 1 if the solution should be rejected.
The current cutoff value.
The new cutoff value, to be used by the Optimizer if the solution is accepted. The
returned newcutoff value will not be updated if the solution is rejected.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which callbacks of this type will be invoked. The
callback added with a higher priority will be called before a callback with a lower priority.
Set to 0 if not required.

Further information
1. If a solution is rejected, the Optimizer will drop the found solution without updating any attributes,
including the cutoff value. To change the cutoff value when rejecting a solution, the control
MIPABSCUTOFF should be set instead.
2. When a node solution is rejected (isheuristic = 0), the node itself will be dropped without further
branching.
3. To retrieve the integer solution, use either problem.getlpsol or problem.getpresolvesol.
problem.getmipsol will not return the newly found solution because it has not been saved at thispoint.
Related topics
problem.removecbpreintsol, problem.addcbintsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

130Reference Manual

problem.addcbprenode
Purpose

Synopsis

Declares a preprocess node callback function, called before the LP relaxation of a node has been
optimized, so the solution at the node will not be available. This callback function will be called inaddition to any callbacks already added by addcbprenode.
problem.addcbprenode(callback, data, priority)
nodinfeas = callback(my_prob, my_object)Arguments
callback

my_prob
my_objectnodinfeas
data
priority

ExampleThe callback function, which takes three arguments, my_prob, my_object andnodinfeas, and has no return value. This function is called before a node isreoptimized and the node may be made infeasible by setting ⁎nodinfeas to 1.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbprenode.
The feasibility status. If set to a nonzero value by the user, the current node will bedeclared infeasible by the Optimizer.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple preprocess node callbacks will be
invoked. The callback added with a higher priority will be called before a callback with alower priority. Set to 0 if not required.

The following example notiﬁes the user before each node is processed:
prob.addcbprenode(preNode, None, 0)prob.mipoptimize("")
The callback function might resemble:
def preNode(prob, object):return 0 # set to 1 if node is infeasible

Related topics
problem.removecbprenode, problem.addcbinfnode, problem.addcbintsol,
problem.addcbnodecutoff, problem.addcboptnode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

131Reference Manual

problem.addcbusersolnotify
Purpose

Synopsis

Declares a callback function to be called each time a solution added by problem.addmipsol has
been processed. This callback function will be called in addition to any callbacks already added by
addcbusersolnotify.
problem.addcbusersolnotify(callback, data, priority)
callback(my_prob, my_object, solname, status)

Arguments
callback
my_prob
my_objectsolnamestatusdata
priority

The callback function which takes four arguments, my_prob, my_object, id andstatus and has no return value.
The problem passed to the callback function, callback.
The user-deﬁned object passed as object when setting up the callback withaddcbusersolnotify.
The string name assigned to the solution when it was loaded into the Optimizer using
problem.addmipsol.
One of the following status values:
0
An error occured while processing the solution.
1
Solution is feasible.
2
Solution is feasible after reoptimizing with ﬁxed globals.
3
A local search heuristic was applied and a feasible solution discovered.
4
A local search heuristic was applied but a feasible solution was not found.
5
Solution is infeasible and a local search could not be applied.
6
Solution is partial and a local search could not be applied.
7
Failed to reoptimize the problem with globals ﬁxed to the provided solution.
Likely because a time or iteration limit was reached.
8
Solution is dropped. This can happen if the MIP problem is changed or solved
to completion before the solution could be processed.
A user-deﬁned object to be passed to the callback function, callback.
An integer that determines the order in which multiple callbacks will be invoked. The
callback added with a higher priority will be called before a callback with a lower priority.
Set to 0 if not required.

Further information
If presolve is turned on, any solution added with problem.addmipsol will ﬁrst be presolved before it
can be checked. The value returned in status refers to the presolved solution, which might have hadvalues adjusted due to bound changes, ﬁxing of variables, etc.
Related topics
problem.removecbusersolnotify, problem.addmipsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

132

Reference Manual

problem.addcoefs
Purpose
Synopsis

Add non-linear coefﬁcients to the SLP problem
problem.addcoefs(rowindex, colindex, factor, fstart, parsed, type, value)

Arguments
rowindex
Array holding the rows (or their indices or names) for the coefﬁcient.
colindex
Array holding the columns (or their indices or names) for the coefﬁcient.
factorArray holding factor by which formula is scaled. If None, a value of 1.0 will be used.
FormulaStart Integer array holding the start position in the arrays Type and Value of the formulafor the coefﬁcients. FormulaStart should have an extra entry containing the next
position after the end of the last formula.
parsedInteger indicating whether the token arrays are formatted as internal unparsed (parsed= False) or internal parsed reverse Polish (parsed = True).
type
Array of token types providing the formula for each coefﬁcient.
value
Array of values corresponding to the types in Type.
ExampleAssume that the rows and columns of Prob are named Row1, Row2 ..., Col1, Col2 ..., respectively. The
following example adds coefﬁcients representing:
Col2 ⁎ Col3 + Col6 ⁎ Col2ˆ2 into Row1 andCol2 ˆ 2 into Row3.
rowindex = [Row1,Row1,Row3]
colindex = [Col2,Col6,Col2]
formulastart = []n = 0ncoef = 0
formulastart[ncoef], ncoef = n, ncoef + 1
Type[n], Value[n], n = xslp_op_col, 3, n+1
Type[n],n = xslp_op_eof,
n+1
formulastart[ncoef], ncoef = n, ncoef + 1
Type[n], Value[n], n = xslp_op_col, 2,
n+1
Type[n], Value[n], n = xslp_op_col, 2,
n+1
Type[n], Value[n], n = xslp_op_op, xslp_MULTIPLY, n+1
Type[n],n = xslp_op_eof,
n+1
formulastart[ncoef], ncoef = n, ncoef + 1
Type[n], Value[n], n = xslp_op_col, 2, n+1
Type[n],n = xslp_op_eof,
n+1
formulastart[ncoef] = np.addcoefs(rowindex, colindex,

Fair Isaac Corporation Conﬁdential and Proprietary Information

None, formulastart, 1, Type, Value)133

Reference Manual

The ﬁrst coefﬁcient in Row1 is in Col2 and has the formula Col3, so it represents Col2 ⁎ Col3.
The second coefﬁcient in Row1 is in Col6 and has the formula Col2 ⁎ Col2 so it represents Col6 ⁎Col2ˆ2. The formulae are described as parsed (Parsed=1), so the formula is written as
Col2 Col2 ⁎rather than the unparsed form
Col2 ⁎ Col2The last coefﬁcient, in Row3, is in Col2 and has the formula Col2, so it represents Col2 ⁎ Col2.
Further information
The jth coefﬁcient is made up of two parts: Factor and Formula. Factor is a constant multiplier,which can be provided in the Factor array. If Xpress Nonlinear can identify a constant factor in
Formula, then it will use that as well, to minimize the size of the formula which has to be calculated.
Formula is made up of a list of tokens in Type and Value starting at formulastart[j]. The tokens
follow the rules for parsed or unparsed formulae as indicated by the setting of Parsed. The formula
must be terminated with an xslp_op_eof token. If several coefﬁcients share the same formula, they
can have the same value in FormulaStart. For possible token types and values see the chapter on"Formula Parsing".
The addcoef function loads additional items into the SLP problem. The corresponding loadcoefs
function deletes any existing items ﬁrst.
The behaviour for existing coefﬁcients is additive: the formula deﬁned in the parameters are added toany existing formula coefﬁcients. However, due to performance considerations, such duplications
should be avoided when possible.
Related topics
problem.chgnlcoef, problem.chgccoef, problem.delcoefs, problem.getcoefformula,problem.getccoef, problem.loadcoefs

Fair Isaac Corporation Conﬁdential and Proprietary Information

134

Reference Manual

problem.addcols
Purpose
Synopsis

Add columns to the problem after passing it to the Optimizer using the input routines.
problem.addcols(objx, mstart, mrwind, dmatval, bdl, bdu, names, types)

Arguments
objx
mstartmrwinddmatval
bdl
bdu
names
types

ExampleArray containing the objective function coefﬁcients of the new columns.
Array containing the offsets in the mrwind and dmatval arrays of the start of theelements for each column.
Array containing the rows (i.e. xpress.constraint objects, indices, or names) for theelements in each column.
Array containing the element values.
Array containing the lower bounds on the added columns.
Array containing the upper bounds on the added columns.
(optional) Array containing the names of the columns added.
(optional) Array of characters containing the types of the newly added columns:
C
indicates a continuous variable (default);
I
indicates an integer variable;
B
indicates a binary variable;
S
indicates a semi-continuous variable;R
indicates a semi-continuous integer variable;P
indicates a partial integer variable.

In this example, we consider the two problems:(a)maximize:

2x + y(b)subject to:x + 4y≤24

y3x + y

≤
≤

5
20

x+y

≤

9

maximize:

2x + y + 3z

subject to:x + 4y + 2z

≤

24

y+z
3x + y≤≤520

x + y + 3z

≤

9

z

≤

12

Using addcols, the following transforms (a) into (b):p = xpress.problem()p.read("example.lp")# assume this problem has at least four constraints
p.addcols(obj=[3], mstart=[0,3], mrwind=[0, 1, 3],matval=[2,1,3], bdl=[-xpress.infinity], bdu=[12],names=['john_cleese'], types=['C'])
Further information
1. The constant xpress.infinity can be used to represent inﬁnite bounds.
2. If the columns are added to a MIP problem, then they will be continuous variables unless types is
speciﬁed. Use problem.chgcoltype to impose integrality conditions on such new columns.

Fair Isaac Corporation Conﬁdential and Proprietary Information

135

Reference Manual

Related topics
problem.addrows, problem.chgcoltype.

Fair Isaac Corporation Conﬁdential and Proprietary Information

136

Reference Manual

problem.addConstraint
Purpose
Synopsis

Adds one or more constraints to the problem.
problem.addConstraint(c1, c2, ...)

Argument
c1,c2...

Constraints or list/tuples/array of constraints created with thexpress.constraint() call.

ExampleN = 20x = [xpress.var() for i in range(N)]c = [x[i] <= x[i+1] for i in range(N-1)]
c2 = x[0] >= x[19]p = xpress.problem()p.addVariable(x)p.addConstraint(x[2] == x[4])p.addConstraint(c, c2)
Further information
All arguments can be single constraints or lists, tuples, or NumPy arrays of constraints created as
xpress.constraint objects. Arguments do not need to be declared prior to the call.

Fair Isaac Corporation Conﬁdential and Proprietary Information

137

Reference Manual

problem.addcuts
Purpose

Synopsis

Adds cuts directly to the matrix at the current node. Any cuts added to the matrix at the current nodeand not deleted at the current node will be automatically added to the cut pool. The cuts added to thecut pool will be automatically restored at descendant nodes.
problem.addcuts(mtype, rtype, rhs, mstart, mcols, dmatval)

Arguments
mtype

rtype

rhs
mstartmcols
dmatvalArray containing the user assigned cut types. The cut types can be any integer chosen
by the user, and are used to identify the cuts in other cut manager routines using user
supplied parameters. The cut type can be interpreted as an integer or a bitmap - see
problem.delcuts.
Character array containing the row types:
Lindicates a ≤ row;G
indicates ≥ row;E
indicates an = row.
Array containing the right hand side elements for the cuts.
Array containing offset into the mcols and dmatval arrays indicating the start of eachcut. This array is of length ncuts+1 with the last element, mstart[ncuts], being
where cut ncuts+1 would start.
Array containing the columns (i.e. xpress.var objects, indices, or names) in the cuts.
Array containing the matrix values for the cuts.

Further information
1. The columns and elements of the cuts must be stored contiguously in the mcols and dmatval arrays
passed to addcuts. The starting point of each cut must be stored in the mstart array. To determine
the length of the ﬁnal cut, the mstart array must be of length ncuts+1 with the last element of thisarray containing the position in mcols and dmatval where the cut ncuts+1 would start.
mstart[ncuts] denotes the number of nonzeros in the added cuts.
2. The cuts added to the matrix are always added at the end of the matrix and the number of rows isalways set to the original number of cuts added. If ncuts have been added, then the rows
0,...,ROWS-ncuts-1 are the original rows, whilst the rows ROWS-ncuts,...,ROWS-1 are the added cuts.
The number of cuts can be found by consulting the CUTS problem attribute.
Related topics
problem.addrows, problem.delcpcuts, problem.delcuts, problem.getcpcutlist,
problem.getcutlist, problem.loadcuts, problem.storecuts, Section "Working with the cut
manager" of the Xpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

138

Reference Manual

problem.adddfs
Purpose
Synopsis

Add a set of distribution factors
problem.adddfs(colindex, rowindex, value)

Arguments
colindex
rowindexvalue
ExampleArray of columns (i.e. xpress.var objects, indices, or names) whose distribution
factor is to be changed.
Array of rows (i.e. xpress.constraint objects, indices, or names) where each
distribution factor applies.
Array holding the new values of the distribution factors.

The following example adds distribution factors as follows:column 282 in row 134 = 0.1
column 282 in row 136 = 0.15
column 285 in row 133 = 1.0.
colindex = [282, 282, 285]
rowindex = [134, 136, 133]value
= [0.1, 0.15, 1]
p.adddfs(colindex,rowindex,value)

Further information
The distribution factor of a column in a row is the matrix coefﬁcient of the corresponding delta vector in
the row. Distribution factors are used in conventional recursion models, and are essentially normalizedﬁrst-order derivatives. Xpress SLP can accept distribution factors instead of initial values, provided thatthe values of the variables involved can all be calculated after optimization using determining rows, orby a callback.
The problem.adddfs functions load additional items into the SLP problem. The corresponding
problem.loaddfs functions delete any existing items ﬁrst.
Related topics
problem.chgdf, problem.getdf, problem.loaddfs

Fair Isaac Corporation Conﬁdential and Proprietary Information

139

Reference Manual

problem.addgencons
Purpose

Synopsis

Adds one or more general constraints to the problem. Each general constraint y = f(x1, ..., xn,
c1, ..., cn) consists of one or more (input) columns xi, zero or more constant values ci and a
resultant (output column) y. General constraints can be deﬁned using operators such as maximum andminimum (at least one input column of any type and arbitrary number of input values), and and or (atleast one binary input column, no constant values, binary resultant) and absolute value (exactly
one input column of arbitrary type, no constant values).
problem.addgencons (type, resultant, colstart, col, valstart, val)

Arguments
type

resultantcolstart
colvalstart
val
Examplelist or array containing the types of the general constraints:
xpress.gencons_max (0)indicates a maximum constraint;
xpress.gencons_min (1)indicates a minimum constraint;
xpress.gencons_and (2)indicates an and constraint;
xpress.gencons_or (3)indicates an or constraint;
xpress.gencons_abs (4)indicates an absolute value constraint.
Array/list containing the output variables (or indices thereof) of the general
constraints.
Array/list containing the start index of each general constraint in the col array.
Array/list containing the input variables in all general constraints.
Array/list containing the start index of each general constraint in the val array(may be None).
Array/list containing the constant values in all general constraints (may be None).

This adds two new general constraints x2 = max(x0, x1, 5) and x3 = |x1|:
type = [xpress.gencons_max, xpress.gencons_abs]
resultant = [2, 3]
colstart = [0, 2]
col = [0, 1, 1]
valstart = [0, 1]
val = [5.0]prob.addgencons(type, resultant, colstart, col, valstart, val);prob.solve()

Further information
General constraints must be set up before solving the problem. They are converted to additional binary
variables, indicator and linear constraints with the exact formulation and number of added entities
depending on the performed presolving.
Note that using non-binary variables in and/or constraints or adding constant values to them orabsolute value constraints will give an error at solve time.
Related topics
problem.getgencons, problem.delgencons, xpress.And, xpress.Or, xpress.max,
xpress.min, xpress.abs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

140

Reference Manual

problem.addIndicator
Purpose
Synopsis

Adds one or more indicator constraints to the problem.
problem.addIndicator(c1, c2, ...)

Argument
c1,c2...

Tuples containing an indicator constraints, or list/tuples/array of tuples containing abinary condition and a constraint.

Examplex = xpress.var(vartype=xpress.binary)y = xpress.var(lb=10, ub=20)z = xpress.var()
ind1 = (x==1, y+z <= 40)
p = xpress.problem()p.addVariable(x,y,z)p.addIndicator(ind1)
Further information
All arguments can be single indicator constraints or lists, tuples, or NumPy arrays created as indicator
constraints. An indicator constraint is a tuple of two elements, the ﬁrst being a condition (i.e. a binary
variable being 0 or 1) and the second being the constraint.

Fair Isaac Corporation Conﬁdential and Proprietary Information

141

Reference Manual

problem.addmipsol
Purpose
Synopsis

Adds a new feasible, infeasible or partial MIP solution for the problem to the Optimizer.
problem.addmipsol(mipsolval, mipsolcol, solname)Arguments
mipsolval
mipsolcol

solnameArray containing solution values.
Optional integer array containing the columns (i.e. xpress.var objects, indices, ornames) for the solution values provided in mipsolval. It is optional when the length of
mipsolval is equal to COLS, in which case it is assumed that mipsolval provides acomplete solution vector.
An optional name to associate with the solution.

Further information
1. The function returns immediately after passing the solution to the Optimizer. The solution is placed in apool until the Optimizer is able to analyze the solution during a MIP solve.
2. If the provided solution is found to be infeasible, a limited local search heuristic will be run in an
attempt to ﬁnd a close feasible integer solution.
3. If a partial solution is provided, global columns will be ﬁxed to any provided values and a limited local
search will be run in an attempt to ﬁnd integer feasible values for the remaining unspeciﬁed columns.
Values provided for continuous column in partial solutions are currently ignored.
4. The problem.addcbusersolnotify callback function can be used to discover the outcome of aloaded solution. The optional name provided as solname will be returned in the callback function.
5. If one or more solutions are loaded during the problem.addcboptnode callback, the Optimizer willprocess all loaded solutions and ﬁre the callback again. This will be repeated as long as new solutions
are loaded during the callback.
Related topics
problem.addcbusersolnotify, problem.addcboptnode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

142

Reference Manual

problem.addpwlcons
Purpose

Synopsis

Adds one or more piecewise linear constraints to the problem. Each piecewise linear constraint y =f(x) consists of an (input) column x, a resultant (output column) y and a piecewise linear function f.
The piecewise linear function f is described by a number of breakpoints, which are given as
combinations of x- and y-values. Discontinuous piecewise linear functions are supported, in this caseboth the left and right limit at a given point need to be entered as breakpoints. To differentiate between
left and right limit, the breakpoints need to be given as a list with non-decreasing x-values.
problem.addpwlcons(col, resultant, start, xval, yval)

Arguments
colresultant
start
xval
yval
ExampleInteger array (or list) containing the input variables x of the piecewise linear functions.
Integer array containing the output variables y of the piecewise linear functions.
Integer array containing the start index of each piecewise linear constraint in the xval
and yval arrays.
Array containing the x-values of the breakpoints.
Array containing the y-values of the breakpoints.

This adds a new piecewise linear constraint y = f(x), wheref(x) = -x

if x < 0f(x) = 1

if 0 <= x <= 2

f(x) = 2x-3

if x > 2

col = [x]resultant = [y]start = [0]xval = [-1, 0, 0, 2, 3]
yval = [1, 0.5, 1, 1, 3]
prob.addpwlcons(col, resultant, start, xval, yval)
prob.setObjective(y)# the piecewise linear function is to be minimized
prob.mipoptimize()
Further information
Piecewise linear constraints must be set up before solving the problem. They are converted toadditional linear constraints, continuous variables and SOS2 constraints, with the exact formulationand number of added entities depending on the convexity of the piecewise linear function and somepresolving steps that are applied.
Related topics
problem.getpwlcons, problem.delpwlcons, xpress.pwl.

Fair Isaac Corporation Conﬁdential and Proprietary Information

143

Reference Manual

problem.addqmatrix
Purpose
Synopsis

Adds a new quadratic matrix into a row deﬁned by triplets.
problem.addqmatrix(irow, mqc1, mqc2, dqe)

Arguments
irow
mqc1
mqc2
dqe

Row (i.e. xpress.constraint object, index, or name) where the quadratic matrix is tobe added.
Array with ﬁrst variables (i.e. xpress.varobjects, indices, or names) in the triplets.
Array with second variables (i.e. xpress.varobjects, indices, or names) index in the
triplets.
Array of coefﬁcients in the triplets.

Further information
1. The triplets should deﬁne the upper triangular part of the quadratic expression. This means that to add
x2 + 4xy the dqe array shall contain the coefﬁcients 1 and 2.
2. The matrix deﬁned by mqc1, mqc2 and dqe should be positive semi-deﬁnite for ≤ and negative
semi-deﬁnite for ≥ rows.
3. The row must not be an equality or a ranged row.
Related topics
problem.loadproblem, problem.getqrowcoeff, problem.chgqrowcoeff,
problem.getqrowqmatrix, problem.getqrowqmatrixtriplets, problem.getqrows,
problem.chgqobj, problem.chgmqobj, problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

144

Reference Manual

problem.addrows
Purpose
Synopsis

Adds rows and their coefﬁcient to the problem.
problem.addrows(qrtype, rhs, mstart, mclind, dmatval, range=None,names=None)

Arguments
qrtyperhs
mstartmclinddmatvalrange
names
ExampleCharacter array containing the row types:
Lindicates a ≤ row;G
indicates ≥ row;E
indicates an = row.
R
indicates a range constraint;N
indicates a nonbinding constraint.
Array containing the right hand side elements.
Array containing the offsets in the mclind and dmatval arrays of the start of theelements for each row.
Array containing the (contiguous) columns (i.e. xpress.varobjects, indices, or names)
for the elements in each row.
Array containing the (contiguous) element coefﬁcients.
(optional) Array containing the row range elements. The values in the range array will
only be read for ’R’ type rows. The entries for other type rows will be ignored.
(optional) Array of names to be assigned to each new row.

Suppose the current problem is:
maximize:

2x + y + 3z

subject to:x + 4y + 2z

≤

24

y+z

≤

5

3x + y≤20

x + y + 3z≤

9Then the following adds the row 8x + 9y + 10z ≤ 25 to the problem and names it NewRow:
p = xpress.problem()p.addrows(['L'], [25], [0,3], [0,1,2],
dmatval=[8, 9, 10], range=None, names=['NewRow'])
Further information
Range rows are automatically converted to type L, with an upper bound in the slack. This must be taken
into consideration, when retrieving row type, right–hand side values or range information for rows.
Related topics
problem.addcols, problem.addcuts.

Fair Isaac Corporation Conﬁdential and Proprietary Information

145

Reference Manual

problem.addsetnames
Purpose

Synopsis

When a model with global entities is loaded, any special ordered sets may not have names associatedwith them. If you wish names to appear in the ASCII solutions ﬁles, the names for a range of sets canbe added with this function.
problem.addsetnames(names, first=0, last=problem.attributes.sets - 1);

Arguments
names
first
last
ExampleA list of strings contatining all names to be assigned.
(Optional) start of the set range.
(Optional) end of the set range.

Add set names (set1 and set2) to a problem:
snames = ["set1", "set2"]...
p.addsetnames(snames, 0, 1);

Further information
If start is not provided, it is considered equal to 0; if end is omitted, a value ofproblem.attributes.sets - 1 is used.
Related topics
problem.loadproblem,

Fair Isaac Corporation Conﬁdential and Proprietary Information

146

Reference Manual

problem.addSOS
Purpose
Synopsis

Adds one or more Special Ordered Set (SOS) to the problem.
problem.addSOS(s1, s2, ...)

Argument
s1,s2...

Special Ordered Sets deﬁned prior to the call or (see example below) deﬁned directly inthe call.

ExampleN = 20x = [xpress.var() for i in range(N)]p = xpress.problem()p.addVariable(x)s = xpress.sos([x], [i+2 for i in range(N)])
p.addSOS(s)p.addSOS([x[0], x[2]], [4,6])
Further information
All arguments can be single SOSs or lists, tuples, or NumPy arrays of SOSs created as xpress.sos
objects. As for constraints, a SOS does not need to be declared prior to being added as an argument.

Fair Isaac Corporation Conﬁdential and Proprietary Information

147

Reference Manual

problem.addtolsets
Purpose
Synopsis

Add sets of standard tolerance values to an SLP problem
problem.addtolsets(tol)Argument
slptolExampleArray of 9h elements containing the 9 tolerance values for each set in order.

The following example creates two tolerance sets: the ﬁrst has values of 0.005 for all tolerances; thesecond has values of 0.001 for relative tolerances (numbers 2,4,6,8), values of 0.01 for absolute
tolerances (numbers 1,3,5,7) and zero for the closure tolerance (number 0).
tol = 9⁎[0.005]+[0]+[0.01,0.001]⁎4
p.addtolsets(tol)Further information
A tolerance set is an array of 9 values containing the following tolerances:
Entry / Bit

ToleranceXSLP constantXSLP bit constant0

Closure tolerance (TC)xslp_TOLSET_TC

xslp_TOLSETBIT_TC

1

Absolute delta tolerance (TA)xslp_TOLSET_TA

xslp_TOLSETBIT_TA

2

Relative delta tolerance (RA)xslp_TOLSET_RA

xslp_TOLSETBIT_RA

3

Absolute coefﬁcient tolerance (TM)xslp_TOLSET_TM

xslp_TOLSETBIT_TM

4

Relative coefﬁcient tolerance (RM)

xslp_TOLSET_RM

xslp_TOLSETBIT_RM

5

Absolute impact tolerance (TI)

xslp_TOLSET_TI

xslp_TOLSETBIT_TI

6

Relative impact tolerance (RI)

xslp_TOLSET_RI

xslp_TOLSETBIT_RI

7

Absolute slack tolerance (TS)xslp_TOLSET_TS

xslp_TOLSETBIT_TS

8

Relative slack tolerance (RS)xslp_TOLSET_RS

xslp_TOLSETBIT_RS

The xslp_TOLSET constants can be used to access the corresponding entry in the value arrays, whilethe xslp_TOLSETBIT constants are used to set or retrieve which tolerance values are used for a given
SLP variable. Once created, a tolerance set can be used to set the tolerances for any SLP variable. If atolerance value is zero, then the default tolerance will be used instead. To force the use of a tolerance,
use the problem.chgtolset function and set the Status variable appropriately. See the section"Convergence criteria" of the SLP Reference Manual for a fuller description of tolerances and their uses.
The problem.addtolsets functions load additional items into the SLP problem. The corresponding
problem.loadtolsets functions delete any existing items ﬁrst.
Related topics
problem.chgtolset, problem.deltolsets, problem.gettolset, problem.loadtolsets

Fair Isaac Corporation Conﬁdential and Proprietary Information

148

Reference Manual

problem.addVariable
Purpose
Synopsis

Adds one or more variables to the problem.
problem.addVariable(v1, v2, ...)

Argument
v1,v2...

Variables or list/tuples/array of variables created with the xpress.var() call.

Examplex = xpress.var(vartype=xpress.binary)
Y = [xpress.var() for i in range(20)]p = xpress.problem()p.addVariable(x, Y)
Further information
All arguments can be single variables or lists, tuples, or NumPy arrays of variables created as
xpress.var objects.

Fair Isaac Corporation Conﬁdential and Proprietary Information

149

Reference Manual

problem.addvars
Purpose
Synopsis

Add SLP variables deﬁned as matrix columns to an SLP problem
problem.addvars(colindex, vartype, detrow, seqnum, tolindex, initvalue,
stepbound)Arguments
colindex
vartypedetrow

seqnumtolindex

initvalue

stepbound

ExampleInteger array holding the index of the matrix column corresponding to each SLP variable.
Bitmap giving information about the SLP variable as follows:
Bit 1
Variable has a delta vector;
Bit 2
Variable has an initial value;
Bit 14
Variable is the reserved "=" column;
May be None if not required.
Integer array holding the index of the determining row for each SLP variable (a negativevalue means there is no determining row)
May be None if not required.
Integer array holding the index sequence number for cascading for each SLP variable (azero value means there is no pre-deﬁned order for this variable)
May be None if not required.
Integer array holding the index of the tolerance set for each SLP variable (a zero valuemeans the default tolerances are used)
May be None if not required.
Double array holding the initial value for each SLP variable (use the VarType bit map to
indicate if a value is being provided)
May be None if not required.
Double array holding the initial step bound size for each SLP variable (a zero valuemeans that no initial step bound size has been speciﬁed). If a value ofxpress.infinity is used for a value in stepbound, the delta will never have stepbounds applied, and will almost always be regarded as converged.
May be None if not required.

The following example loads two SLP variables into the problem. They correspond to columns 23 and25 of the underlying LP problem. Column 25 has an initial value of 1.42; column 23 has no speciﬁc
initial value
colindex = [23,25]
vartype= [0,2]
initvalue = [0,1.42]
p.addvars(colindex, vartype, None, None, None, initvalue, None)
initvalue is not set for the ﬁrst variable, because it is not used (vartype = 0). Bit 1 of vartype isset for the second variable to indicate that the initial value has been set. The arrays for determining
rows, sequence numbers, tolerance sets and step bounds are not used at all, and so have been passed
to the function as None.

Further information
The addvars functions load additional items into the SLP problem. The corresponding loadvars
functions delete any existing items ﬁrst.
Related topics
problem.chgvar, problem.delvars, problem.getvar, problem.loadvars

Fair Isaac Corporation Conﬁdential and Proprietary Information

150

Reference Manual

problem.basisstability
Purpose
Synopsis

Returns various measures for the stability of the current basis, including the basis condition number.
x = problem.basisstability(type, norm, ifscaled)

Arguments
type

norm
ifscaled

0
Condition number of the basis.
1
Stability measure for the solution relative to the current basis.
2
Stability measure for the duals relative to the current basis.
3
Stability measure for the right hand side relative to the current basis.
4
Stability measure for the basic part of the objective relative to the current basis.
0
Use the inﬁnity norm.
1
Use the 1 norm.
2
Use the Euclidian norm for vectors and the Frobenius norm for matrices.
If the stability values are to be calculated in the scaled or the unscaled matrix.

Further information
1. The condition number (type = 0) of an invertible matrix is the norm of the matrix multiplied with thenorm of its inverse. This number is an indication of how accurate the solution can be calculated andhow sensitive it is to small changes in the data. The larger the condition number is, the less accurate
the solution is likely to become.
2. The stability measures (type = 1...4) are using the original matrix and the basis to recalculate thevarious vectors related to the solution and the duals. The returned stability measure is the norm of thedifference of the recalculated vector to the original one.

Fair Isaac Corporation Conﬁdential and Proprietary Information

151

Reference Manual

problem.btran
Purpose
Synopsis

Post-multiplies a (row) vector provided by the user by the inverse of the current basis.
problem.btran(vec)

Argument
vec
ExampleArray of length problem.attributes.rows containing the values by which the basis
inverse is to be multiplied. The transformed values will also be returned in this array.

Get the (unscaled) tableau row z of constraint number irow, assuming that all arrays have been
dimensioned.
y = [0,1,0,0]
p.btran(y)print("btran result:", y)Further information
If the problem is in a presolved state, btran works with the basis for the presolved problem.
Related topics
problem.ftran.

Fair Isaac Corporation Conﬁdential and Proprietary Information

152

Reference Manual

problem.calcobjective
Purpose
Synopsis

Returns the objective value of a given solution.
objval = problem.calcobjective(solution)

Argument
solution

Array of length problem.attributes.cols that holds the solution.

Further information
The calculations are always carried out in the original problem, even if the problem is currently
presolved.
Related topics
problem.calcslacks, problem.calcreducedcosts.

Fair Isaac Corporation Conﬁdential and Proprietary Information

153

Reference Manual

problem.calcreducedcosts
Purpose
Synopsis

Returns the reduced cost values for a given (row) dual solution.
problem.calcreducedcosts(duals, solution, calculateddjs)

Arguments
duals

Array of length problem.attributes.rows that holds the dual solution to calculate
the reduced costs for.
solution
Optional array of length problem.attributes.cols that holds the primal solution.
This is necessary for quadratic problems.
calculateddjs Array of length problem.attributes.cols in which the calculated reduced
costs are returned.

Examplep = xpress.problem()p.read("silly_walks.lp") # assume problem has 4 constraints
dj = []
p.calcreducedcosts([0,1,1,1], None, dj)
print("red. cost:", dj)
Further information
1. The calculations are always carried out in the original problem, even if the problem is currently
presolved.
2. If using the function during a solve (e.g. from a callback), use ORIGINALCOLS and ORIGINALROWS toretrieve the non-presolved dimensions of the problem.
Related topics
problem.calcslacks, problem.calcobjective.

Fair Isaac Corporation Conﬁdential and Proprietary Information

154

Reference Manual

problem.calcslacks
Purpose
SynopsisCalculates the row slack values for a given solution.
problem.calcslacks(solution, calculatedslacks)

Arguments
solution

Array of length problem.attributes.cols that holds the solution to calculate theslacks for.
calculatedslacks Array of length problem.attributes.rows in which the calculated row
slacks are returned.

Further information
1. The calculations are always carried out in the original problem, even if the problem is currently
presolved.
2. If using the function during a solve (e.g. from a callback), use ORIGINALCOLS and ORIGINALROWS toretrieve the non-presolved dimensions of the problem.
Related topics
problem.calcreducedcosts, problem.calcobjective.

Fair Isaac Corporation Conﬁdential and Proprietary Information

155

Reference Manual

problem.calcsolinfo
Purpose

Synopsis

Returns the required property of a solution, like maximum infeasibility of a given primal and dual
solution.
val = problem.calcsolinfo(solution, dual, property)

Arguments
solutiondual
property

Array of length problem.attributes.cols that holds the solution.
Array of length problem.attributes.rows that holds the dual solution.
xpress.solinfo_absprimalinfeas
absolute primal infeasibility.
xpress.solinfo_relprimalinfeas
relative primal infeasibility.
xpress.solinfo_absdualinfeas
absolute dual infeasibility.
xpress.solinfo_reldualinfeas
relative dual infeasibility.
xpress.solinfo_maxmipfractional absolute MIP infeasibility (fractionality).

Further information
The calculations are always carried out in the original problem, even if the problem is currently
presolved.
Related topics
problem.calcslacks, problem.calcobjective, problem.calcreducedcosts.

Fair Isaac Corporation Conﬁdential and Proprietary Information

156

Reference Manual

problem.cascade
Purpose
Synopsis
ExampleRe-calculate consistent values for SLP variables. based on the current values of the remaining variables
problem.cascade()
The following example changes the solution value for column 91, and then re-calculates the values of
those dependent on it.
colnum = 91
(a,b,c,d,e,f,value,h,i,j,k,l,m,n,o) = p.getvar(colnum)
value += 1.42
p.chgvar(colnum, None, None, None, None,
None, None, value, None, None, None,
None)p.cascade()
problem.getvar and problem.chgvar are being used to get and change the current value of asingle variable. Provided no other values have been changed since the last execution of cascade,values will be changed only for variables which depend on column 91.

Further information
See the section on cascading for an extended discussion of the types of cascading which can be
performed.
cascade is called automatically during the SLP iteration process and so it is not normally necessary to
perform an explicit cascade calculation.
The variables are re-calculated in accordance with the order generated by problem.cascadeorder.
Related topics
problem.cascadeorder

Fair Isaac Corporation Conﬁdential and Proprietary Information

157

Reference Manual

problem.cascadeorderPurpose
Synopsis
ExampleEstablish a re-calculation sequence for SLP variables with determining rows.
problem.cascadeorder()Assuming that all variables are SLP variables, the following example sets default values for thevariables, creates the re-calculation order and then calls problem.cascade to calculate consistentvalues for the dependent variables.
for colnum in range(1, nCol):p.chgvar(colnum, None, None, None, None,
None, None, [DefaultValue [ColNum]], None, None, None,
None)p.cascadeorder()p.cascade()

Further informationcascadeorder is called automatically at the start of the SLP iteration process and so it is notnormally necessary to perform an explicit cascade ordering.
Related topics
problem.cascade

Fair Isaac Corporation Conﬁdential and Proprietary Information

158

Reference Manual

problem.chgbounds
Purpose
Synopsis

Changes the bounds on columns in the problem.
problem.chgbounds(mindex, qbtype, bnd)

Arguments
mindexArray containing the columns (i.e. xpress.var objects, indices, or names) on which
the bounds will change.
Character array indicating the type of bound to change:
U
indicates a change in the upper bound;L
indicates a change in the lower bound;B
indicates a change in both bounds, i.e. the column is ﬁxed.
Array giving the new bound values.

qbtypebnd
ExampleThe following changes the lower bound of variable v1 to 2, upper bound of variable v2 to 5, and ﬁxes
variable v3 to 3:
p.chgbounds([v1,v2,v3],['L','U','B'],[2,5,3])

Further information
1. A column may appear twice in the mindex array so it is possible to change both the upper and lower
bounds on a variable in one go.
2. chgbounds may be applied to the problem in a presolved state, in which case it expects references tothe presolved problem.
3. The double constant xpress.infinity can be used to represent plus and minus inﬁnity in the bound(bnd) array.
4. If the upper bound on a binary variable is changed to be greater than 1 or the lower bound is changed tobe less than 0 then the variable will become an integer variable.
Related topics
problem.getlb, problem.getub.

Fair Isaac Corporation Conﬁdential and Proprietary Information

159

Reference Manual

problem.chgcoef
Purpose

Synopsis

Changes a single coefﬁcient in the problem. If the coefﬁcient does not already exist, a new coefﬁcient
will be added to the problem. If many coefﬁcients are being added to a row of the problem, it may be
more efﬁcient to delete the old row and add a new row.
problem.chgcoef(irow, icol, dval)

Arguments
irow
icol
dval
ExampleRow (i.e. xpress.constraint object, index, or name) for the coefﬁcient.
Column (i.e. xpress.var object, index, or name) for the coefﬁcient.
New value for the coefﬁcient. If dval is zero, any existing coefﬁcient will be deleted.

In the following, the constraint is introduced in the problem and then its linear coefﬁcient for x ischanged to 3:
p = xpress.problem()x = xpress.var()c = x + x⁎⁎2 <= 3
p.addVariable(x)p.addConstraint(c)p.chgcoef(c,x,3)

Further information
problem.chgmcoef is more efﬁcient than multiple calls to chgcoef and should be used in its placein such circumstances.
Related topics
problem.addcols, problem.addrows, problem.chgmcoef, problem.chgmqobj,
problem.chgobj, problem.chgqobj, problem.chgrhs, problem.getcols,
problem.getrows.

Fair Isaac Corporation Conﬁdential and Proprietary Information

160

Reference Manual

problem.chgcoltype
Purpose
Synopsis

Changes the type of a column in the problem.
problem.chgcoltype(mindex, qctype)

Arguments
mindexArray containing the columns (i.e. xpress.var objects, indices, or names) whose type
is to be changed.
Character array giving the new column types:
C
indicates a continuous column;
Bindicates a binary column;
I
indicates an integer column.
S
indicates a semi–continuous column. The semi–continuous lower bound will
be set to 1.0.
R
indicates a semi–integer column. The semi–integer lower bound will be set to
1.0.
P
indicates a partial integer column. The partial integer bound will be set to 1.0.

qctypeExampleThe following changes the type of variable x from binary to integer:p = xpress.problem()x = xpress.var(vartype=xp.binary)p.addVariable(x)p.chgcoltype([x],['I'])

Further information
1. The column types can only be changed before the global search is started.
2. Calling chgcoltype to change any variable into a binary variable causes the bounds previously
deﬁned for the variable to be deleted and replaced by bounds of 0 and 1.
3. Calling chgcoltype to change a continuous variable into an integer variable cause its lower bound to
be rounded up to the nearest integer value and its upper bound to be rounded down to the nearest
integer value.
Related topics
problem.addcols, problem.chgrowtype, problem.getcoltype.

Fair Isaac Corporation Conﬁdential and Proprietary Information

161

Reference Manual

problem.chgcascadenlimit
Purpose
Synopsis

Set a variable speciﬁc cascade iteration limit
problem.chgcascadenlimit(icol, cascadenlimit)

Arguments
icol

The column corresponding to the SLP variable for which the cascading limit is to be
imposed.
cascadenlimit The new cascading iteration limit.

Further information
A value set by this function will overwrite the value of the control xslp_cascadenlimit for thisvariable. To remove any previous value set by this function, use an iteration limit of 0.
Related topics
problem.cascadeorder

Fair Isaac Corporation Conﬁdential and Proprietary Information

162

Reference Manual

problem.chgccoef
Purpose
Synopsis

Add or change a single matrix coefﬁcient using a character string for the formulaproblem.chgccoef(rowindex, colindex, factor, formula)

Arguments
rowindex
colindex
factorFormulaExampleThe row (i.e. xpress.constraint object, index, or name) for the coefﬁcient.
The column (i.e. xpress.var object, index, or name) for the coefﬁcient.
Constant multiplier for the formula. If factor is None, a value of 1.0 will be used.
Character string holding the formula, with the tokens separated by spaces.

Assuming that the columns of the matrix are named Col1, Col2, etc, the following example puts theformula 2.5⁎sin(Col1) into the coefﬁcient in row 1, column 3.
Formula = "sin ( Col1 )"Factor = 2.5
p.chgccoef(1, 3, Factor, Formula)
Note that all the tokens in the formula (including mathematical operators and separators) are
separated by one or more spaces.

Further information
If the coefﬁcient already exists as a constant or formula, it will be changed into the new coefﬁcient. If it
does not exist, it will be added to the problem.
A coefﬁcient is made up of two parts: Factor and Formula. Factor is a constant multiplier which
can be provided in the Factor variable. If Xpress Nonlinear can identify a constant factor in the
Formula, then it will use that as well, to minimize the size of the formula which has to be calculated.
This function can only be used if all the operands in the formula can be correctly identiﬁed as
constants, existing columns, character variables or functions. Therefore, if a formula refers to a newcolumn, that new item must be added to the Xpress Nonlinear problem ﬁrst.
Related topics
problem.addcoefs, problem.delcoefs, problem.chgnlcoef, problem.getcoefformula,problem.loadcoefs

Fair Isaac Corporation Conﬁdential and Proprietary Information

163

Reference Manual

problem.chgdeltatype
Purpose
Synopsis

Changes the type of the delta assigned to a nonlinear variableproblem.chgdeltatype(vars, deltatypes, values)

Arguments
Vars
Indices of the variables to change the deltas for.
DeltaTypes Type if the delta variable:
0
Differentiable variable, default.
1
Variable deﬁned over the grid size given in values.
2
Variable where a minimum perturbation size given in values may berequired before a signiﬁcant change in the problem is achieved.
3
Variable where a meaningful step size should automatically be detected,
with an upper limit given in values.
ValuesGrid or minimum step sizes for the variables.
Further information
Changing the delta type of a variables makes the variable nonlinear.
Related topics

Fair Isaac Corporation Conﬁdential and Proprietary Information

164

Reference Manual

problem.chgdf
Purpose
Synopsis

Set or change a distribution factor
problem.chgdf(colindex, rowindex, value)

Arguments
colindex
rowindexvalue
ExampleThe column (i.e. xpress.var object, index, or name) whose distribution factor is to be
set or changed.
The row (i.e. xpress.constraint object, index, or name) where the distribution
applies.
Address of a double precision variable holding the new value of the distribution factor.
May be None if not required.

The following example retrieves the value of the distribution factor for column 282 in row 134 andchanges it to be twice as large.
value = p.getdf(282,134)
value ⁎= 2
p.chgdf(282,134,value)

Further information
The distribution factor of a column in a row is the matrix coefﬁcient of the corresponding delta vector in
the row. Distribution factors are used in conventional recursion models, and are essentially normalizedﬁrst-order derivatives. Xpress Nonlinear can accept distribution factors instead of initial values,
provided that the values of the variables involved can all be calculated after optimization using
determining rows, or by a callback.
Related topics
problem.adddfs, problem.getdf, problem.loaddfs

Fair Isaac Corporation Conﬁdential and Proprietary Information

165

Reference Manual

problem.chgglblimit
Purpose
Synopsis

Changes semi-continuous or semi-integer lower bounds, or upper limits on partial integers.
problem.chgglblimit(mindex, dlimit)

Arguments
mindexdlimitArray containing the indices of the semi-continuous, semi-integer or partial integer
columns that should have their limits changed.
Array giving the new limit values.

Further information
1. The new limits are not allowed to be negative.
2. Partial integer limits can be at most 228 .
Related topics
problem.chgcoltype, problem.getglobal.

Fair Isaac Corporation Conﬁdential and Proprietary Information

166

Reference Manual

problem.chgmcoef
Purpose

Synopsis

Change multiple coefﬁcients in the problem. The coefﬁcients that do not exist yet will be added to the
problem. If many coefﬁcients are being added to a row of the matrix, it may be more efﬁcient to delete
the old row of the matrix and add a new one.
problem.chgmcoef(mrow, mcol, dval)

Arguments
mrow
mcol
dval

Array containing the rows (i.e. xpress.constraint objects, indices, or names) of thecoefﬁcients to be changed.
Array containing the columns (i.e. xpress.var objects, indices, or names) of thecoefﬁcients to be changed.
Array containing the new coefﬁcient values. If an element of dval is zero, thecoefﬁcient will be deleted.

Examplecon1 = x + y + z <= 2
con2 = x + y >= 1
con3 = x + 3⁎y == 1
p.addVariable(x,y,z)p.addConstraint(con1, con2, con3)
p.chgmcoef([con1,con1,con1,con2,con3], [x,y,z,x,x], [-2, -3, -3.2, 1, 3])This changes ﬁve coefﬁcients, three of which in the ﬁrst constraint and one in each of the second andthird constraints.
Further information
chgmcoef is more efﬁcient than repeated calls to problem.chgcoef and should be used in its place
if many coefﬁcients are to be changed.
Related topics
problem.chgcoef, problem.chgmqobj, problem.chgobj, problem.chgqobj,
problem.chgrhs, problem.getcols, problem.getrhs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

167

Reference Manual

problem.chgmqobj
Purpose

Synopsis

Change multiple quadratic coefﬁcients in the objective function. If any of the coefﬁcients does not exist
already, new coefﬁcients will be added to the objective function.
problem.chgmqobj(mqcol1, mqcol2, dval)

Arguments
mqcol1
mqcol2dval

ExampleArray containing the column index of the ﬁrst variable in each quadratic term.
Array containing the column index of the second variable in each quadratic term.
New values for the coefﬁcients. If an entry in dval is 0, the corresponding entry will bedeleted. These are the coefﬁcients of the lower triangular part of the Hessian of theobjective function.

The following code results in an objective function with terms: [4x12 + 6x1 x2
p.chgmqobj([x1,x1], [x1,x2], [4,3])

Further information
1. The columns in the arrays mqcol1 and mqcol2 must already exist in the matrix. If the columns do notexist, they must be added.
2. chgmqobj is more efﬁcient than repeated calls to problem.chgqobj and should be used in its placewhen several coefﬁcients are to be changed.
Related topics
problem.chgcoef, problem.chgmcoef, problem.chgobj, problem.chgqobj,
problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

168

Reference Manual

problem.chgnlcoef
Purpose
Synopsis

Add or change a single matrix coefﬁcient using a parsed or unparsed formulaproblem.chgnlcoef(rowindex, colindex, factor, parsed, type, value)

Arguments
rowindex
colindex
factorparsedtype
value
ExampleThe index of the matrix row for the coefﬁcient.
The index of the matrix column for the coefﬁcient.
Address of a double precision variable holding the constant multiplier for the formula. If
Factor is None, a value of 1.0 will be used.
Integer indicating the whether the token arrays are formatted as internal unparsed(parsed=False) or internal parsed reverse Polish (parsed=True).
Array of token types providing the description and formula for each item.
Array of values corresponding to the types in type.

Assuming that the columns of the matrix are named Col1, Col2, etc, the following example puts theformula 2.5⁎sin(Col1) into the coefﬁcient in row 1, column 3.
type = [xp.xslp_op_ifun, xp.xslp_op_var, xp.xslp_op_rb, xp.xslp_op_eof]
value = [xp.xslp_ifun_sin, 1,0,0]Factor = 2.5
p.chgnlcoef(1, 3, Factor, 0, type, value)
problem.getIndex is used to retrieve the index for the internal function sin. The "nocase" version
matches the function name regardless of the (upper or lower) case of the name. Tokens of typexpress.xslp_op_var always count from 1, so Col1 is 1. The formula is written in unparsed form
(parsed = 0) and so it is provided as tokens in the same order as they would appear if the formulawere written in character form.

Further information
If the coefﬁcient already exists as a constant or formula, it will be changed into the new coefﬁcient. If it
does not exist, it will be added to the problem.
A coefﬁcient is made up of two parts: Factor and Formula. Factor is a constant multiplier which
can be provided in the factor variable. If Xpress Nonlinear can identify a constant factor in the
Formula, then it will use that as well, to minimize the size of the formula which has to be calculated.
Related topics
problem.addcoefs, problem.chgccoef, problem.delcoefs, problem.getcoefformula,problem.loadcoefs

Fair Isaac Corporation Conﬁdential and Proprietary Information

169

Reference Manual

problem.chgobj
Purpose
Synopsis

Change the objective function coefﬁcients.
problem.chgobj(mindex, obj)

Arguments
mindexobj
ExampleArray containing the columns (i.e. xpress.var objects, indices, or names) on which
the range elements will change. An index of -1 indicates that the ﬁxed part of theobjective function on the right hand side should change.
Array giving the new objective function coefﬁcient.

Changing three coefﬁcients of the objective function with chgobj:
p.chgobj([x1,x2,x3,-1], [3.5, -2, 0, 224])

Further information
The value of the ﬁxed part of the objective function can be obtained using the OBJRHS problem
attribute.
Related topics
problem.chgcoef, problem.chgmcoef, problem.chgmqobj, problem.chgqobj,
problem.getobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

170

Reference Manual

problem.chgobjsense
Purpose
Synopsis

Changes the problem’s objective function sense to minimize or maximize.
problem.chgobjsense(sense)

Argument
objsense
Examplexpress.minimize or xpress.maximize to change into a minimization or
maximization problem, respectively.

Changing three coefﬁcients of the objective function with chgobj:
p.chgobjsense(xpress.maximize) # optimize in this general direction

Related topics
problem.lpoptimize, problem.mipoptimize.

Fair Isaac Corporation Conﬁdential and Proprietary Information

171

Reference Manual

problem.chgqobj
Purpose

Synopsis

Change a single quadratic coefﬁcient in the objective function corresponding to the variable pair(icol,jcol) of the Hessian matrix.
problem.chgqobj(icol, jcol, dval)

Arguments
icol
jcol
dval
ExampleColumn index for the ﬁrst variable in the quadratic term.
Column index for the second variable in the quadratic term.
New value for the coefﬁcient in the quadratic Hessian matrix. If an entry in dval is 0,
the corresponding entry will be deleted.

The following code adds the terms [6x12 + 3x1 x2 + 3x2 x1 ]/2 to the objective function:
p.chgqobj(x1, x1, 6)
p.chgqobj(x1, x2, 3)

Further information
1. The columns icol and jcol must already exist in the matrix..
2. If icol is not equal to jcol, then both the matrix elements (icol, jcol) and (jcol, icol) arechanged to leave the Hessian symmetric.
Related topics
problem.chgcoef, problem.chgmcoef, problem.chgmqobj, problem.chgobj,
problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

172

Reference Manual

problem.chgqrowcoeff
Purpose
Synopsis

Changes a single quadratic coefﬁcient in a row.
problem.chgqrowcoeff(irow, icol, jcol, dval)

Arguments
irow
icol
jcol
dval

Row (i.e. xpress.constraint object, index, or name) where the quadratic matrix is tobe changed.
First index of the coefﬁcient to be changed.
Second index of the coefﬁcient to be changed.
The new coefﬁcient.

Further information
1. This function may be used to add new nonzero coefﬁcients, or even to deﬁne the whole quadratic
expression with it. Doing that, however, is signiﬁcantly less efﬁcient than adding the whole expression
with problem.addqmatrix.
2. The row must not be an equality or a ranged row.
Related topics
problem.loadproblem, problem.getqrowcoeff, problem.addqmatrix,
problem.chgqrowcoeff, problem.getqrowqmatrix, problem.getqrowqmatrixtriplets,
problem.getqrows, problem.chgqobj, problem.chgmqobj, problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

173

Reference Manual

problem.chgrhs
Purpose
Synopsis

Changes right–hand side values of the problem.
problem.chgrhs(mindex, rhs)

Arguments
mindexrhs
ExampleArray containing the rows (i.e. xpress.constraint objects, indices, or names) whoseright hand side will change.
Array containing the right hand side values.

Here we change the three right hand sides in rows 2, 6, and 8 to new values:
p.chgrhs([2,8,6], [5, 3.8, 5.7])

Related topics
problem.chgcoef, problem.chgmcoef, problem.chgrhsrange, problem.getrhs,
problem.getrhsrange.

Fair Isaac Corporation Conﬁdential and Proprietary Information

174

Reference Manual

problem.chgrhsrange
Purpose
Synopsis

Change the range for one or more rows of the problem.
problem.chgrhsrange(mindex, rng)

Arguments
mindexArray containing the rows (i.e. xpress.constraint objects, indices, or names) on
which the range elements will change.
Array containing the range values.

rng
ExampleHere, the constraint cons1 x + y ≤ 10 is changed to 8 ≤ x + y ≤ 10:
p.chgrhsrange([cons1], [2])Further information
If the range speciﬁed on the row is r, what happens depends on the row type and value of r. It is
possible to convert non-range rows using this routine.
Value of r

Row type

Effectr≥0= b, ≤ bP
b–r ≤aj xj ≤ bPb≤
aj xj ≤ b + rPb≤aj xj ≤ b – r
P
b + r ≤ aj xj ≤ b

r≥0

≥b

r<0

= b, ≤ br<0≥b

Related topics
problem.chgcoef, problem.chgmcoef, problem.chgrhs, problem.getrhsrange.

Fair Isaac Corporation Conﬁdential and Proprietary Information

175

Reference Manual

problem.chgrowstatus
Purpose
Synopsis

Change the status setting of a constraint
problem.chgrowstatus(rowindex, status)

Arguments
rowindex
statusExampleThe index of the matrix row to be changed.
The bitmap with the new status settings. If the status is to be changed, always get thecurrent status ﬁrst (use problem.getrowstatus) and then change settings as
required. The only settings likely to be changed are:Bit 11
Set if row must not have a penalty error vector. This is the equivalent of an
enforced constraint (SLPDATA type EC).

The following example changes the status of row 9 to be an enforced constraint.
status = p.getrowstatus(9)status = status | (1<<11)p.chgrowstatus(9, status)

Further information
If status is None the current status will remain unchanged.
Related topics
problem.getrowstatus

Fair Isaac Corporation Conﬁdential and Proprietary Information

176

Reference Manual

problem.chgrowtype
Purpose
Synopsis

Changes the type of a row in the problem.
problem.chgrowtype(mindex, qrtype)

Arguments
mindexqrtypeExampleArray containing the rows (i.e. xpress.constraint objects, indices, or names).
Character array giving the new row types:
Lindicates a ≤ row;E
indicates an = row;G
indicates a ≥ row;R
indicates a range row;N
indicates a free row.

Here two rows are changed to an equality and a free row, respectively:
p.chgrowtype([con1, con2], ['E', 'N'])

Further information
A row can be changed to a range type row by ﬁrst changing the row to an R or L type row and thenchanging the range on the row using problem.chgrhsrange.
Related topics
problem.addrows, problem.chgcoltype, problem.chgrhs, problem.chgrhsrange,
problem.getrowtype.

Fair Isaac Corporation Conﬁdential and Proprietary Information

177

Reference Manual

problem.chgrowwt
Purpose
Synopsis

Set or change the initial penalty error weight for a row
problem.chgrowwt(rowindex, value)

Arguments
RowIndex
Value
ExampleThe row (i.e. xpress.constraint object, index, or name) whose weight is to be set orchanged.
The new value of the weight. May be None if not required.

The following example sets the initial weight of row number 2 to a ﬁxed value of 3.6 and the initial
weight of row 4 to a value twice the calculated default value.
p.chgrowwt(2, -3.6)
p.chgrowwt(4,2)

Further information
A positive value is interpreted as a multiplier of the default row weight calculated by Xpress SLP.
A negative value is interpreted as a ﬁxed value: the absolute value is used directly as the row weight.
The initial row weight is used only when the augmented structure is created. After that, the current
weighting can be accessed and changed using problem.getrowinfo.
Related topics
problem.getrowwt, problem.getrowinfo

Fair Isaac Corporation Conﬁdential and Proprietary Information

178

Reference Manual

problem.chgtolset
Purpose
Synopsis

Add or change a set of convergence tolerances used for SLP variables
problem.chgtolset(ntol, status, tols)

Arguments
ntol

Tolerance set for which values are to be changed. A zero value for nSLPTol will create
a new set.
Address of an integer holding a bitmap describing which tolerances are active in thisset. See below for the settings.
Array of 9 double precision values holding the values for the corresponding tolerances.

statustols
ExampleThe following example creates a new tolerance set with the default values for all tolerances except therelative delta tolerance, which is set to 0.005. It then changes the value of the absolute delta andabsolute impact tolerances in tolerance set 6 to 0.015
Tols = 9⁎[0]Tols[2] = 0.005
Status = 1<<2p.chgtolset(0, 1<<2, Tols)
Tols[1] = 0.015
Tols[5] = 0.015
Status = 1<<1 | 1<<5p.chgtolset(6, Status, Tols)

Further information
The bits in status are set to indicate that the corresponding tolerance is to be changed in thetolerance set. The meaning of the bits is as follows:
Entry / Bit

ToleranceXSLP constantXSLP bit constant0

Closure tolerance (TC)xslp_TOLSET_TC

xslp_TOLSETBIT_TC

1

Absolute delta tolerance (TA)xslp_TOLSET_TA

xslp_TOLSETBIT_TA

2

Relative delta tolerance (RA)xslp_TOLSET_RA

xslp_TOLSETBIT_RA

3

Absolute coefﬁcient tolerance (TM)xslp_TOLSET_TM

xslp_TOLSETBIT_TM

4

Relative coefﬁcient tolerance (RM)

xslp_TOLSET_RM

xslp_TOLSETBIT_RM

5

Absolute impact tolerance (TI)

xslp_TOLSET_TI

xslp_TOLSETBIT_TI

6

Relative impact tolerance (RI)

xslp_TOLSET_RI

xslp_TOLSETBIT_RI

7

Absolute slack tolerance (TS)xslp_TOLSET_TS

xslp_TOLSETBIT_TS

8

Relative slack tolerance (RS)xslp_TOLSET_RS

xslp_TOLSETBIT_RS

The xslp_TOLSET constants can be used to access the corresponding entry in the value arrays, whilethe xslp_TOLSETBIT constants are used to set or retrieve which tolerance values are used for a given
SLP variable. The members of the Tols array corresponding to nonzero bit settings in Status will be
used to change the tolerance set. So, for example, if bit 3 is set in Status, then Tols[3] will replace
the current value of the absolute coefﬁcient tolerance. If a bit is not set in Status, the value of thecorresponding element of Tols is unimportant.
Related topics
problem.addtolsets, problem.deltolsets, problem.gettolset, problem.loadtolsets

Fair Isaac Corporation Conﬁdential and Proprietary Information

179

Reference Manual

problem.chgvar
Purpose
SynopsisDeﬁne a column as an SLP variable or change the characteristics and values of an existing SLP variableproblem.chgvar(colindex, detrow, initstepbound, stepbound, penalty, damp,
initvalue, value, tolset, history, converged, vartype)

Arguments
colindex
detrow

The index of the matrix column.
Address of an integer holding the index of the determining row. Use -1 if there is no
determining row. May be None if not required.
initstepbound Address of a double precision variable holding the initial step bound size. May beNone if not required.
stepbound Address of a double precision variable holding the current step bound size. Use zero todisable the step bounds. May be None if not required.
penalty
Address of a double precision variable holding the weighting of the penalty cost forexceeding the step bounds. May be None if not required.
damp
Address of a double precision variable holding the damping factor for the variable. May
be None if not required.
initvalue Address of a double precision variable holding the initial value for the variable. May beNone if not required.
value
Address of a double precision variable holding the current value for the variable. May beNone if not required.
tolsetAddress of an integer holding the index of the tolerance set for this variable. Use zero if
there is no speciﬁc tolerance set. May be None if not required.
history
Address of an integer holding the history value for this variable. May be None if not
required.
converged Address of an integer holding the convergence status for this variable. May be None if
not required.
vartype
Address of an integer holding a bitmap deﬁning the existence of certain properties forthis variable:
Bit 1:
Variable has a delta vector
Bit 2:
Variable has an initial value
Bit 14: Variable is the reserved "=" column
May be None if not required.

ExampleThe following example sets an initial value of 1.42 and tolerance set 2 for column 25 in the matrix.
p.chgvar(25, None, None, None, None,
None, 1.42, None, 2,None, None, 1<<1 | 1<<2)
Note that bits 1 and 2 of vartype are set, indicating that the variable has a delta vector and an initialvalue. For columns already deﬁned as SLP variables, use problem.getvar to obtain the current valueof vartype because other bits may already have been set by the system.

Further information
If any of the arguments is None then the corresponding information for the variable will be left
unaltered. If the information is new (i.e. the column was not previously deﬁned as an SLP variable) thenthe default values will be used.
Changing Value, History or Converged is only effective during SLP iterations.

Fair Isaac Corporation Conﬁdential and Proprietary Information

180

Reference Manual

Changing initvalue and initstepbound is only effective before problem.construct. If a valueof xpress.infinity is used in the value for stepbound or initstepbound, the delta will never
have step bounds applied, and will almost always be regarded as converged.
Related topics
problem.addvars, problem.delvars, problem.getvar, problem.loadvars

Fair Isaac Corporation Conﬁdential and Proprietary Information

181

Reference Manual

problem.construct
Purpose
Synopsis
ExampleCreate the full augmented SLP matrix and data structures, ready for optimization
problem.construct()
The following example constructs the augmented matrix and then outputs the result in MPS format toa ﬁle called augment.mat# creation and/or loading of data
# precedes this segment of codep.construct()p.write("augment","l")The "l" ﬂag causes output of the current linear problem (which is now the augmented structure and thecurrent linearization) rather than the original nonlinear problem.

Further information
construct adds new rows and columns to the SLP matrix and calculates initial values for the
non-linear coefﬁcients. Which rows and columns are added will depend on the setting of
xslp_augmentation. Names for the new rows and columns are generated automatically, based on
the existing names and the string control variables xslp_xxxformat.
Once construct has been called, no new rows, columns or non-linear coefﬁcients can be added to the
problem. Any rows or columns which will be required must be added ﬁrst. Non-linear coefﬁcients mustnot be changed; constant matrix elements can generally be changed after construct, but not after
problem.presolve if used.
construct is called automatically by the SLP optimization procedure, and so only needs to be called
explicitly if changes need to be made between the augmentation and the optimization.
Related topics
problem.presolve

Fair Isaac Corporation Conﬁdential and Proprietary Information

182

Reference Manual

problem.copy
Purpose
Synopsis

Obtains a copy of a problem.
p = problem.copy()

Examplep = xpress.problem()x = [xpress.var() for _ in range(10)]p.addVariable(x)p.addConstraint(xpress.Sum(x) <= 10)
p2 = p.copy() # add a constraint that won't be in p
p2.addConstraint(xpress.Sum(x) >= 6) # x[0] is deleted from p2
p2.delVariable(x[0])Further information
The objects of the copied problem (variables, constraints, SOSs) are the same as the source problem,i.e., the one of which a copy was created. Therefore, any object that existed in the source problem canbe addressed and used in the copy problem.
Related topics
problem.copycallbacks.

Fair Isaac Corporation Conﬁdential and Proprietary Information

183

Reference Manual

problem.copycallbacks
Purpose
Synopsis

Copies callback functions deﬁned for one problem to another.
problem.copycallbacks(src)

Argument
src
ExampleThe problem from which the callbacks are copied.

The following sets up a message callback function callback for problem prob1 and then copies thisto the problem prob2.
prob1 = xp.problem()prob1.addcbmessage(callback, None, 0)
prob2 = xp.problem()prob2.copycallbacks(prob1)

Related topics
problem.copycontrols, problem.copy.

Fair Isaac Corporation Conﬁdential and Proprietary Information

184

Reference Manual

problem.copycontrols
Purpose
Synopsis

Copies controls deﬁned for one problem to another.
problem.copycontrols(src)

Argument
src
ExampleThe problem from which the controls are copied.

The following turns off presolve for problem prob1 and then copies this and other control values to the
problem prob2:
prob1 = xpress.problem()prob2 = xpress.problem()prob1.controls.presolve = 0
prob2.copycontrols(prob1)

Related topics
problem.copycallbacks.

Fair Isaac Corporation Conﬁdential and Proprietary Information

185

Reference Manual

problem.crossoverlpsol
Purpose

Synopsis

Provides a basic optimal solution for a given solution of an LP problem. This function behaves like thecrossover after the barrier algorithm.
status = problem.crossoverlpsol()

Argument
statusExampleOne of:0
The crossover was successful.
1
The crossover was not performed because the problem has no solution.

This example loads a problem, loads a solution for the problem and then uses crossoverlpsol toﬁnd a basic optimal solution.
p = xp.problem()p.read('problem.mps')
status = p.loadlpsol(x, None, dual, None)
status = p.crossoverlpsol()
A solution can also be loaded from an ASCII solution ﬁle using problem.readslxsol.

Further information
1. The crossover performs two phases: a crossover phase for ﬁnding a basic solution and a clean-up
phase for ﬁnding a basic optimal solution. Setting algaftercrossover to 0 will allow the crossoverto skip the clean-up phase.
2. The given solution is expected to be feasible or nearly feasible, otherwise the crossover may take along time to ﬁnd a basic feasible solution. More importantly, the given solution is expected to have asmall duality gap. A small duality gap indicates that the given solution is close to the optimal solution.
If the given solution is far away from the optimal solution, the clean-up phase may need many simplex
iterations to move to a basic optimal solution.
Related topics
problem.loadlpsol, problem.readslxsol

Fair Isaac Corporation Conﬁdential and Proprietary Information

186

Reference Manual

problem.delcoefs
Purpose
Synopsis

Delete coefﬁcients from the current problem
problem.delcoefs(rowindex, colindex)

Arguments
rowindex
colindex

rows (i.e. xpress.constraint objects, indices, or names) of the SLP coefﬁcients todelete.
columns (i.e. xpress.var objects, indices, or names) of the SLP coefﬁcients to delete.

Related topics
problem.addcoefs, problem.chgnlcoef, problem.chgccoef, problem.getcoefformula,problem.getccoef, problem.loadcoefs

Fair Isaac Corporation Conﬁdential and Proprietary Information

187

Reference Manual

problem.delConstraint
Purpose
Synopsis

Delete one or more constraints from the problem.
problem.delConstraint(c1, c2, ...)

ExampleN = 20x = [xpress.var() for i in range(N)]p = xpress.problem()p.addVariable(x)p.addConstraint(x[i] >= x[i+1] for i in range(N-1))
p.delConstraint(2) # deletes x[2] >= x[3]Further information
1. All arguments can be single constraints or lists, tuples, or NumPy arrays of variables. They can also beconstraint indices (from 0 to ROWS-1). The index of variables, constraints, and SOSs can be obtainedwith problem.getIndex.
2. Indicator constraints are indexed as constraints, hence they can also be deleted with this function.

Fair Isaac Corporation Conﬁdential and Proprietary Information

188

Reference Manual

problem.delcpcuts
Purpose

Synopsis

During the branch and bound search, cuts are stored in the cut pool to be applied at descendant nodes.
These cuts may be removed from a given node using problem.delcuts, but if this is to be applied ina large number of cases, it may be preferable to remove the cut completely from the cut pool. This isachieved using delcpcuts.
problem.delcpcuts(itype, interp, cutind)Arguments
itype
interpcutindUser deﬁned cut type to match against.
Way in which the cut itype is interpreted:-1
match all cut types;
1treat cut types as numbers;
2
treat cut types as bit maps - delete if any bit matches any bit set in itype;3
treat cut types as bit maps - delete if all bits match those set in itype.
Array containing the cuts which are to be deleted.

Related topics
problem.addcuts, problem.delcuts, problem.loadcuts, Section "Working with the cut
manager" of the Xpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

189

Reference Manual

problem.delcuts
Purpose

Synopsis

Deletes cuts from the matrix at the current node. Cuts from the parent node which have been
automatically restored may be deleted as well as cuts added to the current node using
problem.addcuts or problem.loadcuts. The cuts to be deleted can be speciﬁed in a number ofways. If a cut is ruled out by any one of the criteria it will not be deleted.
problem.delcuts(ibasis, itype, interp, delta, cutind)Arguments
ibasisitype
interpdelta
cutindEnsures the basis will be valid if set to 1. If set to 0, cuts with non-basic slacks may bedeleted.
User deﬁned type of the cut to be deleted.
Way in which the cut itype is interpreted:-1
match all cut types;
1treat cut types as numbers;
2
treat cut types as bit maps - delete if any bit matches any bit set in itype;3
treat cut types as bit maps - delete if all bits match those set in itype.
Only delete cuts with an absolute slack value greater than delta. To delete all the cuts,
this argument should be set to -xpress.infinity.
Array containing the cuts which are to be deleted.

Further information
1. It is usually best to drop only those cuts with basic slacks, otherwise the basis will no longer be valid
and it may take many iterations to recover an optimal basis. If the ibasis parameter is set to 1, thiswill ensure that cuts with non-basic slacks will not be deleted even if the other parameters specify thatthese cuts should be deleted. It is highly recommended that the ibasis parameter is always set to 1.
2. The cuts to be deleted can also be speciﬁed by the size of the slack variable for the cut. Only those cutswith a slack value greater than the delta parameter will be deleted.
3. A list of indices of the cuts to be deleted can also be provided. The list of active cuts at a node can beobtained with the problem.getcutlist command.
Related topics
problem.addcuts, problem.delcpcuts, problem.getcutlist, problem.loadcuts, Section"Working with the cut manager" of the Xpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

190

Reference Manual

problem.delgencons
Purpose
Synopsis

Delete general constraints from a problem.
problem.delgencons(mindex)

Argument
mindexExampleAn integer array containing the general constraints to delete.

In this example, general constraints 0 and 2 are deleted from the problem:
mindex = [0, 2]
prob.delgencons(mindex)

Further information
After general constraints have been deleted from a problem, the indices of the remaining constraints
are reduced down so that the general constraints are always numbered from 0 to
prob.attributes.gencons - 1 where prob.attributes.gencons contains the number of
non-deleted general constraints in the problem.
Related topics
problem.addgencons, problem.getgencons, xpress.And, xpress.Or, xpress.max,
xpress.min, xpress.abs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

191

Reference Manual

problem.delindicators
Purpose

Synopsis

Delete indicator constraints. This turns the speciﬁed rows into normal rows (not controlled by indicatorvariables).
problem.delindicators(first=None, last=None);

Arguments
first
last
ExampleFirst row in the range.
Last row in the range (inclusive).

In this example, if any of the ﬁrst two rows of the matrix is an indicator constraint, they are turned into
normal rows:
prob.delindicators(0,1)

Further information
This function has no effect on rows that are not indicator constraints.
Related topics
problem.getindicators, problem.setindicators.

Fair Isaac Corporation Conﬁdential and Proprietary Information

192

Reference Manual

problem.delpwlcons
Purpose
Synopsis

Delete piecewise linear constraints from a problem.
problem.delpwlcons(mindex)

Argument
mindexExampleAn integer array containing the piecewise linear constraints to delete.

In this example, piecewise linear constraints 0 and 2 are deleted from the problem:
mindex = [0,2]prob.delpwlcons(mindex)

Further information
After piecewise linear constraints have been deleted from a problem, the indices of the remaining
constraints are reduced so that the piecewise linear constraints are always numbered from 0 to
problem.attributes.pwlcons - 1 where problem.attributes.pwlcons is the problem
attribute containing the number of non-deleted piecewise linear constraints in the problem.
Related topics
problem.addpwlcons, problem.getpwlcons, xpress.pwl.

Fair Isaac Corporation Conﬁdential and Proprietary Information

193

Reference Manual

problem.delqmatrix
Purpose
Synopsis

Deletes the quadratic part of a row or of the objective function.
problem.delqmatrix(row)Argumentrow

Index of row from which the quadratic part is to be deleted.

Further information
If a row index of -1 is used, the function deletes the quadratic coefﬁcients from the objective function.
Related topics
problem.addrows.

Fair Isaac Corporation Conﬁdential and Proprietary Information

194

Reference Manual

problem.delSOS
Purpose
Synopsis

Delete one or more SOSs from the problem.
problem.delSOS(s1, s2, ...)

ExampleN = 20x = [xpress.var() for i in range(N)]p = xpress.problem()p.addVariable(x)s = xpress.sos(x, i+1 for i in range(N))
p.addSOS(s)p.delSOS(s)Further information
All arguments can be single SOSs or lists, tuples, or NumPy arrays of SOSs. They can also be constraint
indices (from 0 to ROWS-1). The index of variables, constraints, and SOSs can be obtained withproblem.getIndex.

Fair Isaac Corporation Conﬁdential and Proprietary Information

195

Reference Manual

problem.deltolsets
Purpose
Synopsis

Delete tolerance sets from the current problem
problem.deltolsets(index)

Argument
tolsetindex

Indices of tolerance sets to delete.

Related topics
problem.addtolsets, problem.chgtolset, problem.gettolset, problem.loadtolsets

Fair Isaac Corporation Conﬁdential and Proprietary Information

196

Reference Manual

problem.delVariable
Purpose
Synopsis

Delete one or more variables from the problem.
problem.delVariable(x1, x2, ...)

ExampleN = 20x = [xpress.var() for i in range(N)]p = xpress.problem()p.addVariable(x)p.addConstraint(x[i] >= x[i+1] for i in range(N-1))# deletes x[2], x[3], i.e., third and fourth variablep.delVariable(x[2:4])
Further information
All arguments can be single variables or lists, tuples, or NumPy arrays of variables. They can also bevariable indices (from 0 to COLS-1). The index of variables, constraints, and SOSs can be obtained withproblem.getIndex.

Fair Isaac Corporation Conﬁdential and Proprietary Information

197

Reference Manual

problem.delvars
Purpose
Synopsis

Convert SLP variables to normal columns. Variables must not appear in SLP structures
problem.delvars(index)

Argument
colindex

Columns to be converted to linear ones.

Further information
The SLP variables to be converted to linear, non SLP columns must not be in use by any other SLP
structure (coefﬁcients, initial value formulae, delayed columns). Use the appropriate deletion or change
functions to remove them ﬁrst.
Related topics
problem.addvars, problem.chgvar, problem.getvar, problem.loadvars

Fair Isaac Corporation Conﬁdential and Proprietary Information

198

Reference Manual

problem.dumpcontrols
Purpose

Synopsis

Displays the list of controls and their current value for those controls that have been set to a non
default value.
problem.dumpcontrols()

Related topics
problem.setdefaults

Fair Isaac Corporation Conﬁdential and Proprietary Information

199

Reference Manual

problem.estimaterowdualranges
Purpose

Synopsis

Performs a dual side range sensitivity analysis, i.e. calculates estimates for the possible ranges fordual values.
problem.estimaterowdualranges(rowIndices, iterationLimit, minDualActivity,
maxDualActivity)

Arguments
rowIndices rows (i.e. xpress.constraint objects, indices, or names) to analyze.
iterationLimit Effort limit expressed as simplex iterations per row.
minDualActivity Estimated lower bounds on the possible dual ranges.
maxDualActivity Estimated upper bounds on the possible dual ranges.
Further information
This function may provide better results for individual row dual ranges when called for a larger numberof rows.
Related topics
problem.lpoptimize, problem.strongbranch

Fair Isaac Corporation Conﬁdential and Proprietary Information

200

Reference Manual

problem.evaluatecoef
Purpose
Synopsis

Evaluate a coefﬁcient using the current values of the variables
value = problem.evaluatecoef(rowindex, colindex)

Arguments
rowindex
colindexvalue
ExampleRow (i.e. xpress.constraint object, index, or name).
Column (i.e. xpress.var object, index, or name).
The result of the calculation.

The following example sets the value of column 5 to 1.42 and then calculates the coefﬁcient in row 2,
column 3. If the coefﬁcient depends on column 5, then a value of 1.42 will be used in the calculation.
p.chgvar(5, None, None, None, None,
None, None, 1.42, None, None, None,
None)value = p.evaluatecoef(2, 3)

Further information
The values of the variables are obtained from the solution, or from the Value setting of an SLP variable(see problem.chgvar and problem.getvar).
Related topics
problem.chgvar, problem.evaluateformula, problem.getvar

Fair Isaac Corporation Conﬁdential and Proprietary Information

201

Reference Manual

problem.evaluateformulaPurpose
Synopsis

Evaluate a formula using the current values of the variables
result = problem.evaluateformula(parsed, type, value)

Arguments
parsedtype
value
resultExampleinteger indicating whether the formula of the item is in internal unparsed format(Parsed=0) or parsed (reverse Polish) format (Parsed=1).
Integer array of token types for the formula.
Double array of values corresponding to Type.
The result of the calculation.

The following example calculates the value of column 3 divided by column 6.
type = [xp.xslp_op_var, xp.xslp_op_var, xp.xslp_op_op,
xp.xslp_op_eof]
value = [3,6,xp.xslp_ifun_divide, 0]value = p.evaluateformula(1, type, value)

Further information
The formula in Type and Value must be terminated by an xslp_op_eof token.
The formula cannot include "complicated" functions, such as user functions which return more than
one value.
Related topics
problem.evaluatecoef

Fair Isaac Corporation Conﬁdential and Proprietary Information

202

Reference Manual

problem.ﬁxglobals
Purpose

Synopsis

Fixes all the global entities to the values of the last found MIP solution. This is useful for ﬁnding the
reduced costs for the continuous variables after the global variables have been ﬁxed to their optimalvalues.
problem.fixglobals(ifround)Argument
ifround
ExampleIf all global entities should be rounded to the nearest discrete value in the solution
before being ﬁxed.

This example performs a global search on problem myprob and then uses fixglobals before solving
the remaining linear problem:
p.read("myprob", "")p.mipoptimize()
p.fixglobals(1)p.lpoptimize()
p.writeprtsol()

Further information
1. Because of tolerances, it is possible for e.g. a binary variable to be slightly fractional in the MIP
solution, where it might have the value 0.999999 instead of being at exactly 1.0. With ifround = 0,such a binary will be ﬁxed at 0.999999, but with ifround = 1, it will be ﬁxed at 1.0.
2. This command is useful for inspecting the reduced costs of the continuous variables in a problem after
the global entities have been ﬁxed. Sensitivity analysis can also be performed on the continuous
variables in a MIP problem using problem.rhssa or problem.objsa after calling fixglobals.
Related topics
problem.mipoptimize.

Fair Isaac Corporation Conﬁdential and Proprietary Information

203

Reference Manual

problem.ﬁxpenalties
Purpose
SynopsisFixe the values of the error vectors
status = problem.fixpenalties()

Argument
statusReturn status after ﬁxing the penalty variables: 0 is successful, nonzero otherwise.

Further information
The function ﬁxes the values of all error vectors on their current values. It also removes their objective
cost contribution.
The function is intended to support post optimization analysis, by removing any possible direct effectof the error vectors from the dual and reduced cost values.
The fixpenalties function will automatically reoptimize the linearization. However, as the XSLP
convergence and infeasibility checks (regarding the original non-linear problem) will not be carried out,
this function will not update the SLP solution itself. The updated values will be accessible using
getlpsolution instead.

Fair Isaac Corporation Conﬁdential and Proprietary Information

204

Reference Manual

problem.ftranPurpose
SynopsisPre-multiplies a (column) vector provided by the user by the inverse of the current matrix.
problem.ftran(vec)

Argument
vec
ExampleArray of length problem.attributes.rows containing the values which are to be
multiplied by the basis inverse. The transformed values appear in the array.

To get the (unscaled) tableau column of structural variable number jcol, assuming that all arrays havebeen dimensioned, do the following:y = [0,1,0,0]
p.ftran(y)print("ftran result:", y)Further information
If the problem is in a presolved state, the function will work with the basis for the presolved problem.
Related topics
problem.btran.

Fair Isaac Corporation Conﬁdential and Proprietary Information

205

Reference Manual

problem.getAttrib
Purpose
Synopsis

Retrieves one or more attributes of a problem.
a = problem.getAttrib(attr1, attr2, ...)

Examplep = xpress.problem()p.read("example.lp")
print(p.getAttrib('cols'), "columns and ",p.getAttrib('rows'), "rows")
prob_attrib = p.getAttrib()
attr_subset = p.getAttrib(['cols', 'rows'])
Further information
This function can be passed either a single attribute name, whose value will be returned, or a list of
attribute names, in which case the return value is a dictionary associating each key in the list with its
value. If no argument is provided, a dictionary containing all attributes of the problem will be returned.

Fair Isaac Corporation Conﬁdential and Proprietary Information

206

Reference Manual

problem.getattribinfo
Purpose

Synopsis

Accesses the id number and the type information of an attribute given its name. An attribute name may
be for example ’rows’. The function will return an id number of 0 and a type value of notdefined if
the name is not recognized as an attribute name. Note that this will occur if the name is a control nameand not an attribute name.
(id,type) = problem.getattribinfo(name)Argument
name

The name of the attribute to be queried. Names are case-insensitive. A full list of all
attributes may be found in the Xpress Optimizer reference manual.

Related topics
problem.getcontrolinfo.

Fair Isaac Corporation Conﬁdential and Proprietary Information

207

Reference Manual

problem.getbasis
Purpose
Synopsis

Returns the current basis into the user’s data arrays.
problem.getbasis(rstatus, cstatus)

Arguments
rstatuscstatus

ExampleArray of length problem.attributes.rows to the basis status of the slack, surplus
or artiﬁcial variable associated with each row. The status will be one of:0
slack, surplus or artiﬁcial is non-basic at lower bound;1
slack, surplus or artiﬁcial is basic;2
slack or surplus is non-basic at upper bound.
3
slack or surplus is super-basic.
May be None if not required.
Array of length problem.attributes.cols to hold the basis status of the columns
in the constraint matrix. The status will be one of:0variable is non-basic at lower bound, or superbasic at zero if the variable has
no lower bound;1
variable is basic;
2
variable is non-basic at upper bound;3
variable is super-basic.
May be None if not required.

The following example minimizes a problem before saving the basis for later:
rstatus = []cstatus = []p.lpoptimize()p.getbasis(rstatus, cstatus)

Related topics
problem.getpresolvebasis, problem.loadbasis, problem.loadpresolvebasis.

Fair Isaac Corporation Conﬁdential and Proprietary Information

208

Reference Manual

problem.getbasisval
Purpose
Synopsis

Returns the current basis status for a speciﬁc column or row.
rstatus, cstatus = problem.getbasisval(row=None, column=None)

Argumentsrow
columnrstatuscstatusRow index to get the row basis status for.
Column index to get the column basis status for.
The row basis status will be returned, or 0 if row was passed as None.
The value of the column basis status, or 0 if column==None.

Related topics
problem.getbasis, problem.getpresolvebasis, problem.loadbasis,problem.loadpresolvebasis

Fair Isaac Corporation Conﬁdential and Proprietary Information

209

Reference Manual

problem.getccoef
Purpose
Synopsis

Retrieve a single matrix coefﬁcient as a formula in a character string(factor, formula) = problem.getccoef(rowindex, colindex, flen)

Arguments
RowIndex
ColIndex
FactorFormulafLen

Integer holding the row index for the coefﬁcient.
Integer holding the column index for the coefﬁcient.
Address of a double precision variable to receive the value of the constant factor
multiplying the formula in the coefﬁcient.
Character buffer in which the formula will be placed in the same format as used for
input from a ﬁle. The formula will be null terminated.
Maximum length of returned formula.

Return value0
Normal return.
1
Formula is too long for the buffer and has been truncated.
other Error.
ExampleThe following example displays the formula for the coefﬁcient in row 2, column 3:(factor, formula) = p.getccoef(2, 3, 60)

Further information
If the requested coefﬁcient is constant, then factor will be set to 1.0 and the value will be formatted informula.
If the length of the formula would exceed flen - 1, the formula is truncated to the last token that will
ﬁt, and the (partial) formula is terminated with a null character.
Related topics
problem.chgccoef, problem.chgnlcoef, problem.getcoefformula

Fair Isaac Corporation Conﬁdential and Proprietary Information

210

Reference Manual

problem.getcoef
Purpose
Synopsis

Returns a single coefﬁcient in the constraint matrix.
coef = problem.getcoef(irow, icol)

Arguments
irow
icol

Row of the constraint matrix.
Column of the constraint matrix.

Further information
It is quite inefﬁcient to get several coefﬁcients with the getcoef function. It is better to use getcols
or getrows.
Related topics
problem.getcols, problem.getrows.

Fair Isaac Corporation Conﬁdential and Proprietary Information

211

Reference Manual

problem.getcoefformulaPurpose
Synopsis

Retrieve a single matrix coefﬁcient as a formula split into tokens(factor, tokencount, type, value) = problem.getcoefformula(rowindex,
colindex, parsed, bufsize)

Arguments
rowindex
colindex
factorparsedThe row index for the coefﬁcient.
The column index for the coefﬁcient.
The value of the constant factor multiplying the formula in the coefﬁcient.
Integer indicating whether the formula of the item is to be returned in internal unparsed
format (Parsed=0) or parsed (reverse Polish) format (Parsed=1).
bufsize
Maximum number of tokens to return, i.e. length of the Type and Value arrays.
tokencount Number of tokens returned in Type and Value.
type
Array to hold the token types for the formula.
value
Array of values corresponding to Type.

ExampleThe following example displays the formula for the coefﬁcient in row 2, column 3 in unparsed form:(fac, tc, type, value) = p.getcoefformula(2, 3, 0, 10)

Further information
The type and value arrays are terminated by an xslp_op_eof token.
If the requested coefﬁcient is constant, then factor will be set to 1.0 and the value will be returned
with token type xslp_op_con.
Related topics
problem.chgccoef, problem.chgnlcoef, problem.getccoef

Fair Isaac Corporation Conﬁdential and Proprietary Information

212

Reference Manual

problem.getcoefs
Purpose
Synopsis

Retrieve the list of positions of the nonlinear coefﬁcients in the problem
problem.getcoefs(rowindex, colindex)

Arguments
rowindices Row positions of the coefﬁcients. May be None if not required.
colindices Column positions of the coefﬁcients. May be None if not required.
Related topics
problem.getccoef, problem.getcoefformula

Fair Isaac Corporation Conﬁdential and Proprietary Information

213

Reference Manual

problem.getcolinfo
Purpose
Synopsis

Get current column information.
problem.getcolinfo(infotype, colindex)

Arguments
InfoType
ColIndex
Info

Type of information (see below)
Column (i.e. xpress.var object, index, or name) whose information is to be handled
Address of information to be set or retrieved

Further information
If the data is not available, the type of the returned Info is set to None.
The following constants are provided for column information handling:
xpress.colinfo_value

Get the current value of the column

xpress.colinfo_rdj

Get the current reduced cost of the column

xpress.colinfo_deltaindex

Get the delta variable index associated to the column

xpress.colinfo_delta

Get the delta value (change since previous value) of the column

xpress.colinfo_deltadj

Get the delta variables reduced cost

xpress.colinfo_updaterow Get the index of the update (or step bound) row associated to thecolumnxpress.colinfo_sb

Get the step bound on the variable

xpress.colinfo_sbdual

Get the dual multiplier of the step bound row for the variable

Fair Isaac Corporation Conﬁdential and Proprietary Information

214

Reference Manual

problem.getcols
Purpose
Synopsis

Returns the nonzeros in the constraint matrix for the columns in a given range.
problem.getcols (mstart, mrwind, dmatval, size, first, last)

Arguments
mstartmrwinddmatval
size
first
last
ExampleArray which will be ﬁlled with the indices indicating the starting offsets in the mrwind
and dmatval arrays for each requested column. It must be of length at least
last-first+2. Column i starts at position mstart[i] in the mrwind and dmatvalarrays, and has mstart[i+1]-mstart[i] elements in it. May be None if not required,but must be speciﬁed.
Array of length size which will be ﬁlled with the rows of the nonzero coefﬁcents foreach column. May be None if not required, but must be speciﬁed.
Array of length size which will be ﬁlled with the nonzero coefﬁcient values. May beNone if not required, but must be speciﬁed.
The size of the mrwind and dmatval arrays. This is the maximum number of nonzero
coefﬁcients that the Optimizer is allowed to return.
First column in the range.
Last column in the range.

The following examples retrieves the mstart vector of the problem:

p = xpress.problem()p.read("example", "l")mstart = []p.getcols(mstart, mrwind=None, dmatval=None, size=100, first=0, last=p.attribut
Further information
It is possible to obtain just the number of elements in the range of columns by replacing mstart,
mrwind and dmatval by None, as in the example. In this case, size must be set to 0 to indicate thatthe length of arrays passed is zero. This is demonstrated in the example above.
Related topics
problem.getrows.

Fair Isaac Corporation Conﬁdential and Proprietary Information

215

Reference Manual

problem.getcoltype
Purpose
Synopsis

Returns the column types for the columns in a given range.
problem.getcoltype(coltype, first, last)

Arguments
coltype

first
last
ExampleCharacter array of length last-first+1 where the column types will be returned:
C
indicates a continuous variable;I
indicates an integer variable;
B
indicates a binary variable;
S
indicates a semi-continuous variable;R
indicates a semi-continuous integer variable;P
indicates a partial integer variable.
First column in the range.
Last column in the range.

This example ﬁnds the types for all columns in the matrix and prints them:coltype = []p.getcoltype(coltype, 0, p.attributes.cols - 1)
print("coltypes:", coltype)

Related topics
problem.chgcoltype, problem.getrowtype.

Fair Isaac Corporation Conﬁdential and Proprietary Information

216

Reference Manual

problem.getConstraint
Purpose

Synopsis

Returns one or more constraint of a problem corresponding to one or more indices passed asarguments. These constraints are returned as Python objects and can be used to access andmanipulate the problem.
r = problem.getConstraint(index, first, last)

Arguments
first
last
index

(optional) The ﬁrst index of the constraints to be returned. It must be between 0 and
ROWS - 1.
(optional) The last index of the constraints to be returned. It must be between 0 and
ROWS - 1.
(optional) Either an integer or a list of integers (not necessarily sorted) with theindex/indices of all constraints to be returned, all between 0 and ROWS - 1

Further information
All arguments are optional. If neither of them is provided, the return value is a list with all constraints ofthe problem. Otherwise, either first and last or just index can be passed.
Related topics
problem.getVariable, problem.getSOS.

Fair Isaac Corporation Conﬁdential and Proprietary Information

217

Reference Manual

problem.getControl
Purpose
Synopsis

Retrieves one or more controls of a problem.
c = problem.getControl(ctrl1, ctrl2, ...)

Examplep = xpress.problem()[...]print("tolerance for feasibility and optimality: ",p.getControl('feastol'), p.getControl('miprelstop'))all_ctrls = p.getControl()
ctrl_subset = p.getControl(['presolve', 'miprelstop', 'feastol'])
Further information
This function can be passed either a single control name, whose value will be returned, or a list ofcontrol names, in which case the return value is a dictionary associating each key in the list with its
value. If no argument is provided, a dictionary containing all controls of the problem will be returned.
Related topics
problem.setControl.

Fair Isaac Corporation Conﬁdential and Proprietary Information

218

Reference Manual

problem.getcontrolinfo
Purpose

Synopsis

Accesses the id number and the type information of a control given its name. A control name may befor example ’presolve’. The function will return an id number of 0 and a type value of notdefined
if the name is not recognized as a control name. Note that this will occur if the name is an attributename rather than a control name.
(id,type) = problem.getcontrolinfo(name)Argument
name

The name of the control to be queried. Names are case-insensitive. A full list of allcontrol may be found in the Xpress Optimizer reference manual.

Related topics
problem.getattribinfo.

Fair Isaac Corporation Conﬁdential and Proprietary Information219

Reference Manual

problem.getcpcutlist
Purpose
Synopsis

Returns a list of cut indices from the cut pool.
ncuts = problem.getcpcutlist(itype, interp, delta, size, cutind, viol)

Arguments
itype
interpdelta
size
mcutinddviol

The user deﬁned type of the cuts to be returned.
Way in which the cut type is interpreted:-1
get all cuts;
1
treat cut types as numbers;
2
treat cut types as bit maps - get cut if any bit matches any bit set in itype;3
treat cut types as bit maps - get cut if all bits match those set in itype.
Only those cuts with a signed violation greater than delta will be returned.
Maximum number of cuts to be returned.
Array of length size where the cuts will be returned.
Array of length size where the values of the signed violations of the cuts will be
returned.

Further information
1. The violated cuts can be obtained by setting the delta parameter to the size of the (signed) violation
required. If unviolated cuts are required as well, delta may be set to _MINUSINFINITY which isdeﬁned in the library header ﬁle.
2. If the number of active cuts is greater than size, only size cuts will be returned. Otherwise only theexisting cuts will be used to ﬁll in the positions of mcutind.
3. In case of a cut of type ’L’, the violation equals the negative of the slack associated with the row of thecut. In case of a cut of type ’G’, the violation equals the slack associated with the row of the cut. For
cuts of type ’E’, the violation equals the absolute value of the slack.
4. Please note that the violations returned are absolute violations, while feasibility is checked by the
Optimizer in the scaled problem.
Related topics
problem.delcpcuts, problem.getcpcuts, problem.getcutlist, problem.loadcuts,
problem.getcutmap, problem.getcutslack, Section "Working with the cut manager" of theXpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

220

Reference Manual

problem.getcpcuts
Purpose

Synopsis

Returns cuts from the cut pool. A list of cuts in the array mindex must be passed to the routine. The
columns and elements of the cut will be returned in the regions pointed to by the mcols and dmatvalparameters. The columns and elements will be stored contiguously and the starting point of each cut
will be returned in the region pointed to by the mstart parameter.
problem.getcpcuts(mindex, size, type, rtype, mstart, mcols, dmatval, drhs)

Arguments
mindex
size
type
rtype
mstartcols
matvalrhs

List containing the cuts.
Maximum number of columns of the cuts to be returned.
List where the cut types will be returned.
Character list where the sense of the cuts (L, G, or E) will be returned.
Array containing the offsets into the mcols and dmatval arrays. The last element
indicates the total number of elements.
Array where the columns of the cuts will be returned.
Array where the coefﬁcients will be returned.
Array where the right hand side elements for the cuts will be returned.

Related topics
problem.getcpcutlist, problem.getcutlist, Section "Working with the cut manager" of theXpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

221

Reference Manual

problem.getcutlist
Purpose
Synopsis

Retrieves a list of cuts for the cuts active at the current node.
problem.getcutlist(itype, interp, size, cutind)Arguments
itype
interpsize
cutindUser deﬁned type of the cuts to be returned. A value of -1 indicates return all active cuts.
Way in which the cut type is interpreted:-1
get all cuts;
1
treat cut types as numbers;
2
treat cut types as bit maps - get cut if any bit matches any bit set in itype;3
treat cut types as bit maps - get cut if all bits match those set in itype.
Maximum number of cuts to be retrieved.
Array of length size where the cuts will be returned.

Further information
If the number of active cuts is greater than size, then size cuts will be returned. Otherwise only the
positions corresponding to the number of active cuts will be ﬁlled in cutind.
Related topics
problem.getcpcutlist, problem.getcpcuts, Section "Working with the cut manager" of theXpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

222

Reference Manual

problem.getcutmap
Purpose

Synopsis

Returns in which rows a list of cuts are currently loaded into the Optimizer. This is useful for example toretrieve the duals associated with active cuts.
problem.getcutmap(cuts, cutmap)

Arguments
cuts
cutmapArray with the cuts for which the row index is requested.
Array where the rows are returned.

Further information
For cuts currently not loaded into the problem, a row index of -1 is returned.
Related topics
problem.getcpcutlist, problem.delcpcuts, problem.getcutlist, problem.loadcuts,
problem.getcutslack, problem.getcpcuts, Section "Working with the cut manager" of theXpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

223

Reference Manual

problem.getcutslack
Purpose

Synopsis

Used to calculate the slack value of a cut with respect to the current LP relaxation solution. The slack is
calculated from the cut itself, and might be requested for any cut (even if it is not currently loaded into
the problem).
slack = problem.getcutslack(cut)Arguments
cuts
slack

Cut object for which the slack is to be calculated.
Value of the slack.

Related topics
problem.getcpcutlist, problem.delcpcuts, problem.getcutlist, problem.loadcuts,
problem.getcutmap, problem.getcpcuts, Section "Working with the cut manager" of the Xpress
Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

224

Reference Manual

problem.getdirs
Purpose

Synopsis

Returns the directives that have been loaded into a problem. Priorities, forced branching directions andpseudo costs can be returned. If called after presolve, getdirs will get the directives for the presolved
problem.
problem.getdirs(mcols, mpri, qbr, dupc, ddpc)

Arguments
mcols

mpri
qbr

dupc
ddpc

Array containing the column numbers (0, 1, 2,...) or negative values corresponding to
special ordered sets (the ﬁrst set numbered -1, the second numbered -2,...). May beNone if not required.
Array containing the priorities for the columns and sets. May be None if not required.
Character array with the branching direction for each column or set:U
the entity is to be forced up;
Dthe entity is to be forced down;N
not speciﬁed.
Array containing the up pseudo costs for the columns and sets. May be None if not
required.
Array containing the down pseudo costs for the columns and sets. May be None if not
required.

Further information
The size of all lists is at most MIPENTS, obtainable from problem.attributes.mipents.
Related topics
problem.loaddirs, problem.loadpresolvedirs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

225

Reference Manual

problem.getdf
Purpose
Synopsis

Get a distribution factor
value = problem.getdf(colindex, rowindex)

Arguments
colindex
rowindexvalue
ExampleThe column (i.e. xpress.var object, index, or name) whose distribution factor is to be
retrieved.
The row (i.e. xpress.constraint object, index, or name) from which the distribution
factor is to be taken.
The value of the distribution factor.

The following example retrieves the value of the distribution factor for column 282 in row 134 andchanges it to be twice as large.
value = p.getdf(282,134)
value ⁎= 2
p.chgdf(282,134,calue)

Further information
The distribution factor of a column in a row is the matrix coefﬁcient of the corresponding delta vector in
the row. Distribution factors are used in conventional recursion models, and are essentially normalizedﬁrst-order derivatives. Xpress SLP can accept distribution factors instead of initial values, provided thatthe values of the variables involved can all be calculated after optimization using determining rows, orby a callback.
Related topics
problem.adddfs, problem.chgdf, problem.loaddfs

Fair Isaac Corporation Conﬁdential and Proprietary Information

226

Reference Manual

problem.getDual
Purpose

Synopsis

Return the dual for all constraints of the problem w.r.t. the solution found by solve(); this only works
on continuous optimization problems.
d = problem.getDual()

Examplep.solve()print("duals:", p.getDual())
Related topics
problem.getlpsol, problem.getSlack, problem.getRCost, problem.getProbStatus,
problem.getProbStatusString.

Fair Isaac Corporation Conﬁdential and Proprietary Information

227

Reference Manual

problem.getdualray
Purpose

Synopsis

Retrieves a dual ray (dual unbounded direction) for the current problem, if the problem is found to be
infeasible.
problem.getdualray(dray)Argumentdray
ExampleArray of length problem.attributes.rows to hold the ray. May be None if not
required.

The following code tries to retrieve a dual ray:if not p.hasdualray():
print("Could not retrieve a dual ray")else:
dray = []p.getdualray(dray)print("dual ray:", dray)

Further information
1. It is possible to retrieve a dual ray only when, after solving an LP problem, the ﬁnal status isxpress.lp_infeas.
2. Dual rays are not post-solved. If the problem is in a presolved state, the dual ray that is returned will be
for the presolved problem. If the problem was solved with presolve on and has been restored to theoriginal state (the default behavior), this function will not be able to return a ray. To ensure that a dual
ray can be obtained, it is recommended to solve a problem with presolve turned off (presolve = 0).
Related topics
problem.getprimalray.

Fair Isaac Corporation Conﬁdential and Proprietary Information

228

Reference Manual

problem.getgencons
Purpose
Synopsis

Returns the general constraints y = f(x1, ..., xn, c1, ..., cm) in a given range.
(ncol, nval) = problem.getgencons(type, resultant, colstart, col, colsize,
valstart, val, valsize, first, last);

Arguments
prob
type

resultantcolstartcolcolsize
valstartvalvalsize
first
last
ncol
nval
ExampleThe current problem.
None if not required, otherwise a list which will be ﬁlled with the types of thegeneral constraints:
xpress.gencons_max (0)indicates a maximum constraint;
xpress.gencons_min (1)indicates a minimum constraint;
xpress.gencons_and (2)indicates an and constraint.
xpress.gencons_or (3)indicates an or constraint;
xpress.gencons_abs (4)indicates an absolute value constraint.
List/array which will be ﬁlled with the output variables y. May be None if not
required.
List/array which will be ﬁlled with the start index of each general constraint in the
col array. May be None if not required.
Integer array which will be ﬁlled with the indices of the input variables xi. May beNone if not required.
Maximum number of input columns to be retrieved.
Integer array of length at least last-first+1 which will be ﬁlled with the startindex of each general constraint in the val array. May be None if not required.
Integer array which will be ﬁlled with the constant values ci. May be None if not
required.
Maximum number of constant values to be retrieved.
First general constraint in the range.
Last general constraint in the range.
Number of values in the col list if not None.
Number of values in the val list if not None.

The following example retrieves all general constraints:

type, resultant, colstart, col, valstart, val = [], [], [], [], [], []prob.getgencons(type, resultant, colstart, col, 1e9, valstart, val, 1e9, 0, pro
Further information
It is possible to obtain just the number of input columns and/or constant values in the range of general
constraints by calling this function with colsize and valsize set to 0, in which case the required
size for the arrays will be returned as a tuple with ncol and nval.
Related topics
problem.addgencons, problem.delgencons, xpress.And, xpress.Or, xpress.max,
xpress.min, xpress.abs.

Fair Isaac Corporation Conﬁdential and Proprietary Information229

Reference Manual

problem.getglobal
Purpose

Synopsis

Retrieves global information about a problem. It must be called before problem.mipoptimize if thepresolve option is used.
problem.getglobal(qgtype, mgcols, dlim, qstype, msstart, mscols, dref)

Arguments
qgtypemgcolsdlim

qstypemsstartmscolsdref
ExampleCharacter array where the entity types will be returned. The types will be one of:B
binary variables;I
integer variables;P
partial integer variables;Ssemi-continuous variables;Rsemi-continuous integer variables.
Array where the columns of the global entities will be returned.
Array where the limits for the partial integer variables and lower bounds for thesemi-continuous and semi-continuous integer variables will be returned (any entries in
the positions corresponding to binary and integer variables will be meaningless).
Character array where the set types will be returned. The set types will be one of:1
SOS1 type sets;
2
SOS2 type sets.
Array where the offsets into the mscols and dref arrays indicating the start of the sets
will be returned. This array must be of length SETMEMBERS+1: the ﬁnal element
contains the length of the mscols and dref arrays.
Array of length problem.attributes.setmembers where the columns in each set
will be returned.
Array of length problem.attributes.setmembers where the reference row entries
for each member of the sets will be returned.

The following obtains the SOS information:
qstype = []mstart = []mscols = []
dref
= []
p.getglobal(None, None, None, qstype, mstart, mscols, dref)

Further information
All arguments may be None if not required.
Related topics
problem.loadproblem.

Fair Isaac Corporation Conﬁdential and Proprietary Information

230

Reference Manual

problem.getiisdata
Purpose

Synopsis

Returns information for an Irreducible Infeasible Set: size, variables (row and column vectors) andconﬂicting sides of the variables, duals and reduced costs.
problem.getiisdata(num, miisrow, miiscol, constrainttype, colbndtype,
duals, rdcs, isolationrows, isolationcols)

Argumentsnum
The ordinal number of the IIS to get data for.
miisrow
Indices of rows in the IIS. Can be None if not required.
miiscol
Indices of bounds (columns) in the IIS. Can be None if not required.
constrainttype Sense of rows in the IIS:L
for less or equal row;G
for greater or equal row.
E
for an equality row (for a non LP IIS);
1
for a SOS1 row;2
for a SOS2 row;I
for an indicator row.
Can be None if not required.
colbndtype Sense of bound in the IIS:
U
for upper bound;L
for lower bound.
F
for ﬁxed columns (for a non LP IIS);
B
for a binary column;
I
for an integer column;
P
for a partial integer columns;
S
for a semi-continuous column;R
for a semi-continuous integer column.
Can be None if not required.
duals
The >dual multipliers associated with the rows. Can be None if not required.
rdcs
The dual multipliers (reduced costs) associated with the bounds. Can be None if not
required.
isolationrows The isolation status of the rows:-1
if isolation information is not available for row (run iis isolations);0
if row is not in isolation;1
if row is in isolation.
Can be None if not required.
isolationcols The isolation status of the bounds:-1
if isolation information is not available for column (run iisisolations);0
if column is not in isolation;1
if column is in isolation. Can be None if not required.
ExampleThis example ﬁrst retrieves the size of IIS 1, then gets the detailed information for the IIS.
miisrow = []miiscol = []constrainttype = []colbndtype = []duals = []rdcs = []Fair Isaac Corporation Conﬁdential and Proprietary Information

231

Reference Manualisolationrows = []isolationcols = []p.getiisdata(1, miisrow, miiscol, constrainttype, colbndtype,
duals, rdcs, isolationrows, isolationcols)
Further information
1. IISs are numbered from 1 to NUMIIS. Index number 0 refers to the IIS approximation.
2. If miisrow and miiscol both are None, only the rownumber and colnumber are returned.
3. The arrays may be None if not required. However, arrays constrainttype, duals andisolationrows are only returned if miisrow is not None. Similarly, arrays colbndtype, rdcs andisolationcols are only returned if miiscol is not None.
4. For the initial IIS approximation (num = 0) the number of rows and columns with a nonzero Lagrange
multiplier (dual/reduced cost respectively) are returned. Please note that in such cases, it might benecessary to call problem.iisstatus to retrieve the necessary size of the return arrays.
5. If there are Special Ordered Sets in the IIS, their number is included in the miisrow array.
6. For non-LP IISs, some column indices may appear more than once in the miiscol array, for example
an integrality and a bound restriction for the same column.
7. Duals, reduced cost and isolation information is not available for nonlinear IIS problems, and for those
the arrays are ﬁlled with zero values in case they are provided.
Related topics
problem.iisall, problem.iisclear, problem.iisfirst, problem.iisisolations,problem.iisnext, problem.iisstatus, problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information

232Reference Manual

problem.getIndex
Purpose
Synopsis

Returns the numerical index for a speciﬁed row, column, or set of the optimizer.
ind = problem.getIndex(obj)

Argument
obj
ExamplePython object with the column, row, or SOS

The following example adds a constraint to a problem and then retrieves its index:
x = xpress.var()c = x⁎⁎2 + 2⁎x >= 5
p.addVariable(x)p.addConstraint(c)print("c has index", p.getIndex(c))

Related topics
problem.getIndexFromName, problem.getVariable, problem.getConstraint.

Fair Isaac Corporation Conﬁdential and Proprietary Information

233

Reference Manual

problem.getIndexFromName
Purpose
Synopsis

Returns the index for a speciﬁed row or column name.
ind = problem.getIndexFromName(type, name)Arguments
type
name
Example1
if a row index is required;2
if a column index is required.
String containing name of the item sought.

The following example retrieves the index of column "xnew":x = xpress.var(name='xnew')[...]print("variable's index: ", p.getIndexFromName('xnew'))

Related topics
problem.getIndexFromName, problem.getVariable, problem.getConstraint.

Fair Isaac Corporation Conﬁdential and Proprietary Information

234

Reference Manual

problem.getindicators
Purpose

Synopsis

Returns the indicator constraint condition (indicator variable and complement ﬂag) associated to therows in a given range.
problem.getindicators(inds, comps, first, last)

Arguments
inds
comps

first
last
ExampleArray of length last-first+1 where the indicator variables are to be placed.
Array of length last-first+1 where the indicator complement ﬂags will be returned:0
not an indicator constraint (in this case the corresponding entry in the indsarray is ignored);1
for indicator constraints with condition "bin = 1";-1
for indicator constraints with condition "bin = 0";First row in the range.
Last row in the range (inclusive).

The following example retrieves information about three indicator constraints in the problem and prints
a list of their indices.
inds = []comps = []p.getindicators(inds, comps, 2, 4)
print("indices:",
inds)
print("complement flags:", comps)

Related topics
problem.setindicators.

Fair Isaac Corporation Conﬁdential and Proprietary Information

235

Reference Manual

problem.getinfeas
Purpose
Synopsis

Returns a list of infeasible primal and dual variables.
problem.getinfeas(mx, mslack, mdual, mdj)

Arguments
mx
mslackmdual
mdj

Array to store the primal infeasible variables. May be None if not required.
Array to store the primal infeasible rows. May be None if not required.
Array to store the dual infeasible rows. May be None if not required.
Array to store the dual infeasible variables. May be None if not required.

Examplemx = []
mslack = []p.getinfeas(mx, mslack, None, None)
print("getinfeas --> mx and mslack:", mx, mslack)
Further information
To ﬁnd the infeasibilities in a previously saved solution, the solution must ﬁrst be loaded into memory
with the problem.readbinsol function.
Related topics
problem.getscaledinfeas, problem.getiisdata, problem.iisall, problem.iisclear,problem.iisfirst, problem.iisisolations, problem.iisnext, problem.iisstatus,
problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information

236

Reference Manual

problem.getlastbarsol
Purpose
Synopsis

Obtains the last barrier solution values following optimization that used the barrier solver.
barsolstatus = problem.getastbarsol(x=None, slack=None, dual=None,
dj=None);Argumentsx

Double array of length problem.attributes.cols where the values of the primal
variables will be returned. May be None if not required.
slack
Double array of length problem.attributes.rows where the values of the slack
variables will be returned. May be None if not required.
dual
Double array of length problem.attributes.rows where the values of the dual
variables (cTB B–1 ) will be returned. May be None if not required.
dj
Double array of length problem.attributes.cols where the reduced cost for eachvariable (cT – cTB B–1 A) will be returned. May be None if not required.
barsolstatus Status of the last barrier solve. Value matches that of the lpstatus attribute if thesolve stopped immediately after the barrier.

Further information
1. If the barrier solver has not been used, barsolstatus will return xpress.lp_unsolved.
2. The barrier solution or the solution candidate is always available if the status is not
xpress.lp_unsolved.
3. The last barrier solution is available until the next solve, and is not invalidated by otherwise working
with the problem.
Related topics
problem.getlpsol

Fair Isaac Corporation Conﬁdential and Proprietary Information

237

Reference Manual

problem.getlasterror
Purpose
Synopsis

Returns the error message corresponding to the last error triggered by a library function.
s = problem.getlasterror()

Example 1
The following shows how this function might be used in error-checking:p.solve()print("Current error status:", p.getlasterror())
Further information
The problem.getlasterror() function is an API wrapper for the XPRSgetlasterror() function in the
Xpress C API. For this reason, errors that occur within the Xpress API are reported by getlasterror().
Errors that occur at the level of the Python interface are not reported by getlasterror. Both classesof errors can be handled with a try/except construct. In the two examples below, the ﬁrst is an errorthat is detected by the Xpress API and propagated to a Python error, while the second is an incorrectstatement for the Python module. They both trigger a RuntimeError exception.
Example 2x = xpress.var()try:
p.addVariable(x)p.addVariable(x)except RuntimeError as e:
print(e)Example 3
try:p.addVariable('John Cleese')
except RuntimeError as e:
print(e)Related topics
problem.addcbmessage, problem.setlogfile.

Fair Isaac Corporation Conﬁdential and Proprietary Information

238

Reference Manual

problem.getlb
Purpose
Synopsis

Returns the lower bounds on the columns in a given range.
problem.getlb(lb, first, last)

Arguments
lb
first
last
ExampleArray where the lower bounds are to be placed.
(optional, default 0) First column in the range.
(optional, default COLS - 1) Last column in the range.

The following example retrieves the lower bounds for the columns of the current problem:
newlb = []p.getlb(newlb, 0, 4)
print("lb: ", newlb)

Further information
Values greater than or equal to xpress.infinity should be interpreted as inﬁnite; values less thanor equal to - xpress.infinity should be interpreted as negative inﬁnite.
Related topics
problem.chgbounds, problem.getub.

Fair Isaac Corporation Conﬁdential and Proprietary Information

239

Reference Manual

problem.getlpsol
Purpose
Synopsis

Used to obtain the LP solution values following optimization.
problem.getlpsol(x, slack, dual, dj)

Arguments
x
slack
dual

Array to store the values of the primal variables. May be None if not required.
Array to store the values of the slack variables. May be None if not required.
Array to store the values of the dual variables (cTB B–1 ). May be None if not required.
Array to store the reduced cost for each variable (cT – cTB B–1 A). May be None if not
required.

dj
ExampleThe following sequence of commands will get the LP solution (x) at the top node of a MIP and the
optimal MIP solution (y):p.mipoptimize("l") # only solve the LP relaxationx = []
p.getlpsol(x)print("root LP solution:", x)
p.mipoptimize() # solve the MIP problem
p.getmipsol(x)print("final MIP solution", x)Further information
1. If called during a global callback the solution of the current node will be returned.
2. When an integer solution is found during a global search, it is always set up as a solution to the current
node; therefore the integer solution is available as the current node solution and can be retrieved withgetlpsol and problem.getpresolvesol.
3. If the problem is modiﬁed after calling lpoptimize, then the solution will no longer be available.
4. If the problem has been presolved, then getlpsol returns the solution to the original problem. The
only way to obtain the presolved solution is to call the related function, problem.getpresolvesol.
Related topics
problem.getpresolvesol, problem.getmipsol, problem.writeprtsol,
problem.writesol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

240

Reference Manual

problem.getlpsolval
Purpose
Synopsis

Used to obtain a single LP solution value following optimization.
x, slack, dual, dj = problem.getlpsolval(column=None, row=None)

Arguments
column
row
x
slack
dual
dj

Column of the variable for which to return the solution value.
Row of the constraint for which to return the solution value.
The returned value of the primal variable.
The returned value of the slack variable.
The returned value of the dual variable (cTB B–1 ).
The returned reduced cost for the variable (cT – cTB B–1 A).

Further information
1. This function is currently not supported if the problem is in a presolved state.
2. If column or row are None, the corresponding output is set to -xpress.infinity.
Related topics
problem.getlpsol, problem.getpresolvesol, problem.getmipsol,
problem.writeprtsol, problem.writesol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

241

Reference Manual

problem.getmessagestatus
Purpose

Synopsis

Returns the current suppression status of a message: non-zero if the message is not suppressed; 0otherwise.
status = problem.getmessagestatus(errcode)

Argument
errcodeThe id number of the message. Refer to the Xpress Optimizer reference manual for a listof possible message numbers.

Further information
If a message is suppressed globally then the message will always have status return zero fromgetmessagestatus.
Related topics
problem.setmessagestatus.

Fair Isaac Corporation Conﬁdential and Proprietary Information

242

Reference Manual

problem.getmipsol
Purpose
Synopsis

Used to obtain the solution values of the last MIP solution that was found.
problem.getmipsol(x, slack)

Argumentsxslack
ExampleArray to store the values of the primal variables. May be None if not required.
Array to store the values of the slack variables. May be None if not required.

The following sequence of commands will get the solution (x) of the last MIP solution for a problem:
x = []
p.mipoptimize()p.getmipsol(x)print("solution:", x)

Related topics
problem.getpresolvesol, problem.writeprtsol, problem.writesol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

243

Reference Manual

problem.getmipsolval
Purpose
Synopsis

Used to obtain a single solution value of the last MIP solution that was found.
x, slack = problem.getmipsolval(column=None, row=None)

Arguments
prob
col
row
x
slack

The current problem.
Column index of the variable for which to return the solution value. May be None.
Row index of the constraint for which to return the solution value. May be None.
The returned value of the primal variable, or -xpress.infinity if column is None.
The returned value of the slack variable, or -xpress.infinity if row is None.

Related topics
problem.getmipsol, problem.getpresolvesol, problem.writeprtsol,
problem.writesol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

244

Reference Manual

problem.getmqobj
Purpose

Synopsis

Returns the nonzeros in the quadratic objective coefﬁcients’ matrix for the columns in a given range. To
achieve maximum efﬁciency, getmqobj returns the lower triangular part of this matrix only.
problem.getmqobj(mstart, mclind, dobjval, size, first, last)

Arguments
mstartmclinddobjval
size
first
last

Array which will be ﬁlled with indices indicating the starting offsets in the mclind anddobjval arrays for each requested column. It must be length of at least
last-first+2. Column i starts at position mstart[i] in the mrwind and dmatvalarrays, and has mstart[i+1]-mstart[i] elements in it. May be None if size is 0.
Array which will be ﬁlled with at most size columns of the nonzero elements in thelower triangular part of Q. May be None if size is 0.
Array which will be ﬁlled with at most size nonzero element values. May be None ifsize is 0.
The maximum number of elements to be returned (size of the arrays).
First column in the range.
Last column in the range.

Further information
The objective function is of the form cT x+0.5xT Qx where Q is positive semi-deﬁnite for minimization
problems and negative semi-deﬁnite for maximization problems. If this is not the case the optimization
algorithms may converge to a local optimum or may not converge at all. Note that only the upper orlower triangular part of the Q matrix is returned.
Related topics
problem.chgmqobj, problem.chgqobj, problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

245

Reference Manual

problem.getnamelist
Purpose

Synopsis

Returns the names for the rows, columns or sets in a given range. The names will be returned in a list of
Python strings.
names = problem.getnamelist(type, first, last);

Arguments
type
names
first
last
Example1
if row names are required;2
if column names are required.
3
if set names are required.
A list containing all returned names.
First row, column or set in the range. If None, it is taken as zero.
Last row, column or set in the range. If None, it is taken as the penultimate element in
the list deﬁned by type.

The following example retrieves and outputs the row and column names for the current problem.
cols = prob.attributes.cols
rows = prob.attributes.rows
rnames = prob.getnamelist(1, 0, rows - 1)
cnames = prob.getnamelist(2, 0, rows - 1)
for k,v in enumerate(rnames):
print("Row {0:4d}: {1}", k, v)
for k,v in enumerate(cnames):
print("Column {0:4d}: {1}", k, v)

Fair Isaac Corporation Conﬁdential and Proprietary Information

246

Reference Manual

problem.getobj
Purpose
Synopsis

Returns the objective function coefﬁcients for the columns in a given range.
problem.getobj(obj, first, last)

Arguments
obj
first
last
ExampleArray of length last-first+1 where the objective function coefﬁcients are to beplaced.
First column in the range.
Last column in the range.

The following example retrieves the objective function coefﬁcients of the ﬁrst ﬁve variables of thecurrent problem:
obj = []
p.getobj(obj, 0, 4)

Related topics
problem.chgobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

247

Reference Manual

problem.getObjVal
Purpose
Synopsis
ExampleReturns the objective value of the solution found by the Optimizer.
o = problem.getObjVal()
The following prints the objective value of an optimal solution after the solve() command is run:p.solve()print("optimal solution:", p.getObjVal())

Related topics
problem.solve.

Fair Isaac Corporation Conﬁdential and Proprietary Information

248

Reference Manual

problem.getpivotorderPurpose
Synopsis

Returns the pivot order of the basic variables.
problem.getpivotorder(mpiv)

Argument
mpiv
ExampleArray where the pivot order will be returned.

The following returns the pivot order of the variables into an array pPivot :mpiv = []p.getpivotorder(mpiv)

Further information
Row indices are in the range 0 to ROWS-1, whilst columns are in the range ROWS+SPAREROWS to
ROWS+SPAREROWS+COLS-1.
Related topics
problem.getpivots.

Fair Isaac Corporation Conﬁdential and Proprietary Information

249

Reference Manual

problem.getpivots
Purpose

Synopsis

Returns a list of potential leaving variables if a speciﬁed variable enters the basis. The return value is atuple containing the objective function value that would result if in entered the basis; and an integer
where the actual number of potential leaving variables will be returned.
dobj, npiv = problem.getpivots(in, outlist, x, maxpiv)

Argumentsinoutlistx

maxpivExampleIndex of the speciﬁed row or column to enter basis.
Array of length at least maxpiv to hold list of potential leaving variables. May be None if
not required.
Array of length problem.attributes.rows +problem.attributes.sparerows + problem.attributes.cols to hold thevalues of all the variables that would result if in entered the basis. May be None if not
required.
Maximum number of potential leaving variables to return.

The following retrieves a list of up to 5 potential leaving variables if variable 6 enters the basis:
outlist = []x = []
obj, npiv = p.getpivots(2, outlist, x, 10)

Further information
1. If the variable in enters the basis and the problem is degenerate then several basic variables are
candidates for leaving the basis, and the number of potential candidates is returned in npiv. A list of at
most maxpiv of these candidates is returned in outlist which must be at least maxpiv long. If
variable in were to be pivoted in, then because the problem is degenerate, the resulting values of theobjective function and all the variables do not depend on which of the candidates from outlist is
chosen to leave the basis. The value of the objective is returned in dobj and the values of the variables
into x.
2. Row indices are in the range 0 to ROWS-1, whilst columns are in the range ROWS+SPAREROWS to
ROWS+SPAREROWS+COLS-1.
Related topics
problem.getpivotorder.

Fair Isaac Corporation Conﬁdential and Proprietary Information

250

Reference Manual

problem.getpresolvebasis
Purpose

Synopsis

Returns the current basis from memory into the user’s data areas. If the problem is presolved, thepresolved basis will be returned. Otherwise the original basis will be returned.
problem.getpresolvebasis(rstatus, cstatus)

Arguments
rstatuscstatus

ExampleArray of length problem.attributes.rows to the basis status of the stack, surplus
or artiﬁcial variable associated with each row. The status will be one of:0
slack, surplus or artiﬁcial is non-basic at lower bound;1
slack, surplus or artiﬁcial is basic;2
slack or surplus is non-basic at upper bound.
May be None if not required.
Array of length problem.attributes.cols to hold the basis status of the columns
in the constraint matrix. The status will be one of:0variable is non-basic at lower bound, or superbasic at zero if the variable has
no lower bound;1
variable is basic;
2
variable is at upper bound;3
variable is super-basic.
May be None if not required.

The following obtains and outputs basis information on a presolved problem prior to the global search:
cs = []
p = xpress.problem()p.read("global1", "")p.mipoptimize()p.getpresolvebasis(cstatus=cs)

Related topics
problem.getbasis, problem.loadbasis, problem.loadpresolvebasis.

Fair Isaac Corporation Conﬁdential and Proprietary Information

251

Reference Manual

problem.getpresolvemap
Purpose

Synopsis

Returns the mapping of the row and column numbers from the presolve problem back to the original
problem.
problem.getpresolvemap(rowmap, colmap)

Arguments
rowmapcolmapExampleArray to store the row maps.
Array to store the column maps.

The following reads in a (Mixed) Integer Programming problem and gets the mapping for the rows andcolumns back to the original problem following optimization of the linear relaxation. The elimination
operations of the presolve are turned off so that a one-to-one mapping between the presolve problem
and the original problem.
p.read("MyProb", "")p.controls.presolveops = 255
p.mipoptimize("l")
rowmap = []colmap = []p.getpresolvemap(rowmap, colmap)

Further information
The presolved problem can contain rows or columns that do not map to anything in the original
problem. An example of this are cuts created during the MIP solve and temporarily added to thepresolved problem. It is also possible that the presolver will introduce new rows or columns. For any
row or column that does not have a mapping to a row or column in the original problem, thecorresponding entry in the returned rowmap and colmap arrays will be -1.

Fair Isaac Corporation Conﬁdential and Proprietary Information

252

Reference Manual

problem.getpresolvesol
Purpose
Synopsis

Returns the solution for the presolved problem from memory.
problem.getpresolvesol(x, slack, dual, dj)

Arguments
x
slack
dual
dj
ExampleArray to store the values of the primal variables. May be None if not required.
Array to store the values of the slack variables. May be None if not required.
Array to store the values of the dual variables. May be None if not required.
Array to store the reduced cost for each variable. May be None if not required.

The following reads in a (Mixed) Integer Programming problem and displays the solution to thepresolved problem following optimization of the linear relaxation:p.read("MyProb", "")p.mipoptimize("l")
sol = []
p.getpresolvesol(x=sol)
print("presolved sol", sol)

Further information
1. If the problem has not been presolved, the solution in memory will be returned.
2. The solution to the original problem should be returned using the related function
problem.getlpsol.
3. If called during a global callback the solution of the current node will be returned.
4. When an integer solution is found during a global search, it is always set up as a solution to the current
node; therefore the integer solution is available as the current node solution and can be retrieved withgetlpsol and problem.getpresolvesol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

253

Reference Manual

problem.getprimalray
Purpose

Synopsis

Retrieves a primal ray (primal unbounded direction) for the current problem, if the problem is found to
be unbounded.
problem.getprimalray(ray)Argumentray
ExampleArray of length problem.attributes.cols to hold the ray. May be None if not
required.

The following code tries to retrieve a primal ray:if not p.hasprimalray():
print("Could not retrieve a primal ray")else:
ray = []
p.getprimalray(ray)print("primal ray:", ray)Further information
1. It is possible to retrieve a primal ray only when, after solving an LP problem, the ﬁnal status(LPSTATUS) is xpress.lp_unbounded.
2. Primal rays are not post-solved. If the problem is in a presolved state, the primal ray that is returned will
be for the presolved problem. If the problem was solved with presolve on and has been restored to theoriginal state (the default behavior), this function will not be able to return a ray. To ensure that a primal
ray can be obtained, it is recommended to solve a problem with presolve turned off (PRESOLVE = 0).
Related topics
problem.getdualray.

Fair Isaac Corporation Conﬁdential and Proprietary Information

254

Reference Manual

problem.getProbStatus
Purpose

Synopsis

Returns the problem status before or after a solve () command. The returned number corresponds
to the problem status described in the Xpress Optimizer reference manual. If the problem is an LP, thereturned value is equal to p.attributes.lpstatus if the problem is an LP, and to
p.attributes.mipstatus if the problem is a MIP.
s = problem.getProbStatus()

Examplep = xpress.problem()p.read("example2", "")p.solve()print("solution status code: ", p.getProbStatus(), " -->",
p.getProbStatusString())
Related topics
problem.solve, problem.getSolution, problem.getDual, problem.getSlack,problem.getRCost, problem.getProbStatusString.

Fair Isaac Corporation Conﬁdential and Proprietary Information

255

Reference Manual

problem.getProbStatusString
Purpose
Synopsis

Returns the string corresponding to the the problem status before or after a solve () command.
s = problem.getProbStatusString()

Examplep = xpress.problem()p.read("example2", "")p.solve()print("solution status code: ", p.getProbStatus(), " -->",
p.getProbStatusString())
Related topics
problem.solve, problem.getSolution, problem.getDual, problem.getSlack,problem.getRCost, problem.getProbStatus.

Fair Isaac Corporation Conﬁdential and Proprietary Information

256Reference Manual

problem.getpwlcons
Purpose
Synopsis

Returns the piecewise linear constraints y = f(x) in a given range.
npoints = problem.getpwlcons(col, resultant, start, xval, yval, size,
first, last);

Arguments
colresultant
start

xval
yval
size
first
last
npoints
ExampleInteger array which will be ﬁlled with the indices of the input variables x. It must be oflength at least last-first+1. May be None if not required.
Integer array which will be ﬁlled with the indices of the output variables y. It must be oflength at least last-first+1. May be None if not required.
Integer array which will be ﬁlled with the start indices of the different constraints in the
breakpoint arrays. It must be of length at least last-first+1. The x-values of the
breakpoints of piecewise linear constraint i < last will be given in xval[start[i]]to xval[start[i+1]]. May be None if not required.
Double array of length sizewhich will be ﬁlled with the x-values of the breakpoints. May
be None if not required.
Double array of length sizewhich will be ﬁlled with the y-values of the breakpoints. May
be None if not required.
Maximum number of breakpoints to be retrieved.
First piecewise linear constraint in the range.
Last piecewise linear constraint in the range.
The returned number of breakpoints in the xval and yval arrays. If the number ofbreakpoints is greater than size, then only size elements will be returned.

The following example retrieves all variables and breakpoints in the ﬁrst two piecewise linear
constraints:col, resultant, start, xval, yval = [], [], [], [], []npoints = prob.getpwlcons(prob, col, resultant, start, xval, yval, 1e9, 0, 1)

Further information
It is possible to obtain just the number of breakpoints in the range of piecewise linear constraints bycalling this function with size set to 0, in which case the required size for the breakpoint arrays will be
returned in npoints.
Related topics
problem.addpwlcons, problem.delpwlcons, xpress.pwl.

Fair Isaac Corporation Conﬁdential and Proprietary Information

257

Reference Manual

problem.getqobj
Purpose

Synopsis

Returns a single quadratic objective function coefﬁcient corresponding to the variable pair (icol,jcol) of the Hessian matrix.
objqcoef = problem.getqobj(icol, jcol)

Arguments
icol
jcol
ExampleColumn index for the ﬁrst variable in the quadratic term.
Column index for the second variable in the quadratic term.

The following returns the coefﬁcient of the x0 2 term in the objective function, placing it in the variablevalue :
print("diagonal coeff of the Hessian:",[p.getqobj(i,i) for i in range(p.attributes.cols)])

Further information
For example, if the objective function has the term [3x1 x2 + 3x2 x1 ]/2 the value retrieved by getqobj is
3.0 and if the objective function has the term [6x1 2 ]/2 the value retrieved by getqobj is 6.0.
Related topics
problem.getmqobj, problem.chgqobj, problem.chgmqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

258

Reference Manual

problem.getqrowcoeff
Purpose

Synopsis

Returns a single quadratic constraint coefﬁcient corresponding to the variable pair (icol, jcol) of the
Hessian of a given constraint.
coeff = problem.getqrowcoeff (irow, icol, jcol)

Arguments
row
icol
jcol
ExampleThe quadratic row where the coefﬁcient is to be looked up.
Column index for the ﬁrst variable in the quadratic term.
Column index for the second variable in the quadratic term.

The following returns the coefﬁcient of the dist2 term in the constraint cons1:
print("diagonal coeff of dist:", p.getqrowcoeff(cons1, dist, dist)

Further information
The coefﬁcient returned corresponds to the Hessian of the constraint. That means the for constraint x+ [x2 + 6 xy] <= 10 getqrowcoeff would return 1 as the coefﬁcient of x2 and 3 as the
coefﬁcient of xy.
Related topics
problem.loadproblem, problem.addqmatrix, problem.chgqrowcoeff,
problem.getqrowqmatrix, problem.getqrowqmatrixtriplets, problem.getqrows,
problem.chgqobj, problem.chgmqobj, problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information259

Reference Manual

problem.getqrowqmatrix
Purpose

Synopsis

Returns the nonzeros in a quadratic constraint coefﬁcients matrix for the columns in a given range. To
achieve maximum efﬁciency, getqrowqmatrix returns the lower triangular part of this matrix only.
problem.getqrowqmatrix(irow, mstart, mclind, dqe, size, first, last)

Argumentsirowmstartmclind
dqe
size
first
last

Row (i.e. xpress.constraint object, index, or name) for which the quadratic
coefﬁcients are to be returned.
List to be ﬁlled with indices indicating the starting offsets in the mclind and dobjval
lists for each requested column. It must be length of at least last-first+2. Column istarts at position mstart[i] in the mrwind and dmatval arrays, and has
mstart[i+1]-mstart[i] elements in it. May be None if size is 0.
Array of length size which will be ﬁlled with the columns of the nonzero elements in thelower triangular part of Q. May be None if size is 0.
Array of length size which will be ﬁlled with the nonzero element values. May be None
if size is 0.
Maximum number of elements to be returned in mclind and dqe.
First column in the range.
Last column in the range.

Related topics
problem.loadproblem, problem.getqrowcoeff, problem.addqmatrix,
problem.chgqrowcoeff, problem.getqrowqmatrixtriplets, problem.getqrows,
problem.chgqobj, problem.chgmqobj, problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

260

Reference Manual

problem.getqrowqmatrixtriplets
Purpose

Synopsis

Returns the nonzeros in a quadratic constraint coefﬁcients matrix as triplets (index pairs with
coefﬁcients). To achieve maximum efﬁciency, getqrowqmatrixtriplets returns the lower
triangular part of this matrix only.
problem.getqrowqmatrixtriplets(irow, mqcol1, mqcol2, dqe)

Argumentsirownqelemmqcol1
mqcol2dqe

Row (i.e. xpress.constraint object, index, or name) for which the quadratic
coefﬁcients are to be returned.
Argument used to return the number of quadratic coefﬁcients in the row.
First index in the triplets. May be None if not required.
Second index in the triplets. May be None if not required.
Coefﬁcients in the triplets. May be None if not required.

Further information
If a row index of -1 is used, the function returns the quadratic coefﬁcients for the objective function.
Related topics
problem.loadproblem, problem.getqrowcoeff, problem.addqmatrix,
problem.chgqrowcoeff, problem.getqrowqmatrix, problem.getqrows, problem.chgqobj,
problem.chgmqobj, problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

261

Reference Manual

problem.getqrows
Purpose
Synopsis

Returns a list of row objects that have quadratic coefﬁcients.
problem.getqrows(qcrows)

Argument
qcrowsArray to contain the indices of rows with quadratic coefﬁcients in them. May be None if
not required.

Related topics
problem.loadproblem, problem.getqrowcoeff, problem.addqmatrix,
problem.chgqrowcoeff, problem.getqrowqmatrix, problem.getqrowqmatrixtriplets,
problem.chgqobj, problem.chgmqobj, problem.getqobj.

Fair Isaac Corporation Conﬁdential and Proprietary Information

262

Reference Manual

problem.getRCost
Purpose

Synopsis

Return the reduced cost of all variables of the problem w.r.t. the solution found by solve(). Thisfunction only works on continuous optimization problems.
r = problem.getRCost()

Examplep.solve()print("reduced costs:", p.getRCost())
Related topics
problem.solve, problem.getlpsol, problem.getSolution, problem.getDual,problem.getSlack, problem.getProbStatus, problem.getProbStatusString.

Fair Isaac Corporation Conﬁdential and Proprietary Information

263

Reference Manual

problem.getrhs
Purpose
Synopsis

Returns the right hand side elements for the rows in a given range.
problem.getrhs(rhs, first, last)

Arguments
rhs
first
last
ExampleArray where the (last - first + 1) right hand side elements are to be placed.
First row in the range.
Last row in the range.

The following example retrieves the right hand side values of the problem:b = []
p.getrhs(b, 0, p.attributes.rows - 1)

Related topics
problem.chgrhs, problem.chgrhsrange, problem.getrhsrange.

Fair Isaac Corporation Conﬁdential and Proprietary Information

264

Reference Manual

problem.getrhsrange
Purpose
Synopsis

Returns the right hand side range values for the rows in a given range.
problem.getrhsrange(range, first, last)

Arguments
range
first
last

Array of length last-first+1 where the right hand side range values are to be placed.
First row in the range.
Last row in the range.

Related topics
problem.chgrhs, problem.chgrhsrange, problem.getrhs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

265Reference Manual

problem.getrowinfo
Purpose
Synopsis

Get current row information.
info = problem.getrowinfo(infotype, rowindex)

Arguments
infotype
rowindex
infoType of information (see below)
Row (i.e. xpress.constraint object, index, or name) whose information is to behandledInformation to be retrieved

Further information
If the data is not available, the type of the returned info is set to xpress.undefined.
The following constants are provided for row information handling:rowinfo_slack

Get the current slack value of the row

rowinfo_dual

Get the current dual multiplier of the row

rowinfo_numpenaltyerrors Get the number of times the penalty error vector has been active forthe rowrowinfo_maxpenaltyerror

Get the maximum size of the penalty error vector activity for the row

rowinfo_totalpenaltyerror

Get the total size of the penalty error vector activity for the row

rowinfo_currentpenaltyerror Get the size of the penalty error vector activity in the current
iteration for the row
rowinfo_currentpenaltyfactor Set the size of the penalty error factor for the current iteration
for the row
rowinfo_penaltycolumnplus

Get the index of the positive penalty column for the row (+)

rowinfo_penaltycolumnplusvalue

Get the value of the positive penalty column for the row (+)

rowinfo_penaltycolumnplusdj Get the reduced cost of the positive penalty column for the row(+)
rowinfo_penaltycolumnminus

Get the index of the negative penalty column for the row (-)

rowinfo_penaltycolumnminusvalue

Get the value of the negative penalty column for the row (-)

rowinfo_penaltycolumnminusdj Get the reduced cost of the negative penalty column for therow (-)

Fair Isaac Corporation Conﬁdential and Proprietary Information

266

Reference Manual

problem.getrows
Purpose
Synopsis

Returns the nonzeros in the constraint matrix for the rows in a given range.
problem.getrows(mstart, mclind, dmatval, size, first, last)

Arguments
mstartmclinddmatval
size
first
last

Array which will be ﬁlled with the indices indicating the starting offsets in the mclind
and dmatval arrays for each requested row. It must be of length at least
last-first+2. Column i starts at position mstart[i] in the mrwind and dmatvalarrays, and has mstart[i+1]-mstart[i] elements in it. May be None if not required.
Arrays which will be ﬁlled with at most size column of the nonzero elements for eachrow. May be None if not required.
Array which will be ﬁlled with at most size nonzero element values. May be None if not
required.
Maximum number of elements to be retrieved.
First row in the range.
Last row in the range.

Related topics
problem.getcols, problem.getrowtype.

Fair Isaac Corporation Conﬁdential and Proprietary Information

267

Reference Manual

problem.getrowstatus
Purpose
Synopsis

Retrieve the status setting of a constraint
status = problem.getrowstatus(rowIndex)

Arguments
rowindex
statusExampleThe index of the matrix row whose data is to be obtained.
The status settings.

This recovers the status of the rows of the matrix of the current problem and reports those which are
ﬂagged as enforced constraints.
m = p.getintattrib('rows')
for i in range(m):status = p.getrowstatus(i)if(Status & 0x800) print("Row {0} is enforced".format(i))

Further information
See the section on bitmap settings of the XSLP reference manual for details on the possible
information in Status.
Related topics
problem.chgrowstatus

Fair Isaac Corporation Conﬁdential and Proprietary Information

268

Reference Manual

problem.getrowtype
Purpose
Synopsis

Returns the row types for the rows in a given range.
problem.getrowtype(qrtype, first, last)

Arguments
qrtypefirst
last
ExampleCharacter array of length last-first+1 characters where the row types will be
returned:N
indicates a free constraint;Lindicates a ≤ constraint;E
indicates an = constraint;G
indicates a ≥ constraint;R
indicates a range constraint.
First row in the range.
Last row in the range.

The following example retrieves the type of the ﬁrst four rows of the problem into an array qrt:
qrt = []
p.getrowtype(qrt, 0, 3)

Related topics
problem.chgrowtype, problem.getrows.

Fair Isaac Corporation Conﬁdential and Proprietary Information

269

Reference Manual

problem.getrowwt
Purpose
Synopsis

Get the initial penalty error weight for a row
value = problem.getrowwt(rowindex)

Arguments
rowindexvalue
ExampleThe row (i.e. xpress.constraint object, index, or name) whose weight is to be
retrieved.
The value of the weight.

The following example gets the initial weight of row number 2.
value = p.getrowwt(2)Further information
The initial row weight is used only when the augmented structure is created. After that, the current
weighting can be accessed using problem.getrowinfo.
Related topics
problem.chgrowwt, problem.getrowinfo

Fair Isaac Corporation Conﬁdential and Proprietary Information

270

Reference Manual

problem.getscaledinfeas
Purpose

Synopsis

Returns a list of scaled infeasible primal and dual variables for the original problem. If the problem iscurrently presolved, it is postsolved before the function returns.
problem.getscaledinfeas(mx, mslack, mdual, mdj)

Arguments
mx
mslackmdual
mdj

Array to store the primal infeasible variables. May be None if not required.
Array to store the primal infeasible rows. May be None if not required.
Array to store the dual infeasible rows. May be None if not required.
Array to store the dual infeasible variables. May be None if not required.

Examplemx = []
mslack = []mdual = []mdj = []
p.getscaledinfeas(mx, mslack, mdual, mdj)
Related topics
problem.getinfeas, problem.getiisdata, problem.iisall, problem.iisclear,problem.iisfirst, problem.iisisolations, problem.iisnext, problem.iisstatus,
problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information

271

Reference Manual

problem.getSlackPurpose

Synopsis

Return the slack for all constraints of the problem w.r.t. the solution found by solve(). This function
works both with continuous and mixed-integer optimization problems.
s = problem.getSlack()

Examplep.solve()print("slack:", p.getSlack())
Related topics
problem.solve, problem.getlpsol, problem.getmipsol, problem.getSolution,
problem.getDual, problem.getRCost, problem.getProbStatus,
problem.getProbStatusString.

Fair Isaac Corporation Conﬁdential and Proprietary Information272

Reference Manual

problem.getslpsol
Purpose
Synopsis

Obtain the solution values for the most recent SLP iteration
problem.getslpsol(x, slack, dual, dj)

Arguments
x
slack
dual
dj
ExampleArray of length problem.attributes.xslp_originalcols to hold the values ofthe primal variables. May be None if not required.
Array of length problem.attributes.xslp_originalrows to hold the values ofthe slack variables. May be None if not required.
Array of length problem.attributes.xslp_originalrows to hold the values ofthe dual variables. May be None if not required.
Array of length problem.attributes.xslp_originalcols to hold the recuded
costs of the primal variables. May be None if not required.

The following code fragment recovers the values and reduced costs of the primal variables from themost recent SLP iteration:ncol = p.getintattrib(prob,xpress.xslp_originalcols)val = []dj
= []p.getslpsol(val,None,None,dj)

Further information
getslpsol can be called at any time after an SLP iteration has completed, and will return the samevalues even if the problem is subsequently changed. getslpsol returns values for the columns androws originally in the problem and not for any augmentation rows or columns. To access the values ofany augmentation columns or rows, use getlpsol; accessing the augmented solution is only
recommended if xslp_presolvelevel indicates that the problem dimensions should not bechanged in presolve.

Fair Isaac Corporation Conﬁdential and Proprietary Information

273

Reference Manual

problem.getSolution
Purpose

Synopsis

Returns the solution to an optimization problem if called after the solve() function has terminated.
This function works with both continuous and mixed-integer optimization problems.
x = problem.getSolution(args=None, flatten=False)

Arguments
args

flatten(optional) specify indices, names, or objects whose solution value is requested. If None,
it is assumed that all indices of the problem’s variables are requested. Starting withversion 8.8, args can contain expressions, both linear and nonlinear, and dictionaries
thereof, in order to allow for more ﬂexible evaluation of functions of the problem solution(optional) allows for backward compatibility with previous versions of the Xpress
Python interface. Regardless of whether the passed object is a (nested) list, tuples, thereturned value is a ﬂattened list containing all requested values.

Example 1
Below are a few possible uses of the function. Note that one can specify variable names, variableindices, or variable objects, and embed them in lists, dictionaries, NumPy arrays, and tuples.
print(m.getSolution ())
print("v1 is", m.getSolution(v1))
a = m.getSolution(x)b = m.getSolution(range(4))
c = m.getSolution('Var1')
e = m.getSolution({1: x, 2: 0,
3: 'Var1'})
d = m.getSolution(v1 + 3⁎x)e = m.getSolution(np.array(x))# Prints a list with an optimal solution# Only prints the value of v1# Gets the values of all variables in the ve# Gets the value of v1 and x[0], x[1], x[2],# the first four variables of the problem# Gets the value of v1 by its name

# Returns a dictionary containing the same k# in the arguments and the values of the# variables/expressions passed# Gets the value of an expression under the# current solution# Gets a NumPy array with the solution of xy=xpress.var(name='var1')
x=xpress.var(name='var2')[...]
p.solve()print("solution:",p.getSolution())
print("x is",p.getSolution(x))
print("first two var:",p.getSolution([0,1]))
print("x and y are", p.getSolution(['var1', 'var2']))
Example 2
The next examples show how to use the flatten argument, which ensures that the returned value is a
ﬂattened list.

y=xpress.var(name='var1')
x=xpress.var(name='var2')[...]
p.solve()print("x is",p.getSolution([[x,y],[x,y]], flatten=True)) # will retu
print("first two var:", p.getSolution(0,1, flatten=True)) # will return the li

Fair Isaac Corporation Conﬁdential and Proprietary Information

274

Reference Manual

Further information
For efﬁciency reasons it is preferable that one call to getSolution is made, as the whole vector is
obtained at each call and only the desired portion is returned.
The function xpress.evaluate is more ﬂexible in that it allows more argument types. Apart from thecase where the args argument contains indices and names of the variables, this function is equivalent
to a call to xpress.evaluate.
Related topics
xpress.evaluate, problem.getlpsol, problem.getmipsol, problem.getDual,problem.getSlack, problem.getRCost, problem.getProbStatus,
problem.getProbStatusString.

Fair Isaac Corporation Conﬁdential and Proprietary Information

275

Reference Manual

problem.getSOS
Purpose

Synopsis

Returns one or more SOSs of a problem corresponding to one or more indices passed as arguments.
These SOSs are returned as Python objects and can be used to access and manipulate the problem.
x = problem.getSOS(index, first, last)

Arguments
first
last
index

(optional) The ﬁrst index of the SOSs to be returned.
(optional) The last index of the SOSs to be returned.
(optional) Either an integer or a list of integers (not necessarily sorted) with theindex/indices of all SOSs to be returned.

Further information
All arguments are optional. If neither of them is provided, the return value is a list with all SOSs of the
problem. Otherwise, either first and last or just index can be passed.
Related topics
problem.getVariable, problem.getConstraint,

Fair Isaac Corporation Conﬁdential and Proprietary Information

276

Reference Manual

problem.gettolset
Purpose
Synopsis

Retrieve the values of a set of convergence tolerances for an SLP problem
status = problem.gettolset(nslptol, tols)

Arguments
nslptolstatusTols
ExampleThe index of the tolerance set.
The bit-map of status settings.
Array of 9 double-precision values to hold the tolerances. May be None if not required.

The following example retrieves the values for tolerance set 3 and prints those which are set:tols = []status = p.gettolset(3, Tols)
for i in range(9):if status &(1<<i):print("Tolerance {0} = {1}".format(i,Tols[i]))Further information
If Tols is None, then the corresponding information will not be returned.
If Tols is not None, then a set of 9 values will always be returned. Status indicates which of thesevalues is active as follows. Bit n of Status is set if Tols[n] is active, where n is:
Entry / Bit

ToleranceXSLP constantXSLP bit constant0

Closure tolerance (TC)xslp_TOLSET_TC

xslp_TOLSETBIT_TC

1

Absolute delta tolerance (TA)xslp_TOLSET_TA

xslp_TOLSETBIT_TA

2

Relative delta tolerance (RA)xslp_TOLSET_RA

xslp_TOLSETBIT_RA

3

Absolute coefﬁcient tolerance (TM)xslp_TOLSET_TM

xslp_TOLSETBIT_TM

4

Relative coefﬁcient tolerance (RM)

xslp_TOLSET_RM

xslp_TOLSETBIT_RM

5

Absolute impact tolerance (TI)

xslp_TOLSET_TI

xslp_TOLSETBIT_TI

6

Relative impact tolerance (RI)

xslp_TOLSET_RI

xslp_TOLSETBIT_RI

7

Absolute slack tolerance (TS)xslp_TOLSET_TS

xslp_TOLSETBIT_TS

8

Relative slack tolerance (RS)xslp_TOLSET_RS

xslp_TOLSETBIT_RS

The xslp_TOLSET constants can be used to access the corresponding entry in the value arrays, whilethe xslp_TOLSETBIT constants are used to set or retrieve which tolerance values are used for a given
SLP variable.
Related topics
Related topics
problem.addtolsets, problem.chgtolset, problem.deltolsets, problem.loadtolsets

Fair Isaac Corporation Conﬁdential and Proprietary Information

277

Reference Manual

problem.getub
Purpose
Synopsis

Returns the upper bounds on the columns in a given range.
problem.getub(ub, first, last)

Arguments
ub
first
last

Array where the last - first + 1 upper bounds are to be placed.
First column in the range.
Last column in the range.

Related topics
problem.chgbounds, problem.getlb.

Fair Isaac Corporation Conﬁdential and Proprietary Information

278

Reference Manual

problem.getunbvec
Purpose

Synopsis

Returns the index vector which causes the primal simplex or dual simplex algorithm to determine that aproblem is primal or dual unbounded respectively.
junb = problem.getunbvec()

Further information
When solving using the dual simplex method, if the problem is primal infeasible thengetunbvec returns the pivot row where dual unboundedness was detected. Also note that whensolving using the dual simplex method, if the problem is primal unbounded then getunbvec returns -1
since the problem is dual infeasible and not dual unbounded.
Related topics
problem.getinfeas, problem.lpoptimize.

Fair Isaac Corporation Conﬁdential and Proprietary Information

279

Reference Manual

problem.getvar
Purpose
Synopsis

Retrieve information about an SLP variable(detrow, initstepbound, stepbound, penalty, damp, initvalue, value, tolset,
history, converged, vartype, delta, penaltydelta, updaterow,oldvalue) = problem.getvar(colindex)

Arguments
colindex
detrow

The column (i.e. xpress.var object, index, or name).
Address of an integer to receive the index of the determining row. May be None if not
required.
initstepbound Address of a double precision variable to receive the value of the initial step boundof the variable. May be None if not required.
stepbound Address of a double precision variable to receive the value of the current step bound of
the variable. May be None if not required.
penalty
Address of a double precision variable to receive the value of the penalty delta
weighting of the variable. May be None if not required.
damp
Address of a double precision variable to receive the value of the current damping factorof the variable. May be None if not required.
initvalue Address of a double precision variable to receive the value of the initial value of thevariable. May be None if not required.
value
Address of a double precision variable to receive the current activity of the variable. May
be None if not required.
tolsetAddress of an integer to receive the index of the tolerance set of the variable. May beNone if not required.
history
Address of an integer to receive the SLP history of the variable. May be None if not
required.
converged Address of an integer to receive the convergence status of the variable as deﬁned in the"Convergence Criteria" section (The returned value will match the numbering of thetolerances). May be None if not required.
vartype
Address of an integer to receive the status settings (a bitmap deﬁning the existence of
certain properties for this variable). The following bits are deﬁned:
Bit 1:
Variable has a delta vector
Bit 2:
Variable has an initial value
Bit 14: Variable is the reserved "=" column
Other bits are reserved for internal use. May be None if not required.
delta
Address of an integer to receive the index of the delta vector for the variable. May beNone if not required.
penaltydelta Address of an integer to receive the index of the ﬁrst penalty delta vector for thevariable. The second penalty delta immediately follows the ﬁrst. May be None if not
required.
updaterow Address of an integer to receive the index of the update row for the variable. May beNone if not required.
oldvalue
Address of a double precision variable to receive the value of the variable at theprevious SLP iteration. May be None if not required.

ExampleThe following example retrieves the current value, convergence history and status for column 3.
(a,b,c,d,e,value,g,history,converged,j,k,i,h,k,l) = p.getvar(3)Fair Isaac Corporation Conﬁdential and Proprietary Information

280

Reference Manual

Further information
If colindex refers to a column which is not an SLP variable, then all the return values will indicate that
there is no corresponding data.
detrow will be set to -1 if there is no determining row.
delta, penaltydelta and updaterow will be set to -1 if there is no corresponding item.
Related topics
problem.addvars, problem.chgvar, problem.delvars, problem.loadvars

Fair Isaac Corporation Conﬁdential and Proprietary Information

281

Reference Manual

problem.getVariable
Purpose

Synopsis

Returns one or more variables of a problem corresponding to one or more indices passed asarguments. These variables are returned as Python objects and can be used to access and manipulate
the problem.
x = problem.getVariable(index, first, last)

Arguments
first
last
index

(optional) The ﬁrst index of the variables to be returned. It must be between 0 and COLS
- 1.
(optional) The last index of the variables to be returned. It must be between 0 and COLS
- 1.
(optional) Either an integer or a list of integers (not necessarily sorted) with theindex/indices of all variables to be returned, all between 0 and COLS - 1

Further information
All arguments are optional. If neither of them is provided, the return value is a list with all variables ofthe problem. Otherwise, either first and last or just index can be passed.
Related topics
problem.getConstraint, problem.getSOS.

Fair Isaac Corporation Conﬁdential and Proprietary Information282

Reference Manual

problem.globalsol
Purpose
Synopsis
ExampleInitiate the Xpress Nonlinear mixed integer SLP (MISLP) algorithm
problem.globalsol()
The following example solves the continuous relaxation of the problem and then ﬁnds the integer
solution.
p.nlpoptimize()
p.globalsol()

Further information
The current Xpress Nonlinear mixed integer problem will be maximized or minimized using thealgorithm deﬁned by the control variable xslp_mipalgorithm.
It is recommended that problem.nlpoptimize be used ﬁrst to obtain a converged solution to therelaxed problem. If this is not done, ensure that xslp_ojsense is set appropriately.
See the chapter on Mixed Integer Non-Linear Programming in the SLP Reference Manual for more
information about the Xpress Nonlinear MISLP algorithms.
Related topics
xslp_MIPALGORITHM, xslp_OBJSENSE

Fair Isaac Corporation Conﬁdential and Proprietary Information

283

Reference Manual

problem.hasdualray
Purpose

Synopsis

Returns true if a dual ray (dual unbounded direction) exists for the current problem, if the problem isfound to be infeasible.
v = problem.hasdualray()Related topics
problem.getdualray.

Fair Isaac Corporation Conﬁdential and Proprietary Information284

Reference Manual

problem.hasprimalray
Purpose

Synopsis

Returns true if a primal ray (primal unbounded direction) exists for the current problem, if the problem isfound to be unbounded.
v = problem.hasprimalray()Related topics
problem.getprimalray.

Fair Isaac Corporation Conﬁdential and Proprietary Information

285

Reference Manual

problem.iisall
Purpose

Synopsis
ExamplePerforms an automated search for independent Irreducible Infeasible Sets (IIS) in an infeasible
problem.
problem.iisall()This example searches for IISs and then questions the problem attribute NUMIIS to determine how
many were found:p.iisall()print("The problem has {0} IISs".format(p.attributes.numiis))

Further information
1. A model may have several infeasibilities. Repairing a single IIS may not make the model feasible. For
this reason the Optimizer can ﬁnd an IIS for each of the infeasibilities in a model. If the control MAXIIS
is set to a positive integer value then the problem.iisall command will stop if MAXIIS IISs havebeen found. By default the control MAXIIS is set to -1, in which case an IIS is found for each of theinfeasibilities in the model.
2. The problem attribute NUMIIS allows the user to recover the number of IISs found in a particularsearch. Alternatively, the problem.iisstatus function may be used to retrieve the number of IISs
found by the problem.iisfirst, problem.iisnext, or problem.iisall functions.
Related topics
problem.getiisdata, problem.iisclear, problem.iisfirst, problem.iisisolations,problem.iisnext, problem.iisstatus, problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information

286

Reference Manual

problem.iisclear
Purpose
Synopsis

Resets the search for Irreducible Infeasible Sets (IIS).
problem.iisclear()Further information
1. The information stored internally about the IISs identiﬁed by problem.iisfirst,
problem.iisnext or problem.iisall are cleared. Functions problem.getiisdata,
problem.iisstatus, problem.iiswrite and problem.iisisolations cannot be called until
the IIS identiﬁcation procedure is started again.
2. This function is automatically called by problem.iisfirst and problem.iisall.
Related topics
problem.getiisdata, problem.iisall, problem.iisfirst, problem.iisisolations,problem.iisnext, problem.iisstatus, problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information

287

Reference Manual

problem.iisﬁrst
Purpose

Synopsis

Initiates a search for an Irreducible Infeasible Set (IIS) in an infeasible problem. The returned value canbe 0 for success, 1 if the problem is feasible, or 2 in case of error.
status_code = problem.iisfirst(iismode)

Argument
iismode0
1
2
ExampleThe IIS search mode:
stops after ﬁnding the initial infeasible subproblem;
ﬁnd an IIS, emphasizing simplicity of the IIS;ﬁnd an IIS, emphasizing a quick result.

This looks for the ﬁrst IIS.
p.iisfirst(1)Further information
1. A model may have several infeasibilities. Repairing a single IIS may not make the model feasible. For
this reason the Optimizer can ﬁnd an IIS for each of the infeasibilities in a model. For the generation ofseveral independent IISs use functions problem.iisnext or problem.iisall.
2. IIS sensitivity ﬁlter: after an optimal but infeasible ﬁrst phase primal simplex, it is possible to identify asubproblem containing all the infeasibilities (corresponding to the given basis) to reduce the size of the
IIS working problem dramatically, i.e., rows with zero duals (thus with artiﬁcials of zero reduced cost)and columns that have zero reduced costs may be deleted. Moreover, for rows and columns with
nonzero costs, the sign of the cost is used to relax equality rows either to less than or greater thanequal rows, and to drop either possible upper or lower bounds on columns.
3. Initial infeasible subproblem: The subproblem identiﬁed after the sensitivity ﬁlter is referred to as initial
infeasible subproblem. Its size is crucial to the running time of the deletion ﬁlter and it contains all theinfeasibilities of the ﬁrst phase simplex, thus if the corresponding rows and bounds are removed the
problem becomes feasible.
4. problem.iisfirst performs the initial sensitivity analysis on rows and columns to reduce theproblem size, and sets up the initial infeasible subproblem. This subproblem signiﬁcantly speeds up
the generation of IISs, however in itself it may serve as an approximation of an IIS, since its
identiﬁcation typically takes only a fraction of time compared to the identiﬁcation of an IIS.
5. The IIS approximation and the IISs generated so far are always available.
Related topics
problem.getiisdata, problem.iisall, problem.iisclear, problem.iisisolations,problem.iisnext, problem.iisstatus, problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information

288

Reference Manual

problem.iisisolations
Purpose
Synopsis

Performs the isolation identiﬁcation procedure for an Irreducible Infeasible Set (IIS).
problem.iisisolations(num)Argument
num
ExampleThe number of the IIS identiﬁed by either problem.iisfirst, problem.iisnext, or
problem.iisall in which the isolations should be identiﬁed.

This example ﬁnds the ﬁrst IIS and searches for the isolations in that IIS.
if p.iisfirst(1) == 0:
iisisolations(1)Further information
1. An IIS isolation is a special constraint or bound in an IIS. Removing an IIS isolation constraint or boundwill remove all infeasibilities in the IIS without increasing the infeasibilities in any row or column outside
the IIS, thus in any other IISs. The IIS isolations thus indicate the likely cause of each independent
infeasibility and give an indication of which constraint or bound to drop or modify. It is not always
possible to ﬁnd IIS isolations.
2. Generally, one should ﬁrst look for rows or columns in the IIS which are both in isolation, and have ahigh dual multiplier relative to the others.
3. The num parameter cannot be zero: the concept of isolations is meaningless for the initial infeasible
subproblem.
Related topics
problem.getiisdata, problem.iisall, problem.iisclear, problem.iisfirst,
problem.iisnext, problem.iisstatus, problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information289

Reference Manual

problem.iisnext
Purpose

Synopsis
ExampleContinues the search for further Irreducible Infeasible Sets (IIS), or calls problem.iisfirst if no IIS
has been identiﬁed yet. The returned value is 0 in case of success; 1 if no more IIS could be found, or
problem is feasible if no problem.iisfirst call preceded; or 2 in case of an error.
status_code = problem.iisnext()
This looks for a further IIS.
while p.iisnext() == 0:[...] # do something with the iis

Further information
1. A model may have several infeasibilities. Repairing a single IIS may not make the model feasible. For
this reason the Optimizer attempts to ﬁnd an IIS for each of the infeasibilities in a model. Call the
problem.iisnext function repeatedly, or use the problem.iisall function to retrieve all IIS atonce.
2. This function is not affected by the control MAXIIS.
3. If the problem has been modiﬁed since the last call to problem.iisfirst or problem.iisnext,
the generation process has to be started from scratch.
Related topics
problem.getiisdata, problem.iisall, problem.iisclear, problem.iisfirst,
problem.iisisolations, problem.iisstatus, problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information

290

Reference Manual

problem.iisstatus
Purpose

Synopsis

Returns statistics on the Irreducible Infeasible Sets (IIS) found so far by problem.iisfirst,
problem.iisnext, or problem.iisall. The returned value is the number of IISs found so far.
iiscount = problem.iisstatus(rowsizes, colsizes, suminfeas, numinfeas)

Arguments
rowsizes
colsizes
suminfeas
numinfeas
ExampleNumber of rows in the IISs.
Number of bounds in the IISs.
The sum of infeasibilities in the IISs after the ﬁrst phase simplex.
The number of infeasible variables in the IISs after the ﬁrst phase simplex.

This example ﬁrst retrieves the number of IISs found so far, and then retrieves their main properties.
Note that the arrays have size count+1, since the ﬁrst index is reserved for the initial infeasible subset.
rs = []
cs = []
ninf = []p.iisstatus(rs, cs, numinfeas=ninf) # suminf is not of interest

Further information
1. The arrays are 0 based, index 0 corresponding to the initial infeasible subproblem.
2. The arrays may be None if not required.
3. For the initial infeasible problem (at position 0) the subproblem size is returned (which may be different
from the number of bounds), while for the IISs the number of bounds is returned (usually much smaller
than the number of columns in the IIS).
4. Note that the values in suminfeas and numinfeas heavily depend on the actual basis where thesimplex has stopped.
5. iiscount is set to -1 if the search for IISs has not yet started.
Related topics
problem.getiisdata, problem.iisall, problem.iisclear, problem.iisfirst,
problem.iisisolations, problem.iisnext, problem.iiswrite.

Fair Isaac Corporation Conﬁdential and Proprietary Information

291

Reference Manual

problem.iiswrite
Purpose

SynopsisWrites an LP/MPS/CSV ﬁle containing a given Irreducible Infeasible Set (IIS). If 0 is passed as the IIS
number parameter, the initial infeasible subproblem is written.
problem.iiswrite(num, fn, type, typeflags)

Arguments
num
fn
type
0
1
typeflags
ExampleThe ordinal number of the IIS to be written.
The name of the ﬁle to be created.
Type of ﬁle to be created:creates an lp/mps ﬁle containing the IIS as a linear programming problem;
creates a comma separated (csv) ﬁle containing the description and supplementary
information on the given IIS.
Flags passed to the problem.write function.

This writes the ﬁrst IIS (if one exists and is already found) as an lp ﬁle.
p.iiswrite(1, "iis.lp", 0, "l")Further information
1. Please note that there are problems on the boundary of being infeasible or not. For such problems,
feasibility or infeasibility often depends on tolerances or even on scaling. This phenomenon makes it
possible that after writing an IIS out as an LP ﬁle and reading it back, it may report feasibility. As a ﬁrst
check it is advised to consider the following options:(a) save the IIS using MPS hexadecimal format to eliminate rounding errors associated withconversion between internal and decimal representation.
(b) turn presolve off since the nature of an IIS makes it necessary that during their identiﬁcation thepresolve is turned off.
(c) use the primal simplex method to solve the problem.
2. Note that the original sense of the original objective function plays no role in an IIS.
3. Even though an attempt is made to identify the most infeasible IISs ﬁrst by the problem.iisfirst,
problem.iisnext, and problem.iisall functions, it is also possible that an IIS becomes justinfeasible in problems that are otherwise highly infeasible. In such cases, it is advised to try to deal withthe more stable IISs ﬁrst, and consider to use the infeasibility breaker tool if only slight infeasibilities
remain.
4. The LP or MPS ﬁles created by problem.iiswrite corresponding to an IIS contain no objectivefunction, since infeasibility is independent from the objective.
Related topics
problem.getiisdata, problem.iisall, problem.iisclear, problem.iisfirst,
problem.iisisolations, problem.iisnext, problem.iisstatus.

Fair Isaac Corporation Conﬁdential and Proprietary Information

292

Reference Manual

problem.interrupt
Purpose
SynopsisInterrupts the Optimizer algorithms.
problem.interrupt(reason)

Argument
reasonThe reason for stopping. Possible reasons are:xpress.stop_timelimit time limit hit;
xpress.stop_ctrlc
control C hit;
xpress.stop_nodelimit node limit hit;
xpress.stop_iterlimit iteration limit hit;
xpress.stop_mipgap MIP gap is sufﬁciently small;
xpress.stop_sollimit solution limit hit;
xpress.stop_user
user interrupt.

Further information
The interrupt command can be called from any callback.

Fair Isaac Corporation Conﬁdential and Proprietary Information

293

Reference Manual

problem.loadbasis
Purpose
Synopsis

Loads a basis as speciﬁed by the user.
problem.loadbasis(rstatus, cstatus)

Arguments
rstatuscstatus

ExampleArray of length problem.attributes.rows containing the basis status of the slack,surplus or artiﬁcial variable associated with each row. The status must be one of:0
slack, surplus or artiﬁcial is non-basic at lower bound;1
slack, surplus or artiﬁcial is basic;2
slack or surplus is non-basic at upper bound.
3
slack or surplus is super-basic.
Array of length problem.attributes.cols containing the basis status of each of
the columns in the constraint matrix. The status must be one of:0variable is non-basic at lower bound or superbasic at zero if the variable has nolower bound;1
variable is basic;
2
variable is at upper bound;3
variable is super-basic.

This example loads a problem and then reloads a (previously optimized) basis from a similar problem
to speed up the optimization:p.read("problem", "")p.loadbasis(rstatus, cstatus)
p.lpoptimize("")

Further information
If the problem has been altered since saving an advanced basis, one can alter the basis as follows
before loading it: Make new variables non-basic at their lower bound (cstatus[icol]=0), unless a variable has an

inﬁnite lower bound and a ﬁnite upper bound, in which case make the variable non-basic at its
upper bound (cstatus[icol]=2);

 Make new constraints basic (rstatus[jrow]=1);
 Try not to delete basic variables, or non-basic constraints.

Related topics
problem.getbasis, problem.getpresolvebasis, problem.loadpresolvebasis.

Fair Isaac Corporation Conﬁdential and Proprietary Information

294

Reference Manual

problem.loadbranchdirs
Purpose

Synopsis

Loads directives into the current problem to specify which global entities the Optimizer should continue
to branch on when a node solution is global feasible.
problem.loadbranchdirs(mcols, mbranch)

Arguments
mcols
mbranchArray containing the column numbers. A negative value indicates a set number (the ﬁrst
set being -1, the second -2, and so on).
Array containing either 0 or 1 for the entities given in mcols. Entities for which mbranch
is set to 1 will be branched on until ﬁxed before a global feasible solution is returned. If
mbranch is None, the branching directive will be set for all entities in mcols.

Related topics
problem.loaddirs, problem.readdirs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

295

Reference Manual

problem.loadcoefs
Purpose
Synopsis

Load non-linear coefﬁcients into the SLP problem
problem.loadcoefs(rowindex, colindex, factor, fstart, parsed, type, value)

Arguments
rowindex
colindex
factorfstartparsedtype
value
ExampleInteger array holding index of row for the coefﬁcient.
Integer array holding index of column for the coefﬁcient.
Double array holding factor by which formula is scaled. If this is None, then a value of
1.0 will be used.
Integer array holding the start position in the arrays Type and Value of the formula forthe coefﬁcients. FormulaStart[nSLPCoef] should be set to the next position after
the end of the last formula.
Integer indicating whether the token arrays are formatted as internal unparsed(Parsed=0) or internal parsed reverse Polish (Parsed=1).
Array of token types providing the formula for each coefﬁcient.
Array of values corresponding to the types in Type.

Assume that the rows and columns of Prob are named Row1, Row2 ..., Col1, Col2 ... The following
example loads coefﬁcients representing:
Col2 ⁎ Col3 + Col6 ⁎ Col2ˆ2 into Row1 andCol2 ˆ 2 into Row3.
rowindex = [Row1,Row1,Row3]
colindex = [Col2,Col6,Col2]
formulastart = []n = 0ncoef = 0
formulastart[ncoef], ncoef = n, ncoef + 1
Type[n], Value[n], n = xslp_op_col, 3, n+1
Type[n],n = xslp_op_eof,
n+1
formulastart[ncoef], ncoef = n, ncoef + 1
Type[n], Value[n], n = xslp_op_col, 2,
n+1
Type[n], Value[n], n = xslp_op_col, 2,
n+1
Type[n], Value[n], n = xslp_op_op, xslp_MULTIPLY, n+1
Type[n],n = xslp_op_eof,
n+1
formulastart[ncoef], ncoef = n, ncoef + 1
Type[n], Value[n], n = xslp_op_col, 2, n+1
Type[n],n = xslp_op_eof,
n+1
formulastart[ncoef] = n

Fair Isaac Corporation Conﬁdential and Proprietary Information

296

Reference Manualp.loadcoefs(rowindex, colindex, None, formulastart, 1, Type, Value)
The ﬁrst coefﬁcient in Row1 is in Col2 and has the formula Col3, so it represents Col2 ⁎ Col3.
The second coefﬁcient in Row1 is in Col6 and has the formula Col2 ⁎ Col2 so it represents Col6 ⁎Col2ˆ2. The formulae are described as parsed (parsed=1), so the formula is written as
Col2 Col2 ⁎rather than the unparsed form
Col2 ⁎ Col2The last coefﬁcient, in Row3, is in Col2 and has the formula Col2, so it represents Col2 ⁎ Col2.
Further information
The jth coefﬁcient is made up of two parts: Factor and Formula. Factor is a constant multiplier,which can be provided in the Factor array. If Xpress Nonlinear can identify a constant factor in
Formula, then it will use that as well, to minimize the size of the formula which has to be calculated.
Formula is made up of a list of tokens in Type and Value starting at FormulaStart[j]. The tokens
follow the rules for parsed or unparsed formulae as indicated by the setting of Parsed. The formula
must be terminated with an xslp_op_eof token. If several coefﬁcients share the same formula, they
can have the same value in FormulaStart. For possible token types and values see the chapter on"Formula Parsing".
The loadcoefs function loads items into the SLP problem. Any existing items of the same type aredeleted ﬁrst. The corresponding addcoefs function adds or replace items leaving other items of thesame type unchanged.
Related topics
problem.addcoefs, problem.chgnlcoef, problem.chgccoef, problem.getcoefformula,problem.getccoef

Fair Isaac Corporation Conﬁdential and Proprietary Information

297

Reference Manual

problem.loadcuts
Purpose

Synopsis

Loads cuts from the cut pool into the matrix. Without calling loadcuts the cuts will remain in the cutpool but will not be active at the node. Cuts loaded at a node remain active at all descendant nodes
unless they are deleted using problem.delcuts.
problem.loadcuts(itype, interp, cutind)Arguments
itype
interpmcutindCut type.
The way in which the cut type is interpreted:-1load all cuts;
1
treat cut types as numbers;
2
treat cut types as bit maps - load cut if any bit matches any bit set in
itype;
3
treat cut types as bit maps - 0 load cut if all bits match those set in itype.
Array containing the cuts to be loaded into the matrix.

Related topics
problem.addcuts, problem.delcpcuts, problem.delcuts, problem.getcpcutlist, Section"Working with the cut manager" of the Xpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

298

Reference Manual

problem.loaddelayedrows
Purpose

Synopsis

Speciﬁes that a set of rows in the problem will be treated as delayed rows during a global search.
These are rows that must be satisﬁed for any integer solution, but will not be loaded into the active setof constraints until required.
problem.loaddelayedrows(mrows)

Argument
mrows
ExampleAn array of rows (i.e. xpress.constraint objects, indices, or names) to treat asdelayed rows.

This sets the ﬁrst six matrix rows as delayed rows in the global problem prob.
p.loaddelayedrows([0,1,2,3,4,5])
p.mipoptimize("")

Further information
Delayed rows must be set up before solving the problem. Any delayed rows will be removed from the
problem after presolve and added to a special pool. A delayed row will be added back into the active
matrix only when such a row is violated by an integer solution found by the Optimizer.
Related topics
problem.loadmodelcuts.

Fair Isaac Corporation Conﬁdential and Proprietary Information

299

Reference Manual

problem.loaddfs
Purpose
Synopsis

Load a set of distribution factors
problem.loaddfs(colindex, rowindex, value)

Arguments
colindex
rowindexvalue
ExampleArray of columns whose distribution factor is to be changed.
Array of rows where each distribution factor applies.
Array of the new values of the distribution factors.

The following example loads distribution factors as follows:column 282 in row 134 = 0.1
column 282 in row 136 = 0.15
column 285 in row 133 = 1.0.
Any other ﬁrst-order derivative placeholders are set to xslp_DELTA_Z.
colindex = [282, 282, 285]
rowindex = [134, 136, 133]value
= [0.1, 0.15, 1]
p.loaddfs(colindex, rowindex, value)

Further information
The distribution factor of a column in a row is the matrix coefﬁcient of the corresponding delta vector in
the row. Distribution factors are used in conventional recursion models, and are essentially normalizedﬁrst-order derivatives. Xpress SLP can accept distribution factors instead of initial values, provided thatthe values of the variables involved can all be calculated after optimization using determining rows, orby a callback.
The adddfs functions load additional items into the SLP problem. The corresponding loaddfs
functions delete any existing items ﬁrst.
Related topics
problem.adddfs, problem.chgdf, problem.getdf

Fair Isaac Corporation Conﬁdential and Proprietary Information

300

Reference Manual

problem.loaddirs
Purpose
Synopsis

Loads directives into the problem.
problem.loaddirs(mcols, mpri, qbr, dupc, ddpc)

Arguments
mcols
mpri
qbr

dupc
ddpc

Array containing the column numbers. A negative value indicates a set number (the ﬁrst
set being -1, the second -2, and so on).
Array containing the priorities for the columns or sets. Priorities must be between 0 and
1000. May be None if not required.
Character array specifying the branching direction for each column or set:U
the entity is to be forced up;
Dthe entity is to be forced down;N
not speciﬁed.
May be None if not required.
Array containing the up pseudo costs for the columns or sets. May be None if not
required.
Array containing the down pseudo costs for the columns or sets. May be None if not
required.

Related topics
problem.getdirs, problem.loadpresolvedirs, problem.readdirs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

301

Reference Manual

problem.loadlpsol
Purpose

Synopsis

Loads an LP solution for the problem into the Optimizer. The returned status is either 0 if the solution isloaded or 1 if the solution is not loaded because the problem is in presolved status.
status = problem.loadlpsol(x, slack, dual, dj)

Argumentsx

Optional: Array of length problem.attributes.cols (for the original problem andnot the presolve problem) containing the values of the variables.
Optional: double array of length problem.attributes.rows containing the values ofslack variables.
Optional: double array of length problem.attributes.rows containing the values ofdual variables.
Optional: double array of length problem.attributes.cols containing the values of
reduced costs.

slack
dual
dj
ExampleThis example loads a problem and loads a solution for the problem.
p.read("problem", "")status = p.loadlpsol(x, None, dual, None)

Further information
1. At least one of variables x and dual variables dual must be provided.
2. When variables x is None, the variables will be set to their bounds.
3. When slack variables slack is None, it will be computed from variables x. If slacks are provided,variables cannot be omitted.
4. When dual variables dual is None, both dual variables and reduced costs will be set to zero.
5. When reduced costs dj is None, it will be computed from dual variables dual. If reduced costs areprovided, dual variables cannot be omitted.
Related topics
problem.getlpsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

302

Reference Manual

problem.loadmipsol
PurposeLoads a MIP solution for the problem into the Optimizer. The returned status is one of the following
values: -1: Solution rejected because an error occurred; 0: Solution accepted. When loading a solution before a MIP solve, the solution is always accepted.

See Further Information below.

 1: Solution rejected because it is infeasible; 2: Solution rejected because it is cut off;
 3: Solution rejected because the LP reoptimization was interrupted.

Synopsisstatus = problem.loadmipsol(dsol)

Argument
dsol
ExampleArray of length problem.attributes.cols (for the original problem and not thepresolve problem) containing the values of the variables.

This example loads a problem and then loads a solution found previously for the problem to help speed
up the MIP search:p.read("problem", "")status = p.loadmipsol(dsol)
p.mipoptimize("")

Further information
1. When a solution is loaded before a MIP solve, the solution is simply placed in temporary storage until
the MIP solve is started. Only after the MIP solve has commenced and any presolve has been applied,
will the loaded solution be checked and possibly accepted as a new incumbent integer solution. There
are no checks performed on the solution before the MIP solve and the returned status inproblem.loadmipsol will always be 0 for accepted.
2. Solutions can be loaded during a MIP solve using the optnode callback function. Any solution loaded
this way is immediately checked and the returned status will be one of the values 0 through 3.
3. Loaded solution values will automatically be adjusted to ﬁt within the current problem bounds.
Related topics
problem.getmipsol, problem.addcboptnode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

303

Reference Manual

problem.loadmodelcuts
Purpose
Synopsis

Speciﬁes that a set of rows in the problem will be treated as model cuts.
problem.loadmodelcuts(mrows)

Argument
mrows
ExampleAn array of rows (i.e. xpress.constraint objects, indices, or names) to be treated as
cuts.

This sets the ﬁrst six matrix rows as model cuts in the global problem myprob.
p.loadmodelcuts([0,1,2,3,4,5])
p.mipoptimize("")

Further information
1. During presolve the model cuts are removed from the problem and added to an internal cut pool. During
the global search, the Optimizer will regularly check this cut pool for any violated model cuts and add
those that cuts off a node LP solution.
2. The model cuts must be "true" model cuts, in the sense that they are redundant at the optimal MIP
solution. The Optimizer does not guarantee to add all violated model cuts, so they must not be required
to deﬁne the optimal MIP solution.

Fair Isaac Corporation Conﬁdential and Proprietary Information

304

Reference Manual

problem.loadpresolvebasis
Purpose
Synopsis

Loads a presolved basis from the user’s areas.
problem.loadpresolvebasis(rstatus, cstatus)

Arguments
rstatuscstatus

ExampleArray containing the basis status of the slack, surplus or artiﬁcial variable associatedwith each row. The status must be one of:0
slack, surplus or artiﬁcial is non-basic at lower bound;1
slack, surplus or artiﬁcial is basic;2
slack or surplus is non-basic at upper bound.
Array containing the basis status of each of the columns in the matrix. The status must
be one of:0variable is non-basic at lower bound or superbasic at zero if the variable has nolower bound;1
variable is basic;
2
variable is at upper bound;3
variable is super-basic.

The following example saves the presolved basis for one problem, loading it into another:p1 = xpress.problem()
p2 = xpress.problem()
p1.read("myprob", "")p1.mipoptimize("l")
rs = []
cs = []
p1.getpresolvebasis(rs, cs)
p2.read("myprob2", "")p2.mipoptimize("l")
p2.loadpresolvebasis(rs, cs)

Related topics
problem.getbasis, problem.getpresolvebasis, problem.loadbasis.

Fair Isaac Corporation Conﬁdential and Proprietary Information

305

Reference Manual

problem.loadpresolvedirs
Purpose
Synopsis

Loads directives into the presolved matrix.
problem.loadpresolvedirs(mcols, mpri, qbr, dupc, ddpc)

Arguments
mcols
mpri
qbr

dupc
ddpc
ExampleArray containing the column numbers. A negative value indicates a set number (-1being the ﬁrst set, -2 the second, and so on).
Array containing the priorities for the columns or sets. May be None if not required.
Character array specifying the branching direction for each column or set:U
the entity is to be forced up;
Dthe entity is to be forced down;N
not speciﬁed.
May be None if not required.
Array containing the up pseudo costs for the columns or sets. May be None if not
required.
Array containing the down pseudo costs for the columns or sets. May be None if not
required.

The following loads priority directives for column 0 in the problem:
p.mipoptimize("l")
p.loadpresolvedirs([0], [1], None, None, None)
p.mipoptimize("")

Related topics
problem.getdirs, problem.loaddirs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

306

Reference Manual

problem.loadproblem
Purpose

Synopsis

Load an optimization problem, possibly with quadratic objective and/or constraints, and integer
variables.
problem.loadproblem(probname, qrtypes, rhs, range, obj, mstart, mnel,
mrwind, dmatval, dlb, dub, mqcol1, mqcol2, dqe, qcrows, qcnquads,
qcmqcol1, qcmqcol2, qcdqval, qgtype, mgcols, dlim, qstype, msstart,
mscols, dref, colnames, rownames)

Arguments
probname
qrtype

rhs
range

obj
mstartmnel

mrwinddmatval
dlb
dub
mqc1
mqc2
dqe
qcrowsqcnquads

A string of up to 200 characters containing the problem name.
Character array containing the row types:
Lindicates a <= constraint;E
indicates an = constraint;G
indicates a >= constraint;R
indicates a range constraint;N
indicates a nonbinding constraint.
Array containing the right hand side coefﬁcients of the rows. The right hand side value
for a range row gives the upper bound on the row.
Array containing the range values for range rows. Values for all other rows will beignored. May be None if there are no ranged constraints. The lower bound on a range
row is the right hand side value minus the range value. The sign of the range value isignored - the absolute value is used in all cases.
Array containing the objective function coefﬁcients.
Array containing the offsets in the mrwind and dmatval arrays of the start of theelements for each column. This array is of length equal to the number ncol of added
variables or, if mnel is None, ncol+1. If mnel is None the extra entry of mstart,
mstart[ncol], contains the position in the mrwind and dmatval arrays at which an
extra column would start, if it were present.
Array containing the number of nonzero elements in each column. May be None if allelements are contiguous and mstart[ncol] contains the offset where the elements
for column ncol+1 would start. This array is not required if the non-zero coefﬁcients inthe mrwind and dmatval arrays are continuous, and the mstart array has ncol+1
entries as described above. It may be None if not required.
Array containing the row indices for the nonzero elements in each column. If the indices
are input contiguously, with the columns in ascending order, the length of the mrwind ismstart[ncol-1]+mnel[ncol-1] or, if mnel is None, mstart[ncol].
Array containing the nonzero element values; length as for mrwind.
Array containing the lower bounds on the columns. Use -xpress.infinity torepresent a lower bound of minus inﬁnity.
Array containing the upper bounds on the columns. Use xpress.infinity torepresent an upper bound of plus inﬁnity.
(optional) Array with the ﬁrst variable in each quadratic term.
(optional) Array with the second variable in each quadratic term.
(optional) Array with the quadratic coefﬁcients.
(optional) Integer containing the indices of rows with quadratic matrices in them. Notethat the rows are expected to be deﬁned in qrtype as type L.
(optional) Array containing the number of nonzeros in each quadratic constraint matrix.

Fair Isaac Corporation Conﬁdential and Proprietary Information

307

Reference Manual

qcmqcol1

qcmqcol2
qcdqvalqgtypemgcolsdlim

qstypemsstartmscolsdref
colnamerowname(optional) Array with a number of elements equal to the sum of the elements in
qcnquads (i.e. the total number of quadratic matrix elements in all the constraints). It
contains the ﬁrst column indices of the quadratic matrices. Indices for the ﬁrst matrix
are listed from 0 to qcnquads[0]-1, for the second matrix from qcnquads[0] to
qcnquads[0]+ qcnquads[1]-1, etc.
(optional) Array containing the second index for the quadratic constraint matrices.
(optional) Array containing the coefﬁcients for the quadratic constraint matrices.
Character array containing the entity types:
Bbinary variables;I
integer variables;P
partial integer variables;Ssemi-continuous variables;Rsemi-continuous integer variables.
(optional) Array containing the variables of the global entities.
(optional) Array containing the integer limits for the partial integer variables and lower
bounds for semi-continuous and semi-continuous integer variables (any entries in thepositions corresponding to binary and integer variables will be ignored). May be None if
not required.
(optional) Character array of length equal to the number of sets speciﬁed,
problem.attributes.nsets, and speciﬁes the set types:
1
SOS1 type sets;
2
SOS2 type sets.
May be None if not required.
(optional) Array containing the offsets in the mscols and dref arrays indicating thestart of the sets. This array is of length nsets+1, the last member containing the offset
where set nsets+1 would start. May be None if not required.
(optional) Array of length msstart[nsets]-1 containing the columns in each set.
May be None if not required.
(optional) Array of length msstart[nsets]-1 containing the reference row entries foreach member of the sets. May be None if not required.
(optional) Array of containing the column names for all variables added.
(optional) Array of containing the row names for all constraints added.

Further information
1. The objective function is of the form cT x+ 1/2 xT Qx where Q is positive semi-deﬁnite forminimization problems and negative semi-deﬁnite for maximization problems. If this is not the casethe optimization algorithms may converge to a local optimum or may not converge at all. Note that only
the upper or lower triangular part of the Q matrix is speciﬁed.
2. All Q matrices in the constraints must be positive semi-deﬁnite. Note that only the upper or lower
triangular part of the Q matrix is speciﬁed for constraints as well.
3. If indices are speciﬁed, both row and column indices are from 0 to rows-1 and 0 to cols-1
respectively.
4. Semi-continuous lower bounds are taken from the dlim array. If this is None then they are given adefault value of 1.0. If a semi-continuous variable has a positive lower bound then this will be used as
the semi-continuous lower bound and the lower bound on the variable will be set to zero.
Related topics
problem.read.

Fair Isaac Corporation Conﬁdential and Proprietary Information

308

Reference Manual

problem.loadsecurevecs
Purpose

Synopsis

Allows the user to mark rows and columns in order to prevent the presolve removing these rows andcolumns from the problem.
problem.loadsecurevecs(mrow, mcol)

Argumentsmrow
mcol
ExampleArray containing the rows to be marked. May be None if not required.
Array containing the columns to be marked. May be None if not required.

This sets the ﬁrst six rows and the ﬁrst four columns to not be removed during presolve.
p.read("myprob", "")p.loadsecurevecs(mrow=[0,1,2,3,4,5], mcol=[0,1,2,3])
p.mipoptimize("")

Fair Isaac Corporation Conﬁdential and Proprietary Information309

Reference Manual

problem.loadtolsets
Purpose
Synopsis

Load sets of standard tolerance values into an SLP problem
problem.loadtolsets(slptol)

Argument
slptolExampleArray of 9h items containing the 9 tolerance values for each set in order.

The following example creates two tolerance sets: the ﬁrst has values of 0.005 for all tolerances; thesecond has values of 0.001 for relative tolerances (numbers 2,4,6,8), values of 0.01 for absolute
tolerances (numbers 1,3,5,7) and zero for the closure tolerance (number 0).
tol = 9⁎[0.005]+[0]+[0.01,0.001]⁎4
p.loadtolsets(tol)Further information
A tolerance set is an array of 9 values containing the following tolerances:
Entry / Bit

ToleranceXSLP constantXSLP bit constant0

Closure tolerance (TC)xslp_TOLSET_TC

xslp_TOLSETBIT_TC

1

Absolute delta tolerance (TA)xslp_TOLSET_TA

xslp_TOLSETBIT_TA

2

Relative delta tolerance (RA)xslp_TOLSET_RA

xslp_TOLSETBIT_RA

3

Absolute coefﬁcient tolerance (TM)xslp_TOLSET_TM

xslp_TOLSETBIT_TM

4

Relative coefﬁcient tolerance (RM)

xslp_TOLSET_RM

xslp_TOLSETBIT_RM

5

Absolute impact tolerance (TI)

xslp_TOLSET_TI

xslp_TOLSETBIT_TI

6

Relative impact tolerance (RI)

xslp_TOLSET_RI

xslp_TOLSETBIT_RI

7

Absolute slack tolerance (TS)xslp_TOLSET_TS

xslp_TOLSETBIT_TS

8

Relative slack tolerance (RS)xslp_TOLSET_RS

xslp_TOLSETBIT_RS

The xslp_TOLSET constants can be used to access the corresponding entry in the value arrays, whilethe xslp_TOLSETBIT constants are used to set or retrieve which tolerance values are used for a given
SLP variable.
Once created, a tolerance set can be used to set the tolerances for any SLP variable. If a tolerance value
is zero, then the default tolerance will be used instead. To force the use of a tolerance, use theproblem.chgtolset function and set the Status variable appropriately.
See the section "Convergence Criteria" in the SLP reference manual for a fuller description of tolerances
and their uses. The loadtolsets functions load items into the SLP problem. Any existing items of thesame type are deleted ﬁrst. The corresponding addtolsets functions add or replace items leaving
other items of the same type unchanged.
Related topics
problem.addtolsets, problem.deltolsets, problem.chgtolset, problem.gettolset

Fair Isaac Corporation Conﬁdential and Proprietary Information

310

Reference Manual

problem.loadvars
Purpose
Synopsis

Load SLP variables deﬁned as matrix columns into an SLP problem
problem.loadvars (colindex, vartype, detrow, seqnum, tolindex, initvalue,
stepbound)Arguments
colindex
vartypedetrow

seqnumtolindex

initvalue

stepbound

ExampleInteger array holding the index of the matrix column corresponding to each SLP variable.
Bitmap giving information about the SLP variable as follows:
Bit 1
Variable has a delta vector;
Bit 2
Variable has an initial value;
Bit 14
Variable is the reserved "=" column;
May be None if not required.
Integer array holding the index of the determining row for each SLP variable (a negativevalue means there is no determining row)
May be None if not required.
Integer array holding the index sequence number for cascading for each SLP variable (azero value means there is no pre-deﬁned order for this variable)
May be None if not required.
Integer array holding the index of the tolerance set for each SLP variable (a zero valuemeans the default tolerances are used)
May be None if not required.
Double array holding the initial value for each SLP variable (use the VarType bit map to
indicate if a value is being provided)
May be None if not required.
Double array holding the initial step bound size for each SLP variable (a zero valuemeans that no initial step bound size has been speciﬁed). If a value ofxpress.infinity is used for a value in StepBound, the delta will never have stepbounds applied, and will almost always be regarded as converged.
May be None if not required.

The following example loads two SLP variables into the problem. They correspond to columns 23 and25 of the underlying LP problem. Column 25 has an initial value of 1.42; column 23 has no speciﬁc
initial value
colindex = [23,25]
vartype= [0,2]
initvalue = [0,1.42]
p.loadvars(colindex, vartype, None, None, None, initvalue, None)
InitValue is not set for the ﬁrst variable, because it is not used (VarType = 0). Bit 1 of VarType isset for the second variable to indicate that the initial value has been set. The arrays for determining
rows, sequence numbers, tolerance sets and step bounds are not used at all, and so have been passed
to the function as None.

Further information
The loadvars functions load items into the SLP problem. Any existing items of the same type aredeleted ﬁrst. The corresponding addvars functions add or replace items leaving other items of thesame type unchanged.

Fair Isaac Corporation Conﬁdential and Proprietary Information

311

Reference Manual

Related topics
problem.addvars, problem.chgvar, problem.delvars, problem.getvar

Fair Isaac Corporation Conﬁdential and Proprietary Information

312

Reference Manual

problem.lpoptimize
Purpose

Synopsis

This function begins a search for the optimal continuous (LP) solution. The direction of optimization is
given by OBJSENSE. The status of the problem when the function completes can be checked using
LPSTATUS. Any global entities in the problem will be ignored.
problem.lpoptimize(flags)

Argument
flags(optional) Flags to pass to lpoptimize. The default is "" or None, in which case thealgorithm used is determined by the DEFAULTALG control. If the argument includes:b
the model will be solved using the Newton barrier method;p
the model will be solved using the primal simplex algorithm;dthe model will be solved using the dual simplex algorithm;
n(lower case N), the network part of the model will be identiﬁed and solved using
the network simplex algorithm;

Further information
1. The algorithm used to optimize is determined by the DEFAULTALG control if no ﬂags are provided. By
default, the dual simplex is used for linear problems and the barrier is used for non-linear problems.
2. The d and p ﬂags can be used with the n ﬂag to complete the solution of the model with either the dual
or primal algorithms once the network algorithm has solved the network part of the model.
3. The b ﬂag cannot be used with the n ﬂag.
Related topics
problem.mipoptimize, Chapter 4 of the Xpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

313

Reference Manual

problem.mipoptimize
Purpose

Synopsis

This function begins a global search for the optimal MIP solution. The direction of optimization is given
by OBJSENSE. The status of the problem when the function completes can be checked using
MIPSTATUS.
problem.mipoptimize(flags)

Argument
flags(optional) Flags to pass to problem.mipoptimize, which speciﬁes how to solve theinitial continuous problem where the global entities are relaxed. If the argument
includes:b
the initial continuous relaxation will be solved using the Newton barrier method;p
the initial continuous relaxation will be solved using the primal simplex algorithm;dthe initial continuous relaxation will be solved using the dual simplex algorithm;n
the network part of the initial continuous relaxation will be identiﬁed and solved
using the network simplex algorithm;
lstop after having solved the initial continous relaxation.

Further information
1. If the l ﬂag is used, the Optimizer will stop immediately after solving the initial continuous relaxation.
The status of the continuous solve can be checked with LPSTATUS and standard LP results areavailable, such as the objective value (LPOBJVAL) and solution (use problem.getlpsol), depending
on LPSTATUS.
2. It is possible for the Optimizer to ﬁnd integer solutions before solving the initial continuous relaxation,either through heuristics or by having the user load an initial integer solution. This can potentially resultin the global search ﬁnishing before solving the continuous relaxation to optimality.
3. If the function returns without having completed the search for an optimal solution, the search can beresumed from where it stopped by calling problem.mipoptimize again.
4. The algorithm used to reoptimize the continuous relaxations during the global search is given by
DEFAULTALG. The default is to use the dual simplex algorithm.
Related topics
problem.mipoptimize.

Fair Isaac Corporation Conﬁdential and Proprietary Information

314

Reference Manual

problem.msaddcustompreset
Purpose

Synopsis

A combined version of msaddjob and msaddpreset. The preset described is loaded, topped up with thespeciﬁc settings supplied
problem.msaddcustompreset(description, preset, count, ivcols, ivvalues,
control, job_object)Arguments
description Text description of the job. Used for messaging, may be None if not required.
presetWhich preset to load.
ivcolsIndices of the variables for which to set an initial value. May be None if nIVs is zero.
ivvalues
Initial values for the variables for which to set an initial value. May be None if nIVs iszero.
control
Python dictionary with control strings as keys and numbers as values. Note that only
numerical controls are allowed.
job_object Job-speciﬁc user context object to be passed to the multistart callbacks.
Further information
This function allows for repeatedly calling the same multistart preset (e.g. initial values) using different
basic controls.
Related topics
problem.msaddpreset, problem.msaddjob, problem.msclear

Fair Isaac Corporation Conﬁdential and Proprietary Information

315

Reference Manual

problem.msaddjob
Purpose
Synopsis

Adds a multistart job to the multistart poolproblem.msaddjob(description, ivcols, ivvalues, control, job_object)Arguments
description Text description of the job. Used for messaging, may be None if not required.
ivcolsIndices of the variables for which to set an initial value. May be None if nIVs is zero.
ivvalues
Initial values for the variables for which to set an initial value. May be None if nIVs iszero.
control
Python dictionary with control strings as keys and numbers as values. Note that only
numerical controls are allowed.
job_object Job-speciﬁc user context object to be passed to the multistart callbacks.
Further information
Adds a mutistart job, applying the speciﬁed initial point and option combinations on top of the baseproblem, i.e. the options and initial values speciﬁed to the function is applied on top of the existing
settigns.
This function allows for loading empty template jobs, that can then be identiﬁed using the pJobObject
variable.
Related topics
problem.msaddpreset, problem.msaddcustompreset, problem.msclear

Fair Isaac Corporation Conﬁdential and Proprietary Information

316

Reference Manual

problem.msaddpreset
Purpose
Synopsis

Loads a preset of jobs into the multistart job pool.
problem.msaddpreset(description, preset, count, job_object)Arguments
description Text description of the preset. Used for messaging, may be None if not required.
presetWhich preset to load.
count
Maximum number of jobs to be added to the multistart pool.
job_object Job-speciﬁc user context object to be passed to the multistart callbacks.
Further information
The following presets are deﬁned:
msset_initialvalues: generate count number of random base points.
msset_solvers: load all solvers.
msset_slp_basic: load the most typical SLP tuning settings. A maximum of count jobs are loaded.
msset_slp_extended: load a comprehensive set of SLP tuning settings. A maximum of count jobs
are loaded.
msset_knitro_basic: load the most typical Knitro tuning settings. A maximum of count jobs areloaded.
msset_knitro_extended: load a comprehensive set of Knitro tuning settings. A maximum ofcount jobs are loaded.
msset_initialfiltered: generate count number of random base points, ﬁltered by a merit
function centred on initial feasibility.
See xslp_MSMAXBOUNDRANGE for controlling the range in which initial values are generated.
Related topics
problem.msaddjob, problem.msaddcustompreset, problem.msclear

Fair Isaac Corporation Conﬁdential and Proprietary Information

317

Reference Manual

problem.msclear
Purpose
Synopsis

Removes all scheduled jobs from the multistart job poolproblem.msclear()

Related topics
problem.msaddjob, problem.msaddpreset, problem.msaddcustompreset

Fair Isaac Corporation Conﬁdential and Proprietary Information

318

Reference Manual

problem.name
Purpose
Synopsis

Returns the name of the problem as a Python string.
brian = problem.name()

Related topics
problem.setprobname.

Fair Isaac Corporation Conﬁdential and Proprietary Information319

Reference Manual

problem.nlpoptimize
Purpose
Synopsis

Solves an SLP problem
problem.nlpoptimize(flags)

Argument
flags Flags affecting the solve. See the SLP reference manual for their meaning
Related topics
problem.globalsol

Fair Isaac Corporation Conﬁdential and Proprietary Information

320Reference Manual

problem.objsa
Purpose

Synopsis

Returns upper and lower sensitivity ranges for speciﬁed objective function coefﬁcients. If the objective
coefﬁcients are varied within these ranges the current basis remains optimal and the reduced costs
remain valid.
problem.objsa(mindex, lower, upper)

Arguments
mindexlower
upper
ExampleArray containing the columns (i.e. xpress.var objects, indices, or names) whose
objective function coefﬁcients sensitivity ranges are required.
Array of the same size as mindex where the objective function lower range values areto be returned.
Array of the same size as mindex where the objective function upper range values areto be returned.

Here we obtain the objective function ranges for the three columns: 2, 6 and 8:
l = []
u = []
p.objsa([2,8,6], l, u)
After which l and u contain:l = [5, 3.8, 5.7]
u = [7, 5.2, 1e+20]
Meaning that the current basis remains optimal when 5.0 ≤ C2 ≤ 7.0, 3.8 ≤ C8 ≤ 5.2 and 5.7 ≤ C6 , Ci
being the objective coefﬁcient of column i.

Further information
objsa can only be called when an optimal solution to the current LP has been found. It cannot be used
when the problem is MIP presolved.
Related topics
problem.rhssa.

Fair Isaac Corporation Conﬁdential and Proprietary Information

321

Reference Manual

problem.postsolve
Purpose
Synopsis

Postsolve the current problem when it is in a presolved state.
problem.postsolve()

Further information
A problem is left in a presolved state whenever a LP or MIP optimization does not complete. In thesecases postsolve can be called to get the problem back into its original state.
Related topics
problem.lpoptimize, problem.mipoptimize.

Fair Isaac Corporation Conﬁdential and Proprietary Information322

Reference Manual

problem.presolve
Purpose
Synopsis
ExamplePerform a nonlinear presolve on the problem
problem.presolve()
The following example reads a problem from ﬁle, sets the presolve control, presolves the problem andthen maximizes it.
p.readprob("Matrix", "")p.controls.xslp_presolve = 1
p.presolve()p.solve("")

Further information
If bit 1 of xslp_presolve is not set, no nonlinear presolve will be performed. Otherwise, the presolve
will be performed in accordance with the bit settings. problem.presolve is called automatically by
problem.construct, so there is no need to call it explicitly unless there is a requirement to interrupt
the process between presolve and optimization. problem.presolve must be called before
problem.construct or any of the SLP optimization procedures..
Related topics
xslp_presolve

Fair Isaac Corporation Conﬁdential and Proprietary Information

323

Reference Manual

problem.presolverow
PurposePresolves a row formulated in terms of the original variables such that it can be added to a presolved
problem. Returns a tuple of two elements containing, respectively, the presolved right-hand side andthe status of the presolved row: -3: Failed to presolve the row due to presolve dual reductions; -2: Failed to presolve the row due to presolve duplicate column reductions; -1: Failed to presolve the row due to an error. Check the Optimizer error code for the cause; 0: The row was successfully presolved;
 1: The row was presolved, but may be relaxed.

Synopsis

drhsp, status = problem.presolverow(qrtype, mcolso, dvalo, drhso,
maxcoeffs, mcolsp, dvalp)

Arguments
qrtypemcolsodvalo
drhso
maxcoeffs
mcolspdvalp
ExampleThe type of the row:L
indicates a ≤ row;G
indicates a ≥ row.
Array containing the columns (i.e. xpress.var objects, indices, or names) of the row
to presolve.
Array containing the non-zero coefﬁcients of the row to presolve.
The right-hand side constant of the row to presolve.
Maximum number of elements to return in the mcolsp and dvalp arrays.
Array which will be ﬁlled with the columns of the presolved row.
Array which will be ﬁlled with the coefﬁcients of the presolved row.

Adding the row 2x1 + x2 ≤ 1 to our presolved problem can be done as follows:presind = []prescoe = []prhs, status = p.presolverow('L', [1,2], [2,1], 1.0,
p.attributes.cols, presind, prescoe)

Further information
There are certain presolve operations that can prevent a row from being presolved exactly. If the row
contains a coefﬁcient for a column that was eliminated due to duplicate column reductions or
singleton column reductions, the row might have to be relaxed to remain valid for the presolved
problem. The relaxation will be done automatically by the problem.presolverow function, but areturn status of +1 will be returned. If it is not possible to relax the row, a status of -2 will be returned
instead. Likewise, it is possible that certain dual reductions prevents the row from being presolved. Insuch a case a status of -3 will be returned instead.
If problem.presolverow is used for presolving e.g. branching bounds or constraints, then dual
reductions and duplicate column reductions should be disabled, by clearing the corresponding bits of
PRESOLVEOPS. By clearing these bits, the default value for PRESOLVEOPS changes to 471.
If the user knows in advance which columns will have non-zero coefﬁcients in rows that will bepresolved, it is possible to protect these individual columns through the problem.loadsecurevecs
function. This way the Optimizer is left free to apply all possible reductions to the remaining columns.
Related topics
problem.addcuts, problem.loadsecurevecs, problem.setbranchcuts,
problem.storecuts.

Fair Isaac Corporation Conﬁdential and Proprietary Information324

Reference Manual

problem.printmemory
Purpose
Synopsis
ExamplePrint the dimensions and memory allocations for a problem
problem.printmemory()
The following example loads a problem from ﬁle and then prints the dimensions of the arrays.
p.readprob("Matrix1", "")p.printmemory()
The output is similar to the following:
Arraysand dimensions: Array Item Used Max Allocated Memory Size Items Items
Memory Control MemList 28 103 129 4K String 1 8779 13107 13K
xslp_MEM_STRING Xv 16 2 1000 16K xslp_MEM_XV Xvitem 48 11 1000 47K
xslp_MEM_XVITEM ....

Further information
printmemory lists the current sizes and amounts used of the variable arrays in the current problem.
For each array, the size of each item, the number used and the number allocated are shown, together
with the size of memory allocated and, where appropriate, the name of the memory control variable toset the array size. Loading and execution of some problems can be speeded up by setting the memory
controls immediately after the problem is created. If an array has to be moved to re-allocate it with alarger size, there may be insufﬁcient memory to hold both the old and new versions; pre-setting thememory controls reduces the number of such re-allocations which take place and may allow larger
problems to be solved.

Fair Isaac Corporation Conﬁdential and Proprietary Information

325

Reference Manual

problem.printevalinfo
Purpose
Synopsis

Print a summary of any evaluation errors that may have occurred during solving a problem
problem.printevalinfo()

Related topics
problem.setcbcoefevalerror

Fair Isaac Corporation Conﬁdential and Proprietary Information326

Reference Manual

problem.read
Purpose

Synopsis

Read an optimization problem into a Python problem object created prior to the call. All formats
allowed by the Xpress Optimizer C API are allowed.
problem.read(filename, flags)

Arguments
filename
flags

ExampleA string of up to 200 characters with the name of the ﬁle to be read.
(optional) Flags to pass to read:lonly the .lp version of the ﬁle is searched.
z
read the input ﬁle in compressed .gz format.

Read problem problem1.lp and output an optimal solution:p.read("problem1", "l")p.solve("", "")print("solution of problem1.lp:", p.getSolution())

Related topics
problem.write.

Fair Isaac Corporation Conﬁdential and Proprietary Information

327

Reference Manual

problem.readbasis
Purpose
Synopsis

Instructs the Optimizer to read in a previously saved basis from a ﬁle.
problem.readbasis(filename, flags)

Arguments
filename
flags

ExampleA string of up to 200 characters containing the ﬁle name from which the basis is to beread. If omitted, the default problem_name is used with a .bss extension.
(optional) Flags to pass to readbasis:i
output the internal presolved basis.
tinput a compact advanced form of the basis;

If an advanced basis is available for the current problem the Optimizer input might be:p.read("filename", "")p.readbasis("", "")p.mipoptimize("")
This reads in a matrix ﬁle, inputs an advanced starting basis and maximizes the MIP.

Further information
1. The only check done when reading compact basis is that the number of rows and columns in the basis
agrees with the current number of rows and columns.
2. readbasis will read the basis for the original problem even if the problem has been presolved. The
Optimizer will read the basis, checking that it is valid, and will display error messages if it detects
inconsistencies.
Related topics
problem.loadbasis, problem.writebasis.

Fair Isaac Corporation Conﬁdential and Proprietary Information

328

Reference Manual

problem.readbinsol
Purpose
Synopsis

Reads a solution from a binary solution ﬁle.
problem.readbinsol(filename, flags)

Arguments
filename
flags
ExampleA string of up to 200 characters containing the ﬁle name from which the solution is tobe read. If omitted, the default problem_name is used with a .sol extension.
(optional) Flags to pass to readbinsol:mload the solution as a solution for the MIP.

A previously saved solution can be loaded into memory and a print ﬁle created from it with thefollowing commands:
p.read("myprob", "")p.readbinsol("", "")p.writeprtsol("", "")Related topics
problem.getlpsol, problem.getmipsol, problem.writebinsol, problem.writesol,
problem.writeprtsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information329

Reference Manual

problem.readdirs
Purpose
Synopsis

Reads a directives ﬁle to help direct the global search.
problem.readdirs(filename)Argument
filename
ExampleA string of up to 200 characters containing the ﬁle name from which the directives are to
be read. If omitted (or None), the default problem_name is used with a .dir extension.

The following example reads in directives from the ﬁle dirfile.dir for use with the problem, prob2:
p.read("prob2","")
p.readdirs("dirfile")
p.mipoptimize("")

Further information
1. Directives cannot be read in after a model has been presolved, so unless presolve has been disabled by
setting PRESOLVE to 0, this command must be issued before problem.mipoptimize.
2. Directives can be given relating to priorities, forced branching directions, pseudo costs and model cuts.
There is a priority value associated with each global entity. The lower the number, the more likely theentity is to be selected for branching; the higher, the less likely. By default, all global entities have apriority value of 500 which can be altered with a priority entry in the directives ﬁle. In general, it isadvantageous for the entity’s priority to reﬂect its relative importance in the model. Priority entries withvalues in excess of 1000 are illegal and are ignored. A full description of the directives ﬁle format may
be found in the Xpress Optimizer reference manual.
3. By default, problem.mipoptimize will explore the branch expected to yield the best integer solution
from each node, irrespective of whether this forces the global entity up or down. This can be overriddenwith an UP or DN entry in the directives ﬁle, which forces mipoptimize to branch up ﬁrst or down ﬁrst
on the speciﬁed entity.
4. Pseudo-costs are estimates of the unit cost of forcing an entity up or down. By default mipoptimize
uses dual information to calculate estimates of the unit up and down costs and these are added to thedefault pseudo costs which are set to the PSEUDOCOST control. The default pseudo costs can beoverridden by a PU or PD entry in the directives ﬁle.
5. If model cuts are used, then the speciﬁed constraints are removed from the problem and added to the
Optimizer cut pool, and only put back in the problem when they are violated by an LP solution at one of
the nodes in the global search.
6. If creating a directives ﬁle by hand, wild cards can be used to specify several vectors at once, forexample PR x1⁎ 2 will give all global entities whose names start with x1 a priority of 2.
Related topics
problem.loaddirs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

330

Reference Manual

problem.readslxsol
Purpose
Synopsis

Reads an ASCII solution ﬁle (.slx) created by the problem.writeslxsol function.
problem.readslxsol(filename, flags)

Arguments
filenameflags

A string of up to 200 characters containing the ﬁle name to which the solution is to beread. If omitted, the default problem_name is used with a .slx extension.
(optional) Flags to pass to writeslxsol:lread the solution as an LP solution in case of a MIP problem;mread the solution as a solution for the MIP problem;areads multiple MIP solutions from the .slx ﬁle and adds them to the MIP
problem.

Examplep.readslxsol("lpsolution", "")This loads the solution to the MIP problem if the problem contains global entities, or otherwise loads it
as an LP (barrier in case of quadratic problems) solution into the problem.
Further information
1. When readslxsol is called before a MIP solve, the loaded solutions will not be checked before callingproblem.mipoptimize. By default, only the last MIP solution read from the .slx ﬁle will be stored.
Use the a ﬂag to store all MIP solutions read from the ﬁle.
2. When using the a ﬂag, read solutions will be queued similarly to the user of the problem.addmipsol
function. Each name string given by the NAME ﬁeld in the .slx ﬁle will be associated with thecorresponding solution. Any registered usersolnotify callback will be ﬁred when the solution has
been checked, and will include the read name string as one of its arguments.
3. Refer to the Appendix of the Xpress Optimizer reference manual on Log and File Formats for a
description of the ASCII Solution (.slx) ﬁle format.
Related topics
problem.readbinsol, problem.writeslxsol, problem.writebinsol,
problem.readbinsol, problem.addmipsol, problem.addcbusersolnotify.

Fair Isaac Corporation Conﬁdential and Proprietary Information

331

Reference Manual

problem.reﬁnemipsol
Purpose
Synopsis

Runs the MIP solution reﬁner.
problem.refinemipsol(options, flags, solution, refined_solution)

Arguments
options

Reﬁnement options:0Reducing MIP fractionality is priority.
1
Reducing LP infeasiblity is priority
flags
Flags passed to any optimization calls during reﬁnement.
solution
The MIP solution to reﬁne. Must be a valid MIP solution.
refined_solution The reﬁned MIP solution in case of successrefinestatus Reﬁnement results:
0
An error has occurred1
The solution has been reﬁned
2
Current solution meets target criteria
3
Solution cannot be reﬁned

Further information
The function provides a mechanism to reﬁne the MIP solution by attempting to round any fractional
global entity and by attempting to reduce LP infeasiblity.
Related topics
REFINEOPS.

Fair Isaac Corporation Conﬁdential and Proprietary Information

332

Reference Manual

problem.reinitialize
Purpose
Synopsis

Reset the SLP problem to match a just augmented systemproblem.reinitialize()

Further information
Can be used to rerun the SLP optimization process with updated parameters, penalties or initial values,
but unchanged augmentation.
Related topics
problem.unconstruct, problem.setcurrentiv,

Fair Isaac Corporation Conﬁdential and Proprietary Information

333Reference Manual

problem.removecbbariteration
Purpose

Synopsis

Removes a barrier iteration callback function previously added by addcbbariteration. The
speciﬁed callback function will no longer be called after it has been removed.
problem.removecbbariteration(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all bariteration callback functions addedwith the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all barrier iteration callbacks with the function callback will be
removed.

Related topics
problem.addcbbariteration.

Fair Isaac Corporation Conﬁdential and Proprietary Information

334

Reference Manual

problem.removecbbarlog
Purpose

Synopsis

Removes a newton barrier log callback function previously added by addcbbarlog. The speciﬁed
callback function will no longer be called after it has been removed.
problem.removecbbarlog(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all barrier log callback functions addedwith the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all barrier log callbacks with the function callback will be removed.

Related topics
problem.addcbbarlog.

Fair Isaac Corporation Conﬁdential and Proprietary Information

335

Reference Manual

problem.removecbchecktime
Purpose

Synopsis

Removes a callback function previously added by problem.addcbchecktime. The speciﬁed
callback function will no longer be called after it has been removed.
problem.removecbchecktime(callback, data)

Arguments
callbackdata

The callback function to remove. If None, then all checktime callback functions addedwith the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all checktime callbacks with the function pointer callback will be
removed.

Related topics
problem.addcbchecktime

Fair Isaac Corporation Conﬁdential and Proprietary Information

336

Reference Manual

problem.removecbchgbranchobject
Purpose

Synopsis

Removes a callback function previously added by addcbchgbranchobject. The speciﬁed callback
function will no longer be called after it has been removed.
problem.removecbchgbranchobject(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all branch object callback functions
added with the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, the object value will not bechecked and all branch object callbacks with the function callback will be removed.

Related topics
problem.addcbchgbranchobject.

Fair Isaac Corporation Conﬁdential and Proprietary Information

337

Reference Manual

problem.removecbcutlog
Purpose

Synopsis

Removes a cut log callback function previously added by addcbcutlog. The speciﬁed callback
function will no longer be called after it has been removed.
problem.removecbcutlog(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all cut log callback functions added withthe given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all cut log callbacks with the function callback will be removed.

Related topics
problem.addcbcutlog.

Fair Isaac Corporation Conﬁdential and Proprietary Information

338

Reference Manual

problem.removecbdestroymt
Purpose

Synopsis

Removes a slave thread destruction callback function previously added by addcbdestroymt. The
speciﬁed callback function will no longer be called after it has been removed.
problem.removecbdestroymt(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all thread destruction callback functions
added with the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all thread destruction callbacks with the function callback will be
removed.

Related topics
problem.addcbdestroymt.

Fair Isaac Corporation Conﬁdential and Proprietary Information

339

Reference Manual

problem.removecbgapnotify
Purpose

Synopsis

Removes a callback function previously added by problem.addcbgapnotify. The speciﬁed
callback function will no longer be removed after it has been returned.
problem.removecbgapnotify(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all gapnotify callback functions addedwith the given user-deﬁned value will be removed.
The user-deﬁned object that the callback was added with. If None then the object will
not be checked and all the gapnotify callbacks with the function callback will be
removed.

Related topics
problem.addcbgapnotify.

Fair Isaac Corporation Conﬁdential and Proprietary Information

340

Reference Manual

problem.removecbgloballog
Purpose

Synopsis

Removes a global log callback function previously added by addcbgloballog. The speciﬁed callback
function will no longer be called after it has been removed.
problem.removecbgloballog(callback, data)

Arguments
callback
data
ExampleThe callback function to remove. If None then all global log callback functions addedwith the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all global log callbacks with the function callback will be removed.

The following code sets and removes a callback function:
prob.controls.miplog = 3
prob.addcbgloballog(globalLog, None, 0)prob.mipoptimize("")
prob.removecbgloballog(globalLog, None)

Related topics
problem.addcbgloballog.

Fair Isaac Corporation Conﬁdential and Proprietary Information

341

Reference Manual

problem.removecbinfnode
Purpose

Synopsis

Removes a user infeasible node callback function previously added by addcbinfnode. The speciﬁed
callback function will no longer be called after it has been removed.
problem.removecbinfnode(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all user infeasible node callback
functions added with the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all user infeasible node callbacks with the function callback will be
removed.

Related topics
problem.addcbinfnode.

Fair Isaac Corporation Conﬁdential and Proprietary Information342

Reference Manual

problem.removecbintsol
Purpose

Synopsis

Removes an integer solution callback function previously added by addcbintsol. The speciﬁed
callback function will no longer be called after it has been removed.
problem.removecbintsol(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all integer solution callback functions
added with the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all integer solution callbacks with the function callback will be
removed.

Related topics
problem.addcbintsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

343

Reference Manual

problem.removecblplog
Purpose

Synopsis

Removes a simplex log callback function previously added by addcblplog. The speciﬁed callback
function will no longer be called after it has been removed.
problem.removecblplog(callback, data)

Arguments
callback
data
ExampleThe callback function to remove. If None then all lplog callback functions added withthe given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all lplog callbacks with the function callback will be removed.

The following code sets and removes a callback function:
prob.controls.lplog = 10
prob.addcblplog(lpLog, None, 0)prob.readprob("problem", "")prob.lpoptimize("")
prob.removecblplog(lpLog, None)

Related topics
problem.addcblplog.

Fair Isaac Corporation Conﬁdential and Proprietary Information

344

Reference Manual

problem.removecbmessage
Purpose

Synopsis

Removes a message callback function previously added by addcbmessage. The speciﬁed callback
function will no longer be called after it has been removed.
problem.removecbmessage(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all message callback functions addedwith the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all message callbacks with the function callback will be removed.

Related topics
problem.addcbmessage.

Fair Isaac Corporation Conﬁdential and Proprietary Information

345

Reference Manual

problem.removecbmipthread
Purpose

Synopsis

Removes a callback function previously added by addcbmipthread. The speciﬁed callback function
will no longer be called after it has been removed.
problem.removecbmipthread(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all variable branching callback functions
added with the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all variable branching callbacks with the function callback will be
removed.

Related topics
problem.addcbmipthread.

Fair Isaac Corporation Conﬁdential and Proprietary Information

346

Reference Manual

problem.removecbnewnode
Purpose

Synopsis

Removes a new-node callback function previously added by addcbnewnode. The speciﬁed callback
function will no longer be called after it has been removed.
problem.removecbnewnode(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all separation callback functions addedwith the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all separation callbacks with the function callback will be removed.

Related topics
problem.addcbnewnode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

347

Reference Manual

problem.removecbnodecutoff
Purpose

Synopsis

Removes a node-cutoff callback function previously added by addcbnodecutoff. The speciﬁed
callback function will no longer be called after it has been removed.
problem.removecbnodecutoff(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all node-cutoff callback functions addedwith the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all node-cutoff callbacks with the function callback will be removed.

Related topics
problem.addcbnodecutoff.

Fair Isaac Corporation Conﬁdential and Proprietary Information

348

Reference Manual

problem.removecboptnode
Purpose

Synopsis

Removes a node-optimal callback function previously added by addcboptnode. The speciﬁed
callback function will no longer be called after it has been removed.
problem.removecboptnode(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all node-optimal callback functions
added with the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all node-optimal callbacks with the function callback will be removed.

Related topics
problem.addcboptnode.

Fair Isaac Corporation Conﬁdential and Proprietary Information349

Reference Manual

problem.removecbpreintsol
Purpose

Synopsis

Removes a pre-integer solution callback function previously added by addcbpreintsol. The
speciﬁed callback function will no longer be called after it has been removed.
problem.removecbpreintsol(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all user infeasible node callback
functions added with the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all user infeasible node callbacks with the function callback will be
removed.

Related topics
problem.addcbpreintsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

350

Reference Manual

problem.removecbprenode
Purpose

Synopsis

Removes a preprocess node callback function previously added by addcbprenode. The speciﬁed
callback function will no longer be called after it has been removed.
problem.removecbprenode(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all preprocess node callback functions
added with the given user-deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all preprocess node callbacks with the function callback will be
removed.

Related topics
problem.addcbprenode.

Fair Isaac Corporation Conﬁdential and Proprietary Information

351

Reference Manual

problem.removecbusersolnotify
Purpose

Synopsis

Removes a user solution notiﬁcation callback previously added by problem.addcbusersolnotify.
The speciﬁed callback function will no longer be called after it has been removed.
problem.removecbusersolnotify(callback, data)

Arguments
callbackdata

The callback function to remove. If None then all user solution notiﬁcation callback
functions added with the given user deﬁned object value will be removed.
The object value that the callback was added with. If None, then the object value will not
be checked and all integer solution callbacks with the function callback will be
removed.

Related topics
problem.addcbusersolnotify.

Fair Isaac Corporation Conﬁdential and Proprietary Information352

Reference Manual

problem.repairinfeas
Purpose

Provides a simpliﬁed interface for problem.repairweightedinfeas. The returned value is asfollows:
 0: relaxed optimum found; 1: relaxed problem is infeasible; 2: relaxed problem is unbounded; 3: solution of the relaxed problem regarding the original objective is nonoptimal;
 4: error (when return code is nonzero); 5: numerical instability; 6: analysis of an infeasible relaxation was performed, but the relaxation is feasible.

Synopsisstatus_code = problem.repairinfeas(pflags, oflags, gflags, lrp, grp, lbp,
ubp, delta)

Arguments
pflagsoflagsgflags
lrp
grp
lbp
ubp
delta

The type of penalties created from the preferences:ceach penalty is the reciprocal of the preference (default);s
the penalties are placed in the scaled problem.
Controls the second phase of optimization:ouse the objective sense of the original problem (default);xmaximize the relaxed problem using the original objective;fskip optimization regarding the original objective;nminimize the relaxed problem using the original objective;iif the relaxation is infeasible, generate an irreducible infeasible subset for the
analys of the problem;aif the relaxation is infeasible, generate all irreducible infeasible subsets for the
analys of the problem.
Speciﬁes if the global search should be done:g
do the global search (default);lsolve as a linear model ignoring the discreteness of variables.
Preference for relaxing the less or equal side of row.
Preference for relaxing the greater or equal side of a row.
Preferences for relaxing lower bounds.
Preferences for relaxing upper bounds.
The relaxation multiplier in the second phase -1. A positive value means a relative
relaxation by multiplying the ﬁrst phase objective with (delta-1), while a negativevalue means an absolute relaxation, by adding abs(delta) to the ﬁrst phase objective.

Fair Isaac Corporation Conﬁdential and Proprietary Information

353

Reference Manual

Further information
1. A row or bound is relaxed by introducing a new nonnegative variable that will contain the infeasibility of
the row or bound. Suppose for example that row aT x = b is relaxed from below. Then a new variable(infeasibility breaker) s>=0 is added to the row, which becomes aT x +s = b. Observe that aT x may now
take smaller values than b. To minimize such violations, the weighted sum of these new variables isminimized.
2. A preference of 0 results in the row or bound not being relaxed.
3. A negative preference indicates that a quadratic penalty cost should be applied. This can speciﬁed on a
per constraint side or bound basis.
4. Note that the set of preferences are scaling independent.
5. If a feasible solution is identiﬁed for the relaxed problem, with a sum of violations p, then the sum ofviolations is restricted to be no greater than (1+delta)p, and the problem is optimized with respect tothe original objective function. A nonzero delta increases the freedom of the original problem.
6. Note that on some problems, slight modiﬁcations of delta may affect the value of the original objective
drastically.
7. Note that because of their special associated modeling properties, binary and semi-continuous
variables are not relaxed.
8. The default algorithm for the ﬁrst phase is the simplex algorithm, since the primal problem can be
efﬁciently warm started in case of the extended problem. These may be altered by setting the value ofcontrol DEFAULTALG.
9. If pflags is set such that each penalty is the reciprocal of the preference, the following rules areapplied while introducing the auxiliary variables:

Preference

Affects

Relaxation

Cost if pref.>0

Cost if pref.<0

lrp= rowsaT x - aux_var = b

1/lrp⁎aux_var

1/lrp⁎aux_var2

lrp<= rowsaT x - aux_var <= b

1/lrp⁎aux_var

1/lrp⁎aux_var2

grp= rowsaT x + aux_var = b

1/grp⁎aux_var

1/grp⁎aux_var2

grp>= rowsaT x + aux_var >= b

1/grp⁎aux_var

1/grp⁎aux_var2

ubp

upper bounds

xi - aux_var <= u1/ubp⁎aux_var

1/ubp⁎aux_var2

lbp

lower bounds

xi + aux_var >= l

1/lbp⁎aux_var

1/lbp⁎aux_var2

10. If an irreducible infeasible set (IIS) has been identiﬁed, the generated IIS(s) are accesible through the
IIS retrieval functions, see NUMIIS and problem.getiisdata.
Related topics
problem.repairweightedinfeas.

Fair Isaac Corporation Conﬁdential and Proprietary Information

354

Reference Manual

problem.repairweightedinfeas
PurposeBy relaxing a set of selected constraints and bounds of an infeasible problem, it attempts to identify a’solution’ that violates the selected set of constraints and bounds minimally, while satisfying all otherconstraints and bounds. Among such solution candidates, it selects one that is optimal regarding tothe original objective function. Similar to repairinfeas, the returned value is as follows: 1: relaxed problem is infeasible; 2: relaxed problem is unbounded; 3: solution of the relaxed problem regarding the original objective is nonoptimal;
 4: error (when return code is nonzero); 5: numerical instability; 6: analysis of an infeasible relaxation was performed, but the relaxation is feasible.

Synopsisstatus_code = problem.repairweightedinfeas(lrp_array, grp_array, lbp_array,ubp_array, phase2, delta, optflags)

Arguments
lrp_array
grp_arraylbp_arrayubp_array
phase2delta
optflags

Array of size ROWS containing the preferences for relaxing the less or equal side of row.
Array of size ROWS containing the preferences for relaxing the greater or equal side of arow.
Array of size COLS containing the preferences for relaxing lower bounds.
Array of size COLS containing preferences for relaxing upper bounds.
Controls the second phase of optimization:ouse the objective sense of the original problem (default);xmaximize the relaxed problem using the original objective;fskip optimization regarding the original objective;nminimize the relaxed problem using the original objective;iif the relaxation is infeasible, generate an irreducible infeasible subset for the
analys of the problem;aif the relaxation is infeasible, generate all irreducible infeasible subsets for the
analys of the problem.
The relaxation multiplier in the second phase -1.
Speciﬁes ﬂags to be passed to the Optimizer.

Fair Isaac Corporation Conﬁdential and Proprietary Information

355

Reference Manual

Further information
1. A row or bound is relaxed by introducing a new nonnegative variable that will contain the infeasibility of
the row or bound. Suppose for example that row aT x = b is relaxed from below. Then a new variable(’infeasibility breaker’) s>=0 is added to the row, which becomes aT x +s = b. Observe that aT x may now
take smaller values than b. To minimize such violations, the weighted sum of these new variables isminimized.
2. A preference of 0 results in the row or bound not being relaxed. The higher the preference, the more
willing the modeller is to relax a given row or bound.
3. The weight of each infeasibility breaker in the objective minimizing the violations is 1/p, where p is thepreference associated with the infeasibility breaker. Thus the higher the preference is, the lower apenalty is associated with the infeasibility breaker while minimizing the violations.
4. If a feasible solution is identiﬁed for the relaxed problem, with a sum of violations p, then the sum ofviolations is restricted to be no greater than (1+delta)p, and the problem is optimized with respect tothe original objective function. A nonzero delta increases the freedom of the original problem.
5. Note that on some problems, slight modiﬁcations of delta may affect the value of the original objective
drastically.
6. Note that because of their special associated modeling properties, binary and semi-continuous
variables are not relaxed.
7. If pflags is set such that each penalty is the reciprocal of the preference, the following rules areapplied while introducing the auxiliary variables:

Pref. array

Affects

Relaxation

Cost if pref.>0

Cost if pref.<0

lrp_array= rowsaT x - aux_var = b

1/lrp⁎aux_var

1/lrp⁎aux_var2

lrp_array<= rowsaT x - aux_var <= b

1/lrp⁎aux_var

1/lrp⁎aux_var2

grp_array= rowsaT x + aux_var = b

1/grp⁎aux_var

1/grp⁎aux_var2

grp_array>= rowsaT x + aux_var >= b

1/grp⁎aux_var

1/grp⁎aux_var2

ubp_array

upper bounds

xi - aux_var <= u1/ubp⁎aux_var

1/ubp⁎aux_var2

lbp_array

lower bounds

xi + aux_var >= l

1/lbp⁎aux_var

1/lbp⁎aux_var2

8. If an irreducible infeasible set (IIS) has been identiﬁed, the generated IIS(s) are accesible through the IIS
retrieval functions, see NUMIIS and problem.getiisdata.
Related topics
problem.repairinfeas, problem.repairweightedinfeasbounds.

Fair Isaac Corporation Conﬁdential and Proprietary Information

356

Reference Manual

problem.repairweightedinfeasbounds
Purpose

SynopsisAn extended version of problem.repairweightedinfeas that allows for bounding the level ofrelaxation allowed. The returned value is the same as repairweightedinfeas.
status = problem.repairweightedinfeasbounds(lrp_array, grp_array,lbp_array, ubp_array, lrb_array, grb_array, lbb_array, ubb_array,
phase2, delta, optflags)

Arguments
lrp_array
grp_arraylbp_arrayubp_arraylrb_arraygrb_arraylbb_arrayubb_array
phase2delta
optflags

Array of size ROWS containing the preferences for relaxing the less or equal side of row.
Array of size ROWS containing the preferences for relaxing the greater or equal side of arow.
Array of size COLS containing the preferences for relaxing lower bounds.
Array of size COLS containing preferences for relaxing upper bounds.
Array of size ROWS containing the upper bounds on the amount the less or equal side ofa row can be relaxed.
Array of size ROWS containing the upper bounds on the amount the greater or equal sideof a row can be relaxed.
Array of size COLS containing the upper bounds on the amount the lower bounds can berelaxed.
Array of size COLS containing the upper bounds on the amount the upper bounds can berelaxed.
Controls the second phase of optimization:ouse the objective sense of the original problem (default);xmaximize the relaxed problem using the original objective;fskip optimization regarding the original objective;nminimize the relaxed problem using the original objective;iif the relaxation is infeasible, generate an irreducible infeasible subset for the
analys of the problem;aif the relaxation is infeasible, generate all irreducible infeasible subsets for the
analys of the problem.
The relaxation multiplier in the second phase -1.
Speciﬁes ﬂags to be passed to the Optimizer.

Fair Isaac Corporation Conﬁdential and Proprietary Information

357

Reference Manual

Further information
1. A row or bound is relaxed by introducing a new nonnegative variable that will contain the infeasibility of
the row or bound. Suppose for example that row aT x = b is relaxed from below. Then a new variable(’infeasibility breaker’) s>=0 is added to the row, which becomes aT x +s = b. Observe that aT x may now
take smaller values than b. To minimize such violations, the weighted sum of these new variables isminimized.
2. A preference of 0 results in the row or bound not being relaxed. The higher the preference, the more
willing the modeller is to relax a given row or bound.
3. A negative preference indicates that a quadratic penalty cost should be applied. This can speciﬁed on a
per constraint side or bound basis.
4. If a feasible solution is identiﬁed for the relaxed problem, with a sum of violations p, then the sum ofviolations is restricted to be no greater than (1+delta)p, and the problem is optimized with respect tothe original objective function. A nonzero delta increases the freedom of the original problem.
5. Note that on some problems, slight modiﬁcations of delta may affect the value of the original objective
drastically.
6. Note that because of their special associated modeling properties, binary and semi-continuous
variables are not relaxed.
7. Given any row j with preferences lrp=lrp_array[j] and grp=grp_array[j], or variable i withbound preferences ubp=ubp_array[i] and lbp=lbp_array[i], the following rules are applied
while introducing the auxiliary variables:

Preference

Affects

Relaxation

Cost if pref.>0

Cost if pref.<0

lrp= rowsaT x - aux_var = b

1/lrp⁎aux_var

1/lrp⁎aux_var2

lrp<= rowsaT x - aux_var <= b

1/lrp⁎aux_var

1/lrp⁎aux_var2

grp= rowsaT x + aux_var = b

1/grp⁎aux_var

1/grp⁎aux_var2

grp>= rowsaT x + aux_var >= b

1/grp⁎aux_var

1/grp⁎aux_var2

ubp

upper bounds

xi - aux_var <= u1/ubp⁎aux_var

1/ubp⁎aux_var2

lbp

lower bounds

xi + aux_var >= l

1/lbp⁎aux_var

1/lbp⁎aux_var2

8. Only positive bounds are applied; a zero or negative bound is ignored and the amount of relaxation
allowed for the corresponding row or bound is not limited. The effect of a zero bound on a row orbound would be equivalent with not relaxing it, and can be achieved by setting its preference array value
to zero instead, or not including it in the preference arrays.
9. If an irreducible infeasible set (IIS) has been identiﬁed, the generated IIS(s) are accesible through the IIS
retrieval functions, see NUMIIS and problem.getiisdata.
Related topics
problem.repairinfeas.

Fair Isaac Corporation Conﬁdential and Proprietary Information

358

Reference Manual

problem.reset
Purpose

Synopsis

Clears all information regarding an optimization problem and returns it to the same status as it would
be after creation (i.e. after the instruction p = xpress.problem()).
problem.reset()

Examplep = xpress.problem()p.read("problem0", "l")p.solve()x0 = p.getSolution()p.reset()p.read("problem1", "")p.solve()x1 = p.getSolution()
Related topics
problem.read.

Fair Isaac Corporation Conﬁdential and Proprietary Information359

Reference Manual

problem.restore
Purpose

Synopsis

Restores the Optimizer’s data structures from a ﬁle created by problem.save. Optimization may thenrecommence from the point at which the ﬁle was created.
problem.restore(probname, flags)

Arguments
probnameflags

A string of up to 200 characters containing the problem name.
fForce the restoring of a save ﬁle even if its from a different version.

Examplep.restore("", "")Further information
1. This routine restores the data structures from the ﬁle probname.svf that was created by a previous
execution of save. The ﬁle probname.sol is also required and, if recommencing optimization in a
global search, the ﬁles problem_name.glb and problem_name.ctp are required too. Note that .svf
ﬁles are particular to the release of the Optimizer used to create them. They can only be read using thesame release Optimizer as used to create them.
2. The use of the ’f’ ﬂag is not recommended and can cause unexpected results.
Related topics
problem.save.

Fair Isaac Corporation Conﬁdential and Proprietary Information

360Reference Manual

problem.rhssa
Purpose

Synopsis

Returns upper and lower sensitivity ranges for speciﬁed right hand side (RHS) function coefﬁcients. If
the RHS coefﬁcients are varied within these ranges the current basis remains optimal and the reduced
costs remain valid.
problem.rhssa(mindex, lower, upper)

Arguments
mindexlower
upper
ExampleArray containing the rows (i.e. xpress.constraint objects, indices, or names) whose
RHS coefﬁcients sensitivity ranges are required.
Array where the RHS lower range values are to be returned.
Array where the RHS upper range values are to be returned.

Here we obtain the RHS function ranges for the three columns: 2, 6 and 8:
l = []
u = []
p.rhssa([2,8,6], l, u)
After which lower and upper contain:l = [5, 3.8, 5.7]
u = [7, 5.2, 1e+20]
Meaning that the current basis remains optimal when 5.0 ≤ rhs2 , 3.8 ≤ rhs8 ≤ 5.2 and 5.7 ≤ rhs6 , rhsi
being the RHS coefﬁcient of row i.

Further information
rhssa can only be called when an optimal solution to the current LP has been found. It cannot be used
when the problem is MIP presolved.
Related topics
problem.objsa.

Fair Isaac Corporation Conﬁdential and Proprietary Information

361

Reference Manual

problem.save
Purpose

Synopsis

Saves the current data structures, i.e. matrices, control settings and problem attribute settings to ﬁleand terminates the run so that optimization can be resumed later.
problem.save(filename=None)

Examplep.save()Further information
The data structures are written to the ﬁle problem_name.svf. Optimization may recommence from thesame point when the data structures are restored by a call to problem.restore. Under suchcircumstances, the ﬁle problem_name.sol and, if a branch and bound search is in progress, the global
ﬁles problem_name.glb and problem_name.ctp are also required. These ﬁles will be present after
execution of save, but will be modiﬁed by subsequent optimization, so no optimization calls may bemade after the call to save. Note that the .svf ﬁles created are particular to the release of the
Optimizer used to create them. They can only be read using the same release Optimizer as used tocreate them.
Related topics
problem.restore.

Fair Isaac Corporation Conﬁdential and Proprietary Information362

Reference Manual

problem.scale
Purpose
Synopsis

Re-scales the current problem.
problem.scale(mrscal, mcscal)

Arguments
mrscalArray of size ROWS containing the exponents of the powers of 2 with which to scale therows, or None if not required.
Array of size COLS containing the exponents of the powers of 2 with which to scale thecolumns, or None if not required.

mcscalExamplep.read("prob1", "")p.scale([1] ⁎ p.attributes.rows, [3] ⁎ p.attributes.cols)
p.lpoptimize("")
This reads the MPS ﬁle prob1.mat, rescales the problem and seeks the minimum objective value.
Further information
1. If mrscal and mcscal are both non-None then they will be used to scale the problem. Otherwise theproblem will be scaled according to the control SCALING. This routine may be useful when the current
problem has been modiﬁed by calls to routines such as problem.chgmcoef and problem.addrows.
2. scale cannot be called if the current problem is presolved.
Related topics
problem.read.

Fair Isaac Corporation Conﬁdential and Proprietary Information

363

Reference Manual

problem.scaling
Purpose
Synopsis
ExampleAnalyze the current matrix for largest/smallest coefﬁcients and ratios
problem.scaling()
The following example analyzes the matrix
p.scaling()

Further information
The current matrix (including augmentation if it has been carried out) is scanned for the absolute andrelative sizes of elements. The following information is reported: Largest and smallest elements in the matrix;
 Counts of the ranges of row ratios in powers of 10 (e.g. number of rows with ratio between 10 and100);

 List of the rows (with largest and smallest elements) which appear in the highest range; Counts of the ranges of column ratios in powers of 10;
 List of the columns (with largest and smallest elements) which appear in the highest range;
 Element ranges in powers of 10.

Where any of the reported items (largest or smallest element in the matrix or any reported row orcolumn element) is in a penalty error vector, the results are repeated, excluding all penalty error vectors.

Fair Isaac Corporation Conﬁdential and Proprietary Information

364

Reference Manual

problem.setbranchbounds
Purpose

Synopsis

Speciﬁes the bounds previously stored using problem.storebounds that are to be applied in orderto branch on a user global entity.
problem.setbranchbounds(mindex)

Argument
mindexObject previously deﬁned in a call to problem.storebounds that references thestored bounds to be used to separate the node.

Related topics
problem.loadcuts, problem.storebounds, Section "Working with the cut manager" of the Xpress
Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

365Reference Manual

problem.setbranchcuts
Purpose
Synopsis

Speciﬁes the cuts in the cut pool that are to be applied in order to branch on a user global entity..
problem.setbranchcuts(mindex)

Argument
mindexArray containing cuts in the cut pool that are to be applied. Typically obtained fromproblem.storecuts.

Related topics
problem.getcpcutlist, problem.storecuts, Section "Working with the cut manager" of theXpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

366

Reference Manual

problem.setcbcascadeend
Purpose

Synopsis

Set a user callback to be called at the end of the cascading process, after the last variable has beencascadedproblem.setcbcascadeend(callback, data)
value = callback(prob, myobject)Arguments
callback

prob
myobjectdata
ExampleThe function to be called at the end of the cascading process. callback returns an
integer value. The return value is noted by Xpress SLP but it has no effect on the
optimization.
The problem passed to the callback function.
The user-deﬁned object passed as data to setcbcascadeend.
User-deﬁned object, which can be used for any purpose by the function. data is passed
to callback as my_object.

The following example sets up a callback to be executed at the end of the cascading process whichchecks if any of the values have been changed signiﬁcantly:
csol = [1,2,3,4]
p.setcbcascadeend(CBCascEnd, csol)
A suitable callback function might resemble this:def CBCascEnd(prob, obj):
for iCol in range(prob.controls.cols):(a,b,c,s,d,e,f,value,g,h,i,j,k,l,m,n) = prob.getvar(iCol)
if abs(value - obj[iCol]) > .01:
print("Col {0} changed from {1} to {2}".format(iCol, obj[iCol], value)
return 0
The obj argument is used here to hold the original solution values.

Further information
This callback can be used at the end of the cascading, when all the solution values have beenrecalculated.
Related topics
problem.cascade, problem.setcbcascadestart, problem.setcbcascadevar,problem.setcbcascadevarfail

Fair Isaac Corporation Conﬁdential and Proprietary Information

367

Reference Manual

problem.setcbcascadestartPurpose

Synopsis

Set a user callback to be called at the start of the cascading process, before any variables have beencascadedproblem.setcbcascadestart(callback, data)
retval = callback(my_prob, my_object)Arguments
callback

my_prob
my_object
data

The function to be called at the start of the cascading process. callback returns an
integer value. If the return value is nonzero, the cascading process will be omitted forthe current SLP iteration, but the optimization will continue.
The problem passed to the callback function.
The user-deﬁned object passed as data to setcbcascadestart.
Address of a user-deﬁned object, which can be used for any purpose by the function.
data is passed to callback as my_object.

Further information
This callback can be used at the start of the cascading, before any of the solution values have beenrecalculated.
Related topics
problem.cascade, problem.setcbcascadeend, problem.setcbcascadevar,problem.setcbcascadevarfail

Fair Isaac Corporation Conﬁdential and Proprietary Information

368

Reference Manual

problem.setcbcascadevar
Purpose
Synopsis

Set a user callback to be called after each column has been cascaded
problem.setcbcascadevar(callback, data)
retval = callback(my_prob, my_object, colindex)

Arguments
callback

my_prob
my_objectcolindexdata
ExampleThe function to be called after each column has been cascaded. callback returns an
integer value. If the return value is nonzero, the cascading process will be omitted for theremaining variables during the current SLP iteration, but the optimization will continue.
The problem passed to the callback function.
The user-deﬁned object passed as data to problem.setcbcascadevar.
The number of the column which has been cascaded.
User-deﬁned object, which can be used for any purpose by the function. data is passed
to callback as my_object.

The following example sets up a callback to be executed after each variable has been cascaded:obj = []
p.setcbcascadevar(CBCascVar, obj)
The following sample callback function resets the value of the variable if the cascaded value is of the
opposite sign to the original value:
def CBCascVar(myprob, obj, iCol):(a,b,c,d,e,f,value,g,h,i,j,k,l,m,n) = myprob.getvar(iCol)
if value ⁎ obj[iCol] < 0:p.chgvar(myprob, ColNum, None, None, None, None,
None, None, obj[iCol], None, None, None,
None)
return 0
The data argument is used here to hold the address of the array cSol which we assume has been
populated with the original solution values.

Further information
This callback can be used after each variable has been cascaded and its new value has been
calculated.
Related topics
problem.cascade, problem.setcbcascadeend, problem.setcbcascadestart,
problem.setcbcascadevarfail

Fair Isaac Corporation Conﬁdential and Proprietary Information369

Reference Manual

problem.setcbcascadevarfail
Purpose
Synopsis

Set a user callback to be called after cascading a column was not successful
problem.setcbcascadevarfail(callback, data)
retval = callback(my_prob, my_object, colindex)

Arguments
callback

my_prob
my_objectcolindexdata

The function to be called after cascading a column was not successful. callback
returns an integer value. If the return value is nonzero, the cascading process will beomitted for the remaining variables during the current SLP iteration, but the optimization
will continue.
The problem passed to the callback function.
The user-deﬁned object passed as data to setcbcascadevarfail.
The number of the column which has been cascaded.
Address of a user-deﬁned object, which can be used for any purpose by the function.
data is passed to callback as my_object.

Further information
This callback can be used to provide user deﬁned updates for SLP variables having a determining row
that were not successfully cascaded due to the determining row being close to singular around thecurrent values. This callback will always be called in place of the cascadevar callback in such cases,
and in no situation will both the cascadevar and the cascadevarfail callback be called in the same
iteration for the same variable.
Related topics
problem.cascade, problem.setcbcascadeend, problem.setcbcascadestart,
problem.setcbcascadevar

Fair Isaac Corporation Conﬁdential and Proprietary Information

370

Reference Manual

problem.setcbcoefevalerror
Purpose
Synopsis

Set a user callback to be called when an evaluation of a coefﬁcient fails during the solve
problem.setcbcoefevalerror(callback, data)
retval = callback(my_prob, my_object, rowindex, colindex)

Arguments
callback
my_prob
my_objectrowindex
colindexdata

The function to be called when an evaluation fails.
The problem passed to the callback function.
The user-deﬁned object passed as data to setcbcoefevalerror.
The row position of the coefﬁcient.
The column position of the coefﬁcient.
Address of a user-deﬁned object, which can be used for any purpose by the function.
data is passed to callback as my_object.

Further information
This callback can be used to capture when an evaluation of a coefﬁcient fails. The callback is called
only once for each coefﬁcient.
Related topics
problem.printevalinfo

Fair Isaac Corporation Conﬁdential and Proprietary Information

371

Reference Manual

problem.setcbconstruct
Purpose
Synopsis

Set a user callback to be called during the Xpress SLP augmentation processproblem.setcbconstruct(callback, data)
retval = callback(my_prob, my_object)Arguments
callback
my_prob
my_object
data
ExampleThe function to be called during problem augmentation. callback returns an integer
value. See below for an explanation of the values.
The problem passed to the callback function.
The user-deﬁned object passed as data to setcbconstruct.
Address of a user-deﬁned object, which can be used for any purpose by the function.
data is passed to callback as my_object.

The following example sets up a callback to be executed during the Xpress SLP problem augmentation:
value = []p.setcbconstruct(CBConstruct, value)
The following sample callback function sets values for the variables the ﬁrst time the function is called
and returns to problem.construct to recalculate the initial matrix. The second time it is called it
frees the allocated memory and returns to problem.construct to proceed with the rest of theaugmentation.
def CBConstruct(myprob, obj):
if obj is None:n = myprob.attributes.cols
cValue = n ⁎ [0]# initialize with values (not shown here)
for i in range(n):# store into SLP structures
myprob.chgvar(i, None, None, None, None,
None, None, cValue[i], None, None, None,
None)# set Object non-null to indicate we have processed data
obj = cValue
return -1
else:
obj = None
return 0

Further information
This callback can be used during the problem augmentation, generally (although not exclusively) tochange the initial values for the variables.
The following return codes are accepted:0

Normal return: augmentation continues-1

Return to recalculate matrix values-2

Return to recalculate row weights and matrix entries

other

Error return: augmentation terminates, problem.construct terminates with anonzero error code.

Fair Isaac Corporation Conﬁdential and Proprietary Information

372

Reference Manual

The return values -1 and -2 will cause the callback to be called a second time after the matrix has beenrecalculated. It is the responsibility of the callback to ensure that it does ultimately exit with a return
value of zero.
Related topics
problem.construct

Fair Isaac Corporation Conﬁdential and Proprietary Information

373

Reference Manual

problem.setcbdestroy
Purpose
Synopsis

Set a user callback to be called when an SLP problem is about to be destroyed
problem.setcbdestroy(callback, data)
callback(prob, my_object)Arguments
callback
my_prob
my_object
objectExampleThe function to be called when the SLP problem is about to be destroyed. callback
returns an integer value. At present the return value is ignored.
The problem passed to the callback function.
The user-deﬁned object passed as object to setcbdestroy.
Address of a user-deﬁned object, which can be used for any purpose by the function.
object is passed to callback as my_object.

The following example sets up a callback to be executed before the SLP problem is destroyed:p.setcbdestroy(CBDestroy, cSol)
The following sample callback function frees the memory associated with the user-deﬁned object:
def CBDestroy(myprob, Obj):
if Obj is not None:
Obj.inuse = 0
return 0
The object argument is used here to hold the address of the array cSol which we assume was
assigned using one of the malloc functions.

Further information
This callback can be used when the problem is about to be destroyed to free any user-deﬁned
resources which were allocated during the life of the problem.

Fair Isaac Corporation Conﬁdential and Proprietary Information

374

Reference Manual

problem.setcbdrcol
Purpose
Synopsis

Set a user callback used to override the update of variables with small determining column
problem.setcbdrcol(callback, object)
newvalue = callback(my_prob, my_object, colindex, drcolindex, drcolvalue,vlb, vub)Arguments
callback

The function to be called after each column has been cascaded. callback returns an
integer value. If the return value is positive, it will indicate that the value has been ﬁxed,
and cascading should be omitted for the variable. A negative value indicates that apreviously ﬁxed value has been relaxed. If no action is taken, a 0 return value should be
used.
my_prob
The problem passed to the callback function.
my_object The user-deﬁned object passed as object to setcbcascadevar.
ColIndex
The column (i.e. xpress.var object, index, or name) for which the determiningcolumns is checked.
DrColIndex The index of the determining column for the column that is being updated.
DrColValue The value of the determining column in the current SLP iteration.
NewValue
Used to return the new value for column ColIndex, should it need to be updated, inwhich case the callback must return a positive value to indicate that this value should be
used.
VLB
The original lower bound of column ColIndex. The callback provides this value as areference, should the bound be updated or changed during the solution process.
VUB
The original upper bound of column ColIndex. The callback provides this value as areference, should the bound be updated or changed during the solution process.
objectAddress of a user-deﬁned object, which can be used for any purpose. by the function.
object is passed to callback as my_object.

Further information
If set, this callback is called as part of the cascading procedure. Please see the chapter on cascadingof the SLP Reference Manual for more information.
Related topics
xslp_DRCOLTOL, problem.cascade, problem.setcbcascadeend,problem.setcbcascadestart

Fair Isaac Corporation Conﬁdential and Proprietary Information

375

Reference Manual

problem.setcbintsol
Purpose
Synopsis

Set a user callback to be called during MISLP when an integer solution is obtained
problem.setcbintsol(callback, data)
callback(prob, data)

Arguments
callback
prob
data
ExampleThe function to be called when an integer solution is obtained.
The problem passed to the callback function.
The user-deﬁned object passed as Object to setcbintsol.

The following example sets up a callback to be executed whenever an integer solution is found during
MISLP:
cSol = []p.setcbintsol(CBIntSol, cSol)
The following sample callback function saves the solution values for the integer solution just found:def CBIntSol(prob, cSol):prob.getmipsol(x=cSol, None, None, None)}

Related topics
problem.setcboptnode, problem.setcbprenode

Fair Isaac Corporation Conﬁdential and Proprietary Information

376

Reference Manual

problem.setcbiterend
Purpose
Synopsis

Set a user callback to be called at the end of each SLP iteration
problem.setcbiterend(callback, object)retval = callback(my_prob, my_object)Arguments
callback
my_prob
my_object
objectExampleThe function to be called at the end of each SLP iteration. callback returns an integer
value. If the return value is nonzero, the SLP iterations will stop.
The problem passed to the callback function.
The user-deﬁned object passed as object to setcbiterend.
Address of a user-deﬁned object, which can be used for any purpose by the function.
object is passed to callback as my_object.

The following example sets up a callback to be executed at the end of each SLP iteration. It records thenumber of LP iterations in the latest optimization and stops if there were fewer than 10:
p.setcbiterend(CBIterEnd, None)
A suitable callback function might resemble this:def CBIterEnd(MyProb, Obj):
niter = MyProb.attributes.simplexiter
return (niter < 10)
The object argument is not used here, and so is passed as None.

Further information
This callback can be used at the end of each SLP iteration to carry out any further processing and/or
stop any further SLP iterations.
Related topics
problem.setcbiterstart, problem.setcbitervar

Fair Isaac Corporation Conﬁdential and Proprietary Information

377

Reference Manual

problem.setcbiterstartPurpose
Synopsis

Set a user callback to be called at the start of each SLP iteration
problem.setcbiterstart(callback, object)retval = callback(my_prob, my_object)Arguments
callback
my_prob
my_object
objectExampleThe function to be called at the start of each SLP iteration. callback returns an integer
value. If the return value is nonzero, the SLP iterations will stop.
The problem passed to the callback function.
The user-deﬁned object passed as object to setcbiterstart.
Address of a user-deﬁned object, which can be used for any purpose by the function.
object is passed to callback as my_object.

The following example sets up a callback to be executed at the start of the optimization to save to savethe values of the variables from the previous iteration:
p.setcbiterstart(CBIterStart, cSol)
A suitable callback function might resemble this:def CBIterStart(MyProb, Obj):
niter = MyProb.attributes.xslp_iter
if nIter == 0:
return 0 # no previous solution
Obj = []
MyProb.getsol(Obj, None, None, None)
return 0
The object argument is used here to hold the address of the array cSol which we populate with thesolution values.

Further information
This callback can be used at the start of each SLP iteration before the optimization begins.
Related topics
problem.setcbiterend, problem.setcbitervar

Fair Isaac Corporation Conﬁdential and Proprietary Information

378

Reference Manual

problem.setcbitervar
Purpose
Synopsis

Set a user callback to be called after each column has been tested for convergenceproblem.setcbitervar(callback, object)retval = callback(my_prob, my_object, colindex)

Arguments
callback

my_prob
my_object
ColIndex
objectExampleThe function to be called after each column has been tested for convergence.
callback returns an integer value. The return value is interpreted as a convergencestatus. The possible values are:< 0
The variable has not converged;0
The convergence status of the variable is unchanged;
1 to 10 The column has converged on a system-deﬁned convergence criterion(these values should not normally be returned);> 10
The variable has converged on user criteria.
The problem passed to the callback function.
The user-deﬁned object passed as object to setcbitervar.
The number of the column which has been tested for convergence.
A user-deﬁned object, which can be used for any purpose by the function. object ispassed to callback as my_object.

The following example sets up a callback to be executed after each variable has been tested forconvergence. The user object Important is an integer array which has already been set up and holds
a ﬂag for each variable indicating whether it is important that it converges.
Obj = Nonep.setcbitervar(CBIterVar, Obj)The following sample callback function tests if the variable is already converged. If not, then it checks if
the variable is important. If it is not important, the function returns a convergence status of 99.
def CBIterVar(MyProb, Obj, iCol):(a,b,c,d,e,f,g,h,i,converged,j,k,l,m,n) = MyProb.getvar(iCol)
if converged:
return 0
if Obj[iCol]:
return 99
return -1
The object argument is used here to hold the address of the array Important.

Further information
This callback can be used after each variable has been checked for convergence, and allows theconvergence status to be reset if required.
Related topics
problem.setcbiterend, problem.setcbiterstart

Fair Isaac Corporation Conﬁdential and Proprietary Information

379

Reference Manual

problem.setcbmessage
Purpose
Synopsis

Set a user callback to be called whenever Xpress Nonlinear outputs a line of text
problem.setcbmessage(callback, object)callback(my_prob, my_object, msg, msgtype)

Arguments
callback
my_prob
my_objectmsg
msgtypeobjectExampleThe function to be called whenever Xpress Nonlinear outputs a line of text. callback
does not return a value.
The problem passed to the callback function.
The user-deﬁned object passed as object to setcbmessage.
String to be output.
Type of message. The following are system-deﬁned:
1
Information message
3
Warning message
4
Error message
A negative value indicates that the Optimizer is about to ﬁnish and any buffers should
be ﬂushed at this time. User-deﬁned values are also possible for msgtype.
Address of a user-deﬁned object, which can be used for any purpose by the function.
object is passed to callback as my_object.

The following example creates a log ﬁle into which all messages are placed. System messages arealso printed on standard output:
log = ''
p.setcbmessage(CBMessage, log)
A suitable callback function could resemble the following:
def CBMessage(Obj, msg, msgtype):
if msgtype < 0:
print(log)log = ''
returnif msgtype >= 1 and msgtype <= 4:print(msg)else:
log += msg + ';'Further information
If a user message callback is deﬁned, screen output is automatically disabled.
Output can be directed into a log ﬁle by using problem.setlogfile.
Also, because of Python’s garbage collection functions, it is advised to explicitly delete a problem at theend of its use (with the del command) if a message callback was set for that problem using
setcbmessage. def CBMessage(Obj, msg, msgtype): pass
p = xp.problem() p.setcbmessage(CBMessage, None) [...] del p
Related topics
problem.setlogfile

Fair Isaac Corporation Conﬁdential and Proprietary Information

380

Reference Manual

problem.setcbmsjobend
Purpose

Synopsis

Set a user callback to be called every time a new multistart job ﬁnishes. Can be used to overwrite thedefault solution ranking function
problem.setcbmsjobend(callback, object)status = callback(my_prob, my_object, job_object, description)

Arguments
callback
The function to be called when a new multistart job is createdmy_prob
The problem passed to the callback function.
my_object The user-deﬁned object passed as object to setcbmsjobend.
job_object Job speciﬁc user-deﬁned object, as speciﬁed in by the multistart job creating API
functions.
description The description of the problem as speciﬁed in by the multistart job creating API
functions.
statusUser return status variable:
0 - use the default evaluation of the ﬁnished job
1 - disregard the result and continue
2 - stop the multistart search
Further information
The multistart pool is dynamic, and this callback can be used to load new multistart jobs using thenormal API functions.
Related topics
problem.setcbmsjobstart, problem.setcbmswinner

Fair Isaac Corporation Conﬁdential and Proprietary Information

381

Reference Manual

problem.setcbmsjobstartPurpose

Synopsis

Set a user callback to be called every time a new multistart job is created, and the pre-loaded settings
are applied
problem.setcbmsjobstart(callback, object)status = callback(my_prob, my_object, job_object, description)

Arguments
callback
The function to be called when a new multistart job is created;
my_prob
The problem passed to the callback function.
my_object The user-deﬁned object passed as object to setcbmsjobstart.
job_object Job speciﬁc user-deﬁned object, as speciﬁed in by the multistart job creating API
functions.
description The description of the problem as speciﬁed in by the multistart job creating API
functions.
statusUser return status variable:
0 - normal return, solve the job,
1 - disregard this job and continue,
2 - Stop multistart.
Further information
All mulit-start jobs operation on an independent copy of the original problem, and any modiﬁcation to
the problem is allowed, including structural changes. Please note however, that any modiﬁcation will be
carried over to the base problem, should a modiﬁed problem be declared the winner prob.
Related topics
problem.setcbmsjobend, problem.setcbmswinner

Fair Isaac Corporation Conﬁdential and Proprietary Information382

Reference Manual

problem.setcbmswinnerPurpose

Synopsis

Set a user callback to be called every time a new multistart job is created, and the pre-loaded settings
are applied
problem.setcbmswinner(callback, object)callback(my_prob, my_object, job_object, description)

Arguments
callback
The function to be called when a new multistart job is createdmy_prob
The problem passed to the callback function.
my_object The user-deﬁned object passed as object to setcbmswinner.
job_object Job speciﬁc user-deﬁned object, as speciﬁed in by the multistart job creating API
functions.
description The description of the problem as speciﬁed in by the multistart job creating API
functions.
Further information
The multistart pool is dynamic, and this callback can be used to load new multistart jobs using thenormal API functions.
Related topics
problem.setcbmsjobstart, problem.setcbmsjobend

Fair Isaac Corporation Conﬁdential and Proprietary Information

383

Reference Manual

problem.setcboptnode
Purpose
Synopsis

Set a user callback to be called during MISLP when an optimal SLP solution is obtained at a node
problem.setcboptnode(callback, object)feas = callback(prob, object)Arguments
callback

prob
objectfeas
ExampleThe function to be called when an optimal SLP solution is obtained at a node. It must
returns an integer value. If the return value is nonzero, or if the feasibility ﬂag is set
nonzero, then further processing of the node will be terminated (it is declaredinfeasible).
The problem passed to the callback function.
The user-deﬁned object passed to setcboptnode.
Integer containing the feasibility ﬂag. If nonzero, the node is declared infeasible.

The following example deﬁnes a callback function to be run at each node when an SLP optimal solution
is found. If there are signiﬁcant penalty errors in the solution, the node is declared infeasible.
p.setcboptnode(CBOptNode, None)
A suitable callback function might resemble the following:
def CBOptNode(prob, data) {total = prob.attributes.xslp_errorcosts
objval = prob.attributes.xslp_objval
if abs(total) > abs(objval) ⁎ 0.001 and abs(total) > 1:
return 1
else:
return 0

Further information
If a node is declared infeasible from the callback function, the cost of exploring the node further will be
avoided.
This callback must be used in place of setcboptnode when optimizing with MISLP.
Related topics
problem.setcbprenode, problem.setcbslpnode

Fair Isaac Corporation Conﬁdential and Proprietary Information

384

Reference Manual

problem.setcbprenode
Purpose

Synopsis

Set a user callback to be called during MISLP after the set-up of the SLP problem to be solved at anode, but before SLP optimization
problem.setcbprenode(callback, data)feas = callback(prob, data)

Arguments
prob
callback

prob
data
feas
ExampleThe current SLP problem.
The function to be called after the set-up of the SLP problem to be solved at a node.
callback returns an integer value. If the return value is nonzero, then further
processing of the node will be terminated (it is declared infeasible).
The problem passed to the callback function.
The user-deﬁned object passed as Object to setcbprenode.
feasibility ﬂag. If callback return a nonzero, the node is declared infeasible.

The following example sets up a callback function to be executed at each node before the SLP
optimization starts. The array IntList contains a list of integer variables, and the function prints thebounds on these variables.
IntList = [...]
prob.setcbprenode(CBPreNode, IntList)
A suitable callback function might resemble the following:
def CBPreNode(myProb, intlist):
for i in intlist:
LO,UP = [],[]
myProb.getlb(LO,i,i);
myProb.getub(UP,i,i);lb,ub = LO[0], UP[0]if lb > 0 or ub < xp.infinity:
print("Col {0}: {1} <= {2}".format(i,lb,ub)
return 0

Further information
If a node can be identiﬁed as infeasible by the callback function, then the initial optimization at thecurrent node is avoided, as well as further exploration of the node.
Related topics
problem.setcboptnode, problem.setcbslpnode

Fair Isaac Corporation Conﬁdential and Proprietary Information

385

Reference Manual

problem.setcbslpend
Purpose
Synopsis

Set a user callback to be called at the end of the SLP optimization
problem.setcbslpend(callback, object)callback(my_prob, my_object)Arguments
callback

my_prob
my_object
objectExampleThe function to be called at the end of the SLP optimization. callback returns an
integer value. If the return value is nonzero, the optimization will return an error codeand the "User Return Code" error will be set.
The problem passed to the callback function.
The user-deﬁned object passed as object to setcbslpend.
Address of a user-deﬁned object, which can be used for any purpose by the function.
object is passed to callback as my_object.

The following example sets up a callback to be executed at the end of the SLP optimization. It frees thememory allocated to the object created when the optimization began:
ObjData = Nonep.setcbslpend(CBSlpEnd, ObjData)
A suitable callback function might resemble this:def CBSlpEnd(MyProb, Obj):
if Obj is not None:
Obj = []
return 0

Further information
This callback can be used at the end of the SLP optimization to carry out any further processing orhousekeeping before the optimization function returns.
Related topics
problem.setcbslpstart

Fair Isaac Corporation Conﬁdential and Proprietary Information

386

Reference Manual

problem.setcbslpnode
Purpose
Synopsis

Set a user callback to be called during MISLP after the SLP optimization at each node.
problem.setcbslpnode(callback, object)(retval, feas) = callback(my_prob, my_object)Arguments
callback

my_prob
my_objectfeas
objectExampleThe function to be called after the set-up of the SLP problem to be solved at a node.
callback returns an integer value. If the return value is nonzero, or if the feasibility ﬂag
is set nonzero, then further processing of the node will be terminated (it is declaredinfeasible).
The problem passed to the callback function.
The user-deﬁned object passed as object to setcbslpnode.
Address of an integer containing the feasibility ﬂag. If callback sets the ﬂag nonzero,
the node is declared infeasible.
Address of a user-deﬁned object, which can be used for any purpose by the function.
object is passed to callback as my_object.

The following example sets up a callback function to be executed at each node after the SLP
optimization ﬁnishes. If the solution value is worse than a target value (referenced through the user
object), the node is cut off (it is declared infeasible).
objtarget = []p.setcbslpnode(CBSLPNode, objtarget)
A suitable callback function might resemble the following:
def CBSLPNode(my_prob, my_obj):
lpval = my_prob.attributes.lpobjval
return (0, (lpval < my_obj))

Further information
If a node can be cut off by the callback function, then further exploration of the node is avoided.

Fair Isaac Corporation Conﬁdential and Proprietary Information

387

Reference Manual

problem.setcbslpstartPurpose
Synopsis

Set a user callback to be called at the start of the SLP optimization
problem.setcbslpstart(callback, object)retval = callback(my_prob, my_object)Arguments
callback
my_prob
my_object
objectExampleThe function to be called at the start of the SLP optimization. callback returns an
integer value. If the return value is nonzero, the optimization will not be carried out.
The problem passed to the callback function.
The user-deﬁned object passed as object to setcbslpstart.
User-deﬁned object, which can be used for any purpose by the function. object ispassed to callback as my_object.

The following example sets up a callback to be executed at the start of the SLP optimization:
Objdata = []p.setcbslpstart(CBSlpStart, Objdata)
A suitable callback function might resemble this:def CBSlpStart(object):
object.append(1)return 0

Further information
This callback can be used at the start of the SLP optimization to carry out any housekeeping before theoptimization actually starts. Note that a nonzero return code from the callback will terminate theoptimization immediately.
Related topics
problem.setcbslpend

Fair Isaac Corporation Conﬁdential and Proprietary Information

388

Reference Manual

problem.setControl
Purpose
Synopsis

Sets one or more controls of a problem.
problem.setControl(string, value)

Examplep = xpress.problem()p.setControl('miprelstop', 1e-4)
p.setControl({'feastol': 1e-4, 'presolve': 0})
Further information
1. As mentioned in the previous chapter, there is an alternative way to set and retrieve controls. It works
by querying the data structure controls of each problem or, if one wants to set a control to be used by
all problems deﬁned subsequently, the global control object xpress.controls.
2. This function can be used in two ways depending on whether one wants to set one or more controls. In
the ﬁrst case, the arguments form a pair (string, value) where the ﬁrst element is the lower-case nameof a control (see the Xpress Optimizer reference manual for a complete list of controls). In the second
case, the argument is a Python dictionary whose keys are control name string and whose values are thevalue of the control.
Related topics
problem.getControl.

Fair Isaac Corporation Conﬁdential and Proprietary Information389

Reference Manual

problem.setcurrentiv
Purpose
Synopsis

Transfer the current solution to initial values
problem.setcurrentiv()

Further information
Provides a way to set the current iterates solution as initial values, make changes to parameters or to
the underlying nonlinear problem and then rerun the SLP optimization process.
Related topics
problem.reinitialize, problem.unconstruct

Fair Isaac Corporation Conﬁdential and Proprietary Information390

Reference Manual

problem.setdefaultcontrol
Purpose

Synopsis

Sets one control to its default values. Must be called before the problem is read or loaded byproblem.read and problem.loadproblem.
problem.setdefaultcontrol(control)

Argument
control
ExampleName of the control to be set to default.

The following turns off presolve to solve a problem, before resetting the control defaults, reading it andsolving it again:p.controls.presolve = 0
p.mipoptimize("")
p.writeprtsol()p.setdefaultcontrol('presolve')p.read()p.mipoptimize("")

Related topics
xpress.setdefaultcontrol, xpress.setdefaults, problem.setdefaultcontrol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

391

Reference Manual

problem.setdefaults
Purpose

Synopsis
ExampleSets all controls to their default values. It must be called before the problem is read withproblem.read or loaded with problem.loadproblem.
problem.setdefaults()
The following turns off presolve to solve a problem, before resetting the control defaults, reading it andsolving it again:p.controls.presolve = 0
p.mipoptimize("")
p.writeprtsol()p.setdefaults()
p.read()p.mipoptimize("")

Related topics
xpress.setdefaultcontrol, xpress.setdefaults, problem.setdefaults.

Fair Isaac Corporation Conﬁdential and Proprietary Information

392

Reference Manual

problem.setindicators
Purpose

Synopsis

Speciﬁes that a set of rows in the problem will be treated as indicator constraints during a global
search. An indicator constraint is made of a condition and a linear inequality. The
condition is of the type "bin = value", where bin is a binary variable and value is either 0 or 1.
The linear inequality is any linear row in the problem with type <= (L) or >= (G). During global
search, a row conﬁgured as an indicator constraint is enforced only when condition holds, that is only if
the indicator variable bin has the speciﬁed value.
problem.setindicators(mrows, inds, comps)

Arguments
mrows
inds
comps

ExampleArray containing the rows (i.e. xpress.constraint objects, indices, or names) thatdeﬁne the linear inequality part for the indicator constraints.
Array containing the columns (i.e. xpress.var objects, indices, or names) of theindicator variables.
Array with the complement ﬂags:
0
not an indicator constraint (in this case the corresponding entry in the indsarray is ignored);1
for indicator constraints with condition "bin = 1";-1
for indicator constraints with condition "bin = 0";This sets the ﬁrst two matrix rows as indicator rows in the global problem prob; the ﬁrst row controlled
by condition x4=1 and the second row controlled by condition x5=0 (assuming x4 and x5 correspondto columns indices 4 and 5).
p.setindicators([0,1],[4,5],[1,-1])
p.mipoptimize("")

Further information
Indicator rows must be set up before solving the problem. Any indicator row will be removed from the
problem after presolve and added to a special pool. An indicator row will be added back into the active
matrix only when its associated condition holds. An indicator variable can be used in multiple indicatorrows and can also appear in normal rows and in the objective function.
Related topics
problem.getindicators.

Fair Isaac Corporation Conﬁdential and Proprietary Information

393

Reference Manual

problem.setlogﬁlePurpose
Synopsis

This directs all Optimizer output to a log ﬁle.
problem.setlogfile(filename)Argument
filename

ExampleThe name of the ﬁle to which all output will be directed. If set to None, redirection of theoutput will stop and all screen output will be turned back on (except for DLL users where
screen output is always turned off).

The following directs output to the ﬁle logfile.log:
p = xpress.problem()p.setlogfile("logfile.log")

Further information
1. It is recommended that a log ﬁle be set up for each problem being worked on, since it provides a meansfor obtaining any errors or warnings output by the Optimizer during the solution process.
2. If output is redirected with setlogfile all screen output will be turned off.
3. Alternatively, an output callback can be deﬁned using problem.addcbmessage, which will be called
every time a line of text is output. Deﬁning a user output callback will turn all screen output off. To
discard all output messages the OUTPUTLOG integer control can be set to 0.
Related topics
problem.addcbmessage.

Fair Isaac Corporation Conﬁdential and Proprietary Information

394

Reference Manual

problem.setmessagestatus
Purpose
Synopsis

Manages suppression of messages.
problem.setmessagestatus(errcode, status)

Arguments
errcodestatusExampleThe id number of the message. Refer to the Section 9 of the Xpress Optimizer reference
manual for a list of possible message numbers.
Non-zero if the message is not suppressed; 0 otherwise.

Attempting to optimize a problem that has no matrix loaded gives error 91. The following code uses
setmessagestatus to suppress the error message:p = xpress.problem()p.setmessagestatus(91, 0)
p.lpoptimize("")

Further information
If a message is suppressed globally then the message can only be enabled for any problem once theglobal suppression is removed with a call to setmessagestatus with prob passed as None.
Related topics
problem.getmessagestatus.

Fair Isaac Corporation Conﬁdential and Proprietary Information

395

Reference Manual

problem.setObjective
Purpose
Synopsis

Sets the objective function of the problem.
problem.setObjective(expr, sense=xpress.minimize)

Arguments
expr

sense
ExampleA linear or quadratic function of the variables that were added to the problem prior tothis call. An error will be returned if any variable in the linear or quadratic part of theobjective was not added to the problem via addVariable.
Either xpress.minimize or xpress.maximize.

The following example sets the objective function of the problem to [2x12 + 3x1 x2 + 5x22 + 4x1 + 4]:
x1 = xpress.var()x2 = xpress.var()p = xpress.problem()p.addVariable(x1, x2)
p.setObjective(2⁎x1⁎⁎2 + 3⁎x1⁎x2 + 5⁎x2⁎⁎2 + 4⁎x1 + 4)

Further information
Multiple calls to setObjective are allowed, and each replaces the old objective function with a newone.
Related topics
problem.addVariable.

Fair Isaac Corporation Conﬁdential and Proprietary Information

396

Reference Manual

problem.setprobname
Purpose
Synopsis

Sets the current default problem name.
problem.setprobname(probname)Argument
probname

A string of up to MAXPROBNAMELENGTH characters containing the problem name.

Related topics
problem.read, problem.name, MAXPROBNAMELENGTH.

Fair Isaac Corporation Conﬁdential and Proprietary Information

397

Reference Manual

problem.solve
Purpose
Synopsis

Solves the current problem.
problem.solve(flags)

Argument
flags(optional) a string with ﬂags expressed as characters.

Fair Isaac Corporation Conﬁdential and Proprietary Information

398

Reference Manual

problem.storebounds
Purpose
SynopsisStores bounds for node separation using user separate callback function.
mindex = problem.storebounds(mcols, type, bds)

Arguments
mcols
type
bds
mindexArray containing the columns (i.e. xpress.var objects, indices, or names).
Array containing the bounds types:
U
indicates an upper bound;L
indicates a lower bound.
Array containing the bound values.
Object that the user will use to reference the stored bounds for the Optimizer inproblem.setbranchbounds.

Related topics
problem.setbranchbounds.

Fair Isaac Corporation Conﬁdential and Proprietary Information

399

Reference Manual

problem.storecuts
Purpose

SynopsisStores cuts into the cut pool, but does not apply them to the current node. These cuts must be explicitly
loaded into the matrix using problem.loadcuts or problem.setbranchcuts before they become
active.
problem.storecuts(nodupl, mtype, rtype, rhs, mstart, mindex, mcols,
dmatval)Arguments
nodupl
mtype
rtype

rhs
mstartmindex
mcols
dmatval0
do not exclude duplicates from the cut pool;
1
duplicates are to be excluded from the cut pool;2
duplicates are to be excluded from the cut pool, ignoring cut type.
Array containing the cut types. The cut types can be any integer and are used to identify
the cuts.
Character array containing the row types:
Lindicates a ≤ row;E
indicates an = row;G
indicates a ≥ row.
Array containing the right hand side elements for the cuts.
Array containing offsets into the mcols and dmtval arrays indicating the start of eachcut. This array is of length ncuts+1 where ncuts is the length of drhs, with the lastelement mstart[ncuts] being where cut ncuts+1 would start.
Array where the cuts will be returned.
Array containing the columns in the cuts.
Array containing the matrix values for the cuts.

Further information
1. storecuts can be used to eliminate duplicate cuts. If the nodupl parameter is set to 1, the cut pool
will be checked for duplicate cuts with a cut type identical to the cuts being added. If a duplicate cut isfound the new cut will only be added if its right hand side value makes the cut stronger. If the cut in thepool is weaker than the added cut it will be removed unless it has been applied to an active node of thetree. If nodupl is set to 2 the same test is carried out on all cuts, ignoring the cut type.
2. storecuts returns a list of the cuts added to the cut pool in the mindex array. If the cut is not added
to the cut pool because a stronger cut exits a None will be returned. The mindex array can be passed
directly to problem.loadcuts or problem.setbranchcuts to load the most recently stored cuts
into the matrix.
3. The columns and elements of the cuts must be stored contiguously in the mcols and dmtval arrays
passed to storecuts. The starting point of each cut must be stored in the mstart array. To
determine the length of the ﬁnal cut the mstart array must be of length ncuts+1 with the last elementof this array containing where the cut ncuts+1 would start.
Related topics
problem.loadcuts, problem.setbranchcuts, Section "Working with the cut manager" of theXpress Optimizer reference manual.

Fair Isaac Corporation Conﬁdential and Proprietary Information

400Reference Manual

problem.strongbranch
Purpose

Synopsis

Performs strong branching iterations on all speciﬁed bound changes. For each candidate boundchange, strongbranch performs dual simplex iterations starting from the current optimal solution of
the base LP, and returns both the status and objective value reached after these iterations.
problem.strongbranch(mbndind, cbndtype, dbndval, itrlimit, dsbobjval,
msbstatus)

Arguments
mbndindcbndtype

dbndvalitrlimit
dsobjval
msbstatus
ExampleArray containing the columns (i.e. xpress.var objects, indices, or names) on which
the bounds will change.
Character array indicating the type of bound to change:
U
indicates change the upper bound;L
indicates change the lower bound;B
indicates change both bounds, i.e. ﬁx the column.
Array giving the new bound values.
Maximum number of LP iterations to perform for each bound change.
Objective value of each LP after performing the strong branching iterations.
Status of each LP after performing the strong branching iterations, as detailed for the
LPSTATUS attribute.

Suppose that the current LP relaxation has two integer columns (columns 0 and 1 which are fractionals
at 0.3 and 1.5, respectively, and we want to perform strong branching in order to choose which tobranch on. This could be done in the following way:
dsbobjval = []msbstatus = []p.strongbranch([0,0,1,0], ['','','',''], [1,0,2,1],
1000, dsbobjval, msbstatus)

Further information
Prior to calling strongbranch, the current LP problem must have been solved to optimality and an
optimal basis must be available.

Fair Isaac Corporation Conﬁdential and Proprietary Information

401Reference Manual

problem.strongbranchcb
Purpose

Synopsis

Performs strong branching iterations on all speciﬁed bound changes. For each candidate boundchange, strongbranchcb performs dual simplex iterations starting from the current optimal solutionof the base LP, and returns both the status and objective value reached after these iterations.
problem.strongbranchcb(bndind, bndtype, bndval, itrlimit, objval, status,
sbsolvecb, vContext)
ret = sbsolvecb(prob, vContext, ibnd)

Arguments
bndindbndtypebndvalitrlimit
objvalstatussbsolvecb
vContext
ibnd

Array containing the columns (i.e. xpress.var objects, indices, or names) on which
the bounds will change.
Character array indicating the type of bound to change:
U
indicates change the upper bound;L
indicates change the lower bound;B
indicates change both bounds, i.e. ﬁx the column.
Array giving the new bound values.
Maximum number of LP iterations to perform for each bound change.
Objective value of each LP after performing the strong branching iterations.
Status of each LP after performing the strong branching iterations, as detailed for the
LPSTATUS attribute.
Function to be called after each strong branch has been reoptimized.
User context to be provided for sbsolvecb.
The index of bound for which sbsolvecb is called.

Further information
Prior to calling strongbranchcb, the current LP problem must have been solved to optimality and an
optimal basis must be available.
strongbranchcb is an extension to problem.strongbranch. If identical input arguments areprovided both will return identical results, the difference being that for the case of
PRSstrongbranchcb the sbnodecb function is called at the end of each LP reoptimization. For eachbranch optimized, the LP can be interrogated: the LP status of the branch is available through checking
LPSTATUS, and the objective function value is available through LPOBJVAL. It is possible to access thefull current LP solution by using problem.getlpsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information402

Reference Manual

problem.tune
Purpose

Synopsis

Begin a tuner session for the current problem. The tuner will solve the problem multiple times while
evaluating a list of control settings and promising combinations of them. When ﬁnished, the tuner will
select and set the best control setting on the problem. Note that the direction of optimization is given
by xpress.attributes.objsense.
problem.tune(flags)

Argumentflags

Flags to specify whether to tune the current problem as an LP or a MIP problem, andthe algorithm for solving the LP problem or the initial LP relaxation of the MIP. The
ﬂags are optional. If the argument includes:lwill tune the problem as an LP (mutually exclusive with ﬂag g);gwill tune the problem as a MIP (mutually exclusive with ﬂag l);dwill use the dual simplex method;pwill use the primal simplex method;bwill use the barrier method;nwill use the network simplex method.

Examplep.tune('dp')This tunes the current problem. The problem type is automatically determined. If it is an LP problem, it
will be solved with a concurrent run of the dual and primal simplex method. If it is a MIP problem, theinitial LP relaxation of the MIP will be solved with a concurrent run of primal and dual simplex.
Further information
Please refer to the Xpress Optimizer reference manual for a detailed guide of how to use the tuner.

Fair Isaac Corporation Conﬁdential and Proprietary Information

403

Reference Manual

problem.tunerreadmethod
Purpose
Synopsis

Load a user deﬁned tuner method from the given ﬁle.
problem.tunerreadmethod(methodfile)Argument
methodfile

The method ﬁle name, from which the tuner can load a user-deﬁned tuner method.

Examplep.tunerreadmethod('method.xtm')
This loads the tuner method from the method.xtm ﬁle.
Further information
Please refer to the Xpress Optimizer reference manual for more information about the tuner method
and for the format of the tuner method ﬁle.

Fair Isaac Corporation Conﬁdential and Proprietary Information

404

Reference Manual

problem.tunerwritemethod
Purpose
SynopsisWrites the current tuner method to a given ﬁle or prints it to the console.
problem.tunerwritemethod(methodfile)Argument
methodfile

The ﬁle name to which the tuner will write the current tuner method. If the input isstdout or STDOUT, then the tuner will print the method to the console instead.

Example 1 (Library)
p.tunerwritemethod('method.xtm')
This writes the tuner method to the ﬁle method.xtm.
Example 2 (Library)
p.tunerwritemethod('stdout')
This prints the tuner method to the console.
Further information
Please refer to the Xpress Optimizer reference manual for more information about the tuner method
and for the format of the tuner method ﬁle.

Fair Isaac Corporation Conﬁdential and Proprietary Information

405

Reference Manual

problem.unconstruct
Purpose
Synopsis

Reset the SLP problem and removes the augmentation structures
problem.unconstruct()

Further information
Can be used to rerun the SLP optimization process with changed parameters or underlying lienar /nonlienar strcutures.
Related topics
problem.reinitialize, problem.setcurrentiv,

Fair Isaac Corporation Conﬁdential and Proprietary Information

406

Reference Manual

problem.updatelinearization
Purpose
Synopsis

Updates the current linearization
problem.updatelinearization()

Further information
Updates the augmented probem (the linearization) to match the current base point. The base point is
the current SLP solution. The values of the SLP variables can be changed using problem.chgvar.
The linearization must be present, and this function can only be called after the problem has been
augmented by problem.construct.
Related topics
problem.construct

Fair Isaac Corporation Conﬁdential and Proprietary Information

407

Reference Manual

problem.validate
Purpose
Synopsis
ExampleValidate the feasibility of constraints in a converged solution
problem.validate()
The following example sets the validation tolerance parameters, validates the converged solution andretrieves the validation indices.
p.controls.xslp_validationtol_a = 0.001
p.controls.xslp_validationtol_r = 0.001
p.validate()
indexA = p.attributes.xslp_validationindex_a
indexR = p.attributes.xslp_validationindex_r

Further information
validate checks the feasibility of a converged solution against relative and absolute tolerances foreach constraint. The left hand side and the right hand side of the constraint are calculated using theconverged solution values. If the calculated values imply that the constraint is infeasible, then the
difference (D) is tested against the absolute and relative validation tolerances.
If D < XSLP_VALIDATIONTOL_A
then the constraint is within the absolute validation tolerance. The total positive (TPos) and negative
contributions (TNeg) to the left hand side are also calculated.
If D < MAX(ABS(TPos), ABS(TNeg)) ∗ XSLP_VALIDATIONTOL_R
then the constraint is within the relative validation tolerance. For each constraint which is outside boththe absolute and relative validation tolerances, validation factors are calculated which are the factors
by which the infeasibility exceeds the corresponding validation tolerance; the smallest factor is printed
in the validation report.
The validation index xslp_validationindex_a is the largest absolute validation factor multipliedby the absolute validation tolerance; the validation index xslp_validationindex_r is the largest
relative validation factor multiplied by the relative validation tolerance.
Related topics
xslp_validationindex_A, xslp_validationindex_R, xslp_validationtol_A,
xslp_validationtol_R

Fair Isaac Corporation Conﬁdential and Proprietary Information

408

Reference Manual

problem.validatekkt
Purpose

Synopsis

Validates the ﬁrst order optimality conditions also known as the Karush-Kuhn-Tucker (KKT) conditions
versus the currect solution
problem.validatekkt(calculationmode, respectbasisstatus, updatemultipliers,
kktviolationtarget)

Arguments
calculationmode The calculation mode can be:0recalculate the reduced costs at the current solution using the current dual
solution.
1minimize the sum of KKT violations by adjusting the dual solution.
2
perform both.
respectbasisstatus The following ways are deﬁned to assess if a constraint is active:
0
evaluate the recalculated slack activity versus xslp_ECFTOL_R.
1
use the basis status of the slack in the linearized problem if available.
2
use both.
updatemultipliers The calculated values can be:0
only used to calculate the xslp_validationindex_k measure.
1
used to update the current dual solution and reduced costs.
kktviolationtarget When calculating the best KKT multipliers, it is possible to enforce an even
distribution of reduced costs violations by enforcing a bound on them.
Further information
The bounds enforced by kktviolationtarget are automatically relaxed if the desired accuracy
cannot be achieved.

Fair Isaac Corporation Conﬁdential and Proprietary Information409

Reference Manual

problem.validaterow
Purpose
Synopsis

Prints an extensive analysis on a given constraint of the SLP problem
problem.validate(row)Argumentrow

The row (i.e. xpress.constraint object, index, or name) to be analyzed.

Further information
The analysis will include the readable format of the original constraint and the augmented constraint.
For infeasible constraints, the absolute and relative infeasibility is calculated. Variables in theconstraints are listed including their value in the solution of the last linearization, the internal value (e.g.
cascaded), reduced cost, step bound and convergence status. Scaling analysis is also provided.

Fair Isaac Corporation Conﬁdential and Proprietary Information

410

Reference Manual

problem.validatevector
Purpose
Synopsis

Validate the feasibility of constraints for a given solution(suminf, sumscaledinf, obj) = problem.validate(vector)

Arguments
vector

A vector of length xpress.attributes.cols containing the solution vector to bechecked.
suminf
The sum of infeasibilities.
sumscaledinf The sum of scaled (relative) infeasibilities.
obj
The net objective.

Further information
validatevector works the same way as problem.validate, and will update
xslp_validationindex_a and xslp_validationindex_r.
Related topics
Xslp_Validationindex_a, xslp_validationindex_r, xslp_validationtol_a,
xslp_validationtol_r

Fair Isaac Corporation Conﬁdential and Proprietary Information

411

Reference Manual

problem.write
Purpose
SynopsisWrites the current problem to an MPS or LP ﬁle.
problem.write(filename, flags)

Arguments
filename

flags

ExampleA string of up to 200 characters to contain the ﬁle name to which the problem is to be
written. If omitted, the default problem_name is used with a .mps extension, unless thel ﬂag is used in which case the extension is .lp.
(optional) Flags, which can be one or more of the following:hsingle precision of numerical values;oone element per line;nscaled;s
scrambled vector names;loutput in LP format;x
output MPS ﬁle in hexadecimal format.
pobsolete ﬂag (now default behavior).

The following example outputs the current problem in full precision, LP format with scrambled vector
names to the ﬁle problem_name.lp.
p.write("", "lps")

Further information
1. If problem.loadproblem is used to obtain a problem then there is no association between theobjective function and the N rows in the problem and so a separate N row (called __OBJ___) is createdupon a write. Also, if after a call to read either the objective row or the N row in the problem
corresponding to the objective row are changed, the association between the two is lost and the__OBJ___ row is created with an write. To remove the objective row from the problem when doing aread, set keepnrows to -1 before read.
2. The hexadecimal format is useful for saving the exact internal precision of the problem.
3. Warning: If problem.read is used to input a problem, then the input ﬁle will be overwritten by write
if a new ﬁlename is not speciﬁed.
Related topics
problem.read.

Fair Isaac Corporation Conﬁdential and Proprietary Information

412

Reference Manual

problem.writebasis
Purpose
SynopsisWrites the current basis to a ﬁle for later input into the Optimizer.
problem.writebasis (filename, flags)

Arguments
filename
flags

ExampleA string of up to 200 characters containing the ﬁle name from which the basis is to be
written. If omitted, the default problem_name is used with a .bss extension.
(optional) Flags to pass to writebasis:i
output the internal presolved basis.
t
output a compact advanced form of the basis.
n
output basis ﬁle containing current solution values.
houtput values in single precision.
x
output values in hexadecimal format.
pobsolete ﬂag (now default behavior).

After an LP has been solved it may be desirable to save the basis for future input as an advanced
starting point for other similar problems. This may save signiﬁcant amounts of time if the LP iscomplex. The Optimizer input commands might then be:
p.read("myprob", "")p.lpoptimize("")
p.writebasis("", "")This reads in a problem ﬁle, maximizes the LP and saves the basis. Loading a basis for a MIP problem
can disable some MIP presolve operations which can result in a large increase in solution times so it isgenerally not recommended.

Further information
1. The t ﬂag is only useful for later input to a similar problem using the t ﬂag with problem.readbasis.
2. If the Newton barrier algorithm has been used for optimization then crossover must have been
performed before there is a valid basis. This basis can then only be used for restarting the simplex(primal or dual) algorithm.
3. writebasis will output the basis for the original problem even if the problem has been presolved.
Related topics
problem.getbasis, problem.readbasis.

Fair Isaac Corporation Conﬁdential and Proprietary Information

413

Reference Manual

problem.writebinsol
Purpose
SynopsisWrites the current MIP or LP solution to a binary solution ﬁle for later input into the Optimizer.
problem.writebinsol(filename, flags)

Arguments
filename
flags
ExampleA string of up to 200 characters containing the ﬁle name to which the solution is to be
written. If omitted, the default problem_name is used with a .sol extension.
(optional) Flags to pass to writebinsol:x
output the LP solution.

After an LP has been solved or a MIP solution has been found the solution can be saved to ﬁle. If a MIP
solution exists it will be written to ﬁle unless the x ﬂag is passed to writebinsol in which case the LP
solution will be written.
p.read("myprob", "")p.mipoptimize("")
p.writebinsol("", "")Related topics
problem.getlpsol, problem.getmipsol, problem.readbinsol, problem.writesol,
problem.writeprtsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

414

Reference Manual

problem.writedirs
Purpose
SynopsisWrites the global search directives from the current problem to a directives ﬁle.
problem.writedirs(filename)Argument
filename

A string of up to 200 characters containing the ﬁle name to which the directives should
be written. If omitted (or None), the default problem_name is used with a .dir
extension.

Further information
If the problem has been presolved, only the directives for columns in the presolved problem will be
written to ﬁle.
Related topics
problem.loaddirs.

Fair Isaac Corporation Conﬁdential and Proprietary Information

415

Reference Manual

problem.writeprtsol
Purpose
SynopsisWrites the current solution to a ﬁxed format ASCII ﬁle, problem_name.prt.
problem.writeprtsol(filename, flags)

Arguments
filename

flags
ExampleA string of up to 200 characters containing the ﬁle name to which the solution is to be
written. If omitted, the default problem_name will be used. The extension .prt will beappended.
(optional) Flags for writeprtsol are:x
write the LP solution instead of the current MIP solution.

This example shows the standard use of this function, outputting the solution to ﬁle immediately
following optimization:p.read("myprob", "")p.lpoptimize("")
p.writeprtsol("", "")Further information
1. The ﬁxed width ASCII format created by this command is not as readily useful as that produced byproblem.writesol. The main purpose of writeprtsol is to create a ﬁle that can be sent directly toa printer. The format of this ﬁxed format ASCII ﬁle is described in the Xpress Optimizer reference
manual.
2. To create a prt ﬁle for a previously saved solution, the solution must ﬁrst be loaded with the
problem.readbinsol function.
Related topics
problem.getlpsol, problem.getmipsol, problem.readbinsol, problem.writebinsol,
problem.writesol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

416

Reference Manual

problem.writeslxsol
Purpose

SynopsisCreates an ASCII solution ﬁle (.slx) using a similar format to MPS ﬁles. These ﬁles can be read backinto the Optimizer using the problem.readslxsol function.
problem.writeslxsol(filename, flags)

Arguments
filenameflags

A string of up to 200 characters containing the ﬁle name to which the solution is to be
written. If omitted, the default problem_name is used with a .slx extension.
(optional) Flags to pass to writeslxsol:lwrite the LP solution in case of a MIP problem;mwrite the MIP solution;p
use full precision for numerical values;x
use hexadecimal format to write values;dLP solution only: including dual variables;s
LP solution only: including slack variables;r
LP solution only: including reduced cost.

Examplep.writeslxsol("lpsolution", "")This saves the MIP solution if the problem contains global entities, or otherwise saves the LP(barrier incase of quadratic problems) solution of the problem.
Related topics
problem.readslxsol, problem.writeprtsol, problem.writebinsol,
problem.readbinsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

417

Reference Manual

problem.writesol
Purpose
SynopsisWrites the current solution to a CSV format ASCII ﬁle, problem_name.asc(and .hdr).
problem.writesol(filename, flags)

Arguments
filename

flags

ExampleA string of up to 200 characters containing the ﬁle name to which the solution is to be
written. If omitted, the default problem_name will be used. The extensions .hdr and.asc will be appended.
(optional) Flags to control which optional ﬁelds are output:ssequence number;
n
name;
t
type;
b
basis status;aactivity;ccost (columns), slack (rows);llower bound;uupper bound;ddj (column; reduced costs), dual value (rows; shadow prices);rright hand side (rows).
If no ﬂags are speciﬁed, all ﬁelds are output.
Additional ﬂags:
eoutputs every MIP or goal programming solution saved;p
outputs in full precision;q
only outputs vectors with nonzero optimum value;x
output the current LP solution instead of the MIP solution.

In this example the basis status is output (along with the sequence number) following optimization:p.read("prob1", "")p.lpoptimize("")
p.writesol("", "sb")

Further information
1. The command produces two readable ﬁles: filename.hdr (the solution header ﬁle) andfilename.asc (the CSV foramt solution ﬁle). The header ﬁle contains summary information, all in
one line. The ASCII ﬁle contains one line of information for each row and column in the problem. Any
ﬁelds appearing in the .asc ﬁle will be in the order the ﬂags are described above. The order that the
ﬂags are speciﬁed by the user is irrelevant.
2. Additionally, the mask control OUTPUTMASK may be used to control which names are reported to the
ASCII ﬁle. Only vectors whose names match OUTPUTMASK are output. OUTPUTMASK is set by default to"????????", so that all vectors are output.
Related topics
problem.getlpsol, problem.getmipsol, problem.writeprtsol.

Fair Isaac Corporation Conﬁdential and Proprietary Information

418

Reference Manual

branchobj.addbounds
Purpose
Synopsis

Adds new bounds to a branch of a user branching object.
branchobj.addbounds(ibranch, bndtype, bndcol, bndval)

Arguments
ibranchbndtypebndcolbndvalThe number of the branch to add the new bounds for. This branch must already havebeen created using branchobj.addbranches. Branches are indexed starting fromzero.
Character array indicating the type of bounds to add:
L
Lower bound.
U
Upper bound.
Array containing the columns for the new bounds.
Array giving the bound values.

Fair Isaac Corporation Conﬁdential and Proprietary Information

419

Reference Manual

branchobj.addbranches
Purpose
Synopsis

Adds new, empty branches to a user deﬁned branching object.
branchobj.addbranches(nbranches)

Argument
nbranches

Number of new branches to create.

Fair Isaac Corporation Conﬁdential and Proprietary Information

420

Reference Manual

branchobj.addcuts
Purpose
Synopsis

Adds stored user cuts as new constraints to a branch of a user branching object.
branchobj.addcuts(ibranch, cutind)Arguments
ibranchcutindThe number of the branch to add the cuts for. This branch must already have beencreated using branchobj.addbranches. Branches are indexed starting from zero.
Array containing the user cuts that should be added to the branch.

Related topics
branchobj.addrows.

Fair Isaac Corporation Conﬁdential and Proprietary Information

421

Reference Manual

branchobj.addrows
Purpose
Synopsis

Adds new constraints to a branch of a user branching object.
branchobj.addrows(ibranch, rtype, rhs, beg, mcol, val)

Arguments
ibranch

rtype

rhs
beg
mcol
dval
ExampleThe number of the branch to add the new constraints for. This branch must already havebeen created using branchobj.addbranches. Branches are indexed starting fromzero.
Character array indicating the type of constraints to add:
L
Less than type.
G
Greater than type.
E
Equality type.
Array containing the right-hand side values.
Array containing the offsets of the mcol and dval arrays of the start of the non zero
coefﬁcients in the new constraints.
Array containing the columns for the non zero coefﬁcients.
Array containing the non-zero coefﬁcient values.

The following function will create a branching object that branches on constraints x1 + x2 ≥ 1 or
x1 + x2 ≤ 0:
def CreateConstraintBranch(mip, icol):# Create the new object with two empty branches.
bo = xpress.branchobj(mip, isoriginal=True)bo.addbranches(2)# Add the constraint of the branching object:# x1 + x2 >= 1
# x1 + x2 <= 0bo.addrows(0, 1, 2, ['G'], [1.0], [0], [0,1], [1.0,1.0])
bo.addrows(1, 1, 2, ['L'], [0.0], [0], [0,1], [1.0,1.0])# Set a low priority value so our branch object is picked up# before the default branch candidates.
bo.setpriority(100)return bo

Fair Isaac Corporation Conﬁdential and Proprietary Information

422

Reference Manual

branchobj.getbounds
Purpose

Synopsis

Returns the bounds for a branch of a user branching object. The returned value is the actual number ofbounds returned in the output arrays.
branchobj.getbounds(ibranch, nbounds_size, bndtype, bndcol, bndval)

Arguments
ibranchThe number of the branch to get the bounds for.
nbounds_size Maximum number of bounds to return.
bndtype
Character array of length nbounds_size where the types of bounds twill be returned:
L
Lower bound.
U
Upper bound.
bndcolArray of length nbounds_size where the columns will be returned.
bndvalArray of length nbounds_size where the bound values will be returned.
Related topics
branchobj.addbounds.

Fair Isaac Corporation Conﬁdential and Proprietary Information

423

Reference Manual

branchobj.getbranches
Purpose
Synopsis

Returns the number of branches of a branching object.
branchobj.getbranches()

Related topics
branchobj.addbranches.

Fair Isaac Corporation Conﬁdential and Proprietary Information

424

Reference Manual

branchobj.getid
Purpose
Synopsis

Returns the unique identiﬁer assigned to a branching object.
branchobj.getid()

Further information
1. Branching objects associated with existing column entities (binaries, integers, semi–continuous andpartial integers), are given an identiﬁer from 1 to MIPENTS.
2. Branching objects associated with existing Special Ordered Sets are given an identiﬁer fromMIPENTS+1 to MIPENTS+SETS.
3. User created branching objects will always have a negative identiﬁer.

Fair Isaac Corporation Conﬁdential and Proprietary Information

425

Reference Manual

branchobj.getlasterror
Purpose
Synopsis

Returns the last error encountered during a call to the given branch object.
(id,msg) = branchobj.getlasterror()

Argumentsidmsg
ExampleError code.
A string with the last error message relating to the branching object will be returned.

The following shows how this function might be used in error checking:obranch = xpress.branchobj()
try:
obranch.setpreferredbranch(3)except:(i,m) = obranch.getlasterror()print("ERROR when setting preferred branch:", m)

Fair Isaac Corporation Conﬁdential and Proprietary Information

426

Reference Manual

branchobj.getrows
Purpose
Synopsis

Returns the constraints for a branch of a user branching object.
branchobj.getrows(ibranch, nrows_size, nelems_size, rtype, rrhs, rbeg,
mcol, dval)

Arguments
ibranchThe number of the branch to get the constraints from.
nrows_size Maximum number of rows to return.
nelems_size Maximum number of non zero coefﬁcients to return.
rtype
Character array of length nrows_size where the types of the rows will be returned:
L
Less than type.
G
Greater than type.
E
Equality type.
rhs
Array of length nrows_size where the right hand side values will be returned.
mbeg
Array of length nrows_size which will be ﬁlled with the offsets of the mcol and dvalarrays of the start of the non zero coefﬁcients in the returned constraints.
mcol
Array of length nelems_size which will be ﬁlled with the column indices for the nonzero coefﬁcients.
dval
Array of length nelems_size which will be ﬁlled with the non zero coefﬁcient values.
Related topics
branchobj.addrows.

Fair Isaac Corporation Conﬁdential and Proprietary Information

427

Reference Manual

branchobj.setpreferredbranch
Purpose
Synopsis

Speciﬁes which of the child nodes corresponding to the branches of the object should be explored ﬁrst.
branchobj.setpreferredbranch(ibranch)

Argument
ibranchThe number of the branch to mark as preferred.

Fair Isaac Corporation Conﬁdential and Proprietary Information

428

Reference Manual

branchobj.setpriority
Purpose
Synopsis

Sets the priority value of a user branching object.
branchobj.setpriority(ipriority)

Argument
ipriority

The new priority value to assign to the branching object, which must be a number from 0
to 1000. User branching objects are created with a default priority value of 500.

Further information
1. A candidate branching object with lowest priority number will always be selected for branching before
an object with a higher number.
2. Priority values must be an integer from 0 to 1000. User branching objects and global entities are by
default assigned a priority value of 500. Special branching objects, such as those arising fromstructural branches or split disjunctions are assigned a priority value of 400.

Fair Isaac Corporation Conﬁdential and Proprietary Information429

Reference Manual

branchobj.store
Purpose

Synopsis

Adds a new user branching object to the Optimizer’s list of candidates for branching. This function isavailable only through the callback function set by problem.addcboptnode.
status = branchobj.store()

Argument
status

The returned status from checking the provided branching object:0
The object was accepted successfully.
1
Failed to presolve the object due to dual reductions in presolve.
2
Failed to presolve the object due to duplicate column reductions in presolve.
3
The object contains an empty branch.
The object was not added to the candidate list if a non zero status is returned.

Further information
1. To ensure that a user branching object expressed in terms of the original matrix columns can beapplied to the presolved problem, it might be necessary to turn off certain presolve operations.
2. If any of the original matrix columns referred to in the object are unbounded, dual reductions might
prevent the corresponding bound or constraint from being presolved. To avoid this, dual reductions
should be turned off in presolve, by clearing bit 3 of the integer control PRESOLVEOPS.
3. If one or more of the original matrix columns of the object are duplicates in the original matrix, but notin the branching object, it might not be possible to presolve the object due to duplicate column
eliminations in presolve. To avoid this, duplicate column eliminations should be turned off in presolve,
by clearing bit 5 of PRESOLVEOPS.
4. As an alternative to turning off the above mentioned presolve features, it is possible to protect individualcolumns of a the problem from being modiﬁed by presolve. Use the problem.loadsecurevecs
function to mark any columns that might be branched on using branching objects.
Related topics
branchobj.validate.

Fair Isaac Corporation Conﬁdential and Proprietary Information

430

Reference Manual

branchobj.validate
Purpose

Synopsis

Veriﬁes that a given branching object is valid for branching on the current branch-and-bound node of a
MIP solve. The function will check that all branches are non-empty, and if required, verify that thebranching object can be presolved.
status = branchobj.validate()

Argument
status

The returned status from checking the provided branching object:0
The object is acceptable.
1
Failed to presolve the object due to dual reductions in presolve.
2
Failed to presolve the object due to duplicate column reductions in presolve.
3
The object contains an empty branch.

Fair Isaac Corporation Conﬁdential and Proprietary Information

431

APPENDIX A

Contacting FICO
FICO provides clients with support and services for all our products. Refer to the following sections formore information.

Product support
FICO offers technical support and services ranging from self-help tools to direct assistance with a FICO
technical support engineer. Support is available to all clients who have purchased a FICO product andhave an active support or maintenance contract. You can ﬁnd support contact information and a link to
the Customer Self Service Portal (online support) on the Product Support home page(www.ﬁco.com/en/product-support).
The FICO Customer Self Service Portal is a secure web portal that is available 24 hours a day, 7 days aweek from the Product Support home page. The portal allows you to open, review, update, and close
cases, as well as ﬁnd solutions to common problems in the FICO Knowledge Base.
Please include ’Xpress’ in the subject line of your support queries.

Product education
FICO Product Education is the principal provider of product training for our clients and partners.
Product Education offers instructor-led classroom courses, web-based training, seminars, and training
tools for both new user enablement and ongoing performance support. For additional information, visit
the Product Education homepage at www.ﬁco.com/en/product-training or email
producteducation@ﬁco.com.

Product documentation
FICO continually looks for new ways to improve and enhance the value of the products and services weprovide. If you have comments or suggestions regarding how we can improve this documentation, let
us know by sending your suggestions to techpubs@ﬁco.com.
Please include your contact information (name, company, email address, and optionally, your phone
number) so we may reach you if we have questions.

Fair Isaac Corporation Conﬁdential and Proprietary Information

432

Contacting FICO

Sales and maintenanceIf you need information on other Xpress Optimization products, or you need to discuss maintenancecontracts or other sales-related items, contact FICO by:

Phone: +1 (408) 535-1500 or +44 207 940 8718



Web: http://www.ﬁco.com/optimization and use the available contact forms

Related services
Strategy Consulting: Included in your contract with FICO may be a speciﬁed amount of consulting time
to assist you in using FICO Optimization Modeler to meet your business needs. Additional consulting
time can be arranged by contract.
Conferences and Seminars: FICO offers conferences and seminars on our products and services. For
announcements concerning these events, go to www.ﬁco.com or contact your FICO accountrepresentative.

FICO Community
The FICO Community is a great resource to ﬁnd the experts and information you need to collaborate,
support your business, and solve common business challenges. You can get informal technicalsupport, build relationships with local and remote professionals, and improve your business practices.
For additional information, visit the FICO Community (community.ﬁco.com/welcome).

About FICO
FICO (NYSE:FICO) powers decisions that help people and businesses around the world prosper.
Founded in 1956 and based in Silicon Valley, the company is a pioneer in the use of predictive analytics
and data science to improve operational decisions. FICO holds more than 165 US and foreign patents
on technologies that increase proﬁtability, customer satisfaction, and growth for businesses inﬁnancial services, telecommunications, health care, retail, and many other industries. Using FICO
solutions, businesses in more than 100 countries do everything from protecting 2.6 billion payment
cards from fraud, to helping people get credit, to ensuring that millions of airplanes and rental cars arein the right place at the right time. Learn more at www.ﬁco.com.

Fair Isaac Corporation Conﬁdential and Proprietary Information

433

IndexB
branchobj.addbounds, 419
branchobj.addbranches, 420
branchobj.addcuts, 421
branchobj.addrows, 422
branchobj.getbounds, 423
branchobj.getbranches, 424
branchobj.getid, 425
branchobj.getlasterror, 426
branchobj.getrows, 427
branchobj.setpreferredbranch, 428
branchobj.setpriority, 429
branchobj.store, 430
branchobj.validate, 431
Oobject.extractLinear, 65
object.extractQuadratic, 66
Pproblem.addcbbariteration, 112
problem.addcbbarlog, 114
problem.addcbchecktime, 115
problem.addcbchgbranchobject, 116
problem.addcbcutlog, 117
problem.addcbdestroymt, 118
problem.addcbgapnotify, 119
problem.addcbgloballog, 121
problem.addcbinfnode, 122
problem.addcbintsol, 123
problem.addcblplog, 124
problem.addcbmessage, 125problem.addcbmipthread, 126
problem.addcbnewnode, 127
problem.addcbnodecutoff, 128
problem.addcboptnode, 129
problem.addcbpreintsol, 130
problem.addcbprenode, 131
problem.addcbusersolnotify, 132
problem.addcoefs, 133
problem.addcols, 135
problem.addConstraint, 137
problem.addcuts, 138
problem.adddfs, 139
problem.addgencons, 140
problem.addIndicator, 141
problem.addmipsol, 142
problem.addpwlcons, 143
problem.addqmatrix, 144
problem.addrows, 145
problem.addsetnames, 146
problem.addSOS, 147

Fair Isaac Corporation Conﬁdential and Proprietary Information

problem.addtolsets, 148problem.addVariable, 149
problem.addvars, 150
problem.basisstability, 151
problem.btran, 152
problem.calcobjective, 153
problem.calcreducedcosts, 154
problem.calcslacks, 155problem.calcsolinfo, 156
problem.cascade, 157
problem.cascadeorder, 158
problem.chgbounds, 159
problem.chgcascadenlimit, 162
problem.chgccoef, 163
problem.chgcoef, 160
problem.chgcoltype, 161
problem.chgdeltatype, 164
problem.chgdf, 165
problem.chgglblimit, 166
problem.chgmcoef, 167
problem.chgmqobj, 168
problem.chgnlcoef, 169
problem.chgobj, 170
problem.chgobjsense, 171
problem.chgqobj, 172
problem.chgqrowcoeff, 173
problem.chgrhs, 174
problem.chgrhsrange, 175
problem.chgrowstatus, 176
problem.chgrowtype, 177
problem.chgrowwt, 178
problem.chgtolset, 179
problem.chgvar, 180
problem.construct, 182
problem.copy, 183
problem.copycallbacks, 184
problem.copycontrols, 185
problem.crossoverlpsol, 186
problem.delcoefs, 187
problem.delConstraint, 188
problem.delcpcuts, 189
problem.delcuts, 190
problem.delgencons, 191
problem.delindicators, 192
problem.delpwlcons, 193
problem.delqmatrix, 194
problem.delSOS, 195
problem.deltolsets, 196
problem.delVariable, 197
problem.delvars, 198
problem.dumpcontrols, 199
problem.estimaterowdualranges, 200434

Indexproblem.evaluatecoef, 201
problem.evaluateformula, 202
problem.fixglobals, 203
problem.fixpenalties, 204
problem.ftran, 205
problem.getAttrib, 206
problem.getattribinfo, 207
problem.getbasis, 208
problem.getbasisval, 209
problem.getccoef, 210
problem.getcoef, 211
problem.getcoefformula, 212
problem.getcoefs, 213
problem.getcolinfo, 214
problem.getcols, 215
problem.getcoltype, 216
problem.getConstraint, 217
problem.getControl, 218
problem.getcontrolinfo, 219
problem.getcpcutlist, 220
problem.getcpcuts, 221
problem.getcutlist, 222
problem.getcutmap, 223
problem.getcutslack, 224
problem.getdf, 226
problem.getdirs, 225
problem.getDual, 227
problem.getdualray, 228
problem.getgencons, 229
problem.getglobal, 230
problem.getiisdata, 231
problem.getIndex, 233
problem.getIndexFromName, 234
problem.getindicators, 235
problem.getinfeas, 236
problem.getlastbarsol, 237
problem.getlasterror, 238
problem.getlb, 239
problem.getlpsol, 240
problem.getlpsolval, 241
problem.getmessagestatus, 242
problem.getmipsol, 243
problem.getmipsolval, 244
problem.getmqobj, 245
problem.getnamelist, 246
problem.getobj, 247
problem.getObjVal, 248
problem.getpivotorder, 249
problem.getpivots, 250
problem.getpresolvebasis, 251
problem.getpresolvemap, 252
problem.getpresolvesol, 253
problem.getprimalray, 254
problem.getProbStatus, 255
problem.getProbStatusString, 256
problem.getpwlcons, 257
problem.getqobj, 258
problem.getqrowcoeff, 259
problem.getqrowqmatrix, 260
problem.getqrowqmatrixtriplets, 261

Fair Isaac Corporation Conﬁdential and Proprietary Information

problem.getqrows, 262
problem.getRCost, 263
problem.getrhs, 264
problem.getrhsrange, 265
problem.getrowinfo, 266
problem.getrows, 267
problem.getrowstatus, 268
problem.getrowtype, 269
problem.getrowwt, 270
problem.getscaledinfeas, 271
problem.getSlack, 272
problem.getslpsol, 273
problem.getSolution, 274
problem.getSOS, 276
problem.gettolset, 277
problem.getub, 278
problem.getunbvec, 279
problem.getvar, 280
problem.getVariable, 282
problem.globalsol, 283
problem.hasdualray, 284
problem.hasprimalray, 285
problem.iisall, 286
problem.iisclear, 287
problem.iisfirst, 288
problem.iisisolations, 289
problem.iisnext, 290
problem.iisstatus, 291
problem.iiswrite, 292
problem.interrupt, 293
problem.loadbasis, 294
problem.loadbranchdirs, 295
problem.loadcoefs, 296
problem.loadcuts, 298
problem.loaddelayedrows, 299
problem.loaddfs, 300
problem.loaddirs, 301
problem.loadlpsol, 302
problem.loadmipsol, 303
problem.loadmodelcuts, 304
problem.loadpresolvebasis, 305
problem.loadpresolvedirs, 306
problem.loadproblem, 307
problem.loadsecurevecs, 309
problem.loadtolsets, 310
problem.loadvars, 311
problem.lpoptimize, 313
problem.mipoptimize, 314
problem.msaddcustompreset, 315
problem.msaddjob, 316
problem.msaddpreset, 317
problem.msclear, 318
problem.name, 319
problem.nlpoptimize, 320
problem.objsa, 321
problem.postsolve, 322
problem.presolve, 323
problem.presolverow, 324
problem.printevalinfo, 326
problem.printmemory, 325

435

Indexproblem.read, 327
problem.readbasis, 328
problem.readbinsol, 329
problem.readdirs, 330
problem.readslxsol, 331
problem.refinemipsol, 332
problem.reinitialize, 333
problem.removecbbariteration, 334
problem.removecbbarlog, 335
problem.removecbchecktime, 336
problem.removecbchgbranchobject, 337
problem.removecbcutlog, 338
problem.removecbdestroymt, 339
problem.removecbgapnotify, 340
problem.removecbgloballog, 341
problem.removecbinfnode, 342
problem.removecbintsol, 343
problem.removecblplog, 344
problem.removecbmessage, 345
problem.removecbmipthread, 346
problem.removecbnewnode, 347
problem.removecbnodecutoff, 348
problem.removecboptnode, 349
problem.removecbpreintsol, 350
problem.removecbprenode, 351
problem.removecbusersolnotify, 352
problem.repairinfeas, 353
problem.repairweightedinfeas, 355
problem.repairweightedinfeasbounds, 357
problem.reset, 359
problem.restore, 360
problem.rhssa, 361
problem.save, 362
problem.scale, 363
problem.scaling, 364
problem.setbranchbounds, 365
problem.setbranchcuts, 366
problem.setcbcascadeend, 367
problem.setcbcascadestart, 368
problem.setcbcascadevar, 369
problem.setcbcascadevarfail, 370
problem.setcbcoefevalerror, 371
problem.setcbconstruct, 372
problem.setcbdestroy, 374
problem.setcbdrcol, 375
problem.setcbintsol, 376
problem.setcbiterend, 377
problem.setcbiterstart, 378
problem.setcbitervar, 379
problem.setcbmessage, 380
problem.setcbmsjobend, 381
problem.setcbmsjobstart, 382
problem.setcbmswinner, 383
problem.setcboptnode, 384
problem.setcbprenode, 385
problem.setcbslpend, 386
problem.setcbslpnode, 387
problem.setcbslpstart, 388
problem.setControl, 389
problem.setcurrentiv, 390

Fair Isaac Corporation Conﬁdential and Proprietary Information

problem.setdefaultcontrol, 391
problem.setdefaults, 392
problem.setindicators, 393
problem.setlogfile, 394
problem.setmessagestatus, 395
problem.setObjective, 396
problem.setprobname, 397
problem.solve, 398
problem.storebounds, 399
problem.storecuts, 400
problem.strongbranch, 401
problem.strongbranchcb, 402
problem.tune, 403
problem.tunerreadmethod, 404
problem.tunerwritemethod, 405
problem.unconstruct, 406
problem.updatelinearization, 407
problem.validate, 408
problem.validatekkt, 409
problem.validaterow, 410
problem.validatevector, 411
problem.write, 412
problem.writebasis, 413
problem.writebinsol, 414
problem.writedirs, 415
problem.writeprtsol, 416
problem.writeslxsol, 417
problem.writesol, 418X
xpress.abs, 67
xpress.acos, 68
xpress.addcbmsghandler, 69
xpress.And, 70
xpress.asin, 71
xpress.atan, 72
xpress.cos, 73
xpress.Dot, 74
xpress.erf, 76
xpress.erfc, 77
xpress.evaluate, 78
xpress.examples, 80
xpress.exp, 81
xpress.featurequery, 82
xpress.free, 83
xpress.getbanner, 84
xpress.getcheckedmode, 85
xpress.getdaysleft, 86
xpress.getlasterror, 87
xpress.getlicerrmsg, 88
xpress.getversion, 89
xpress.init, 90
xpress.log, 91
xpress.log10, 92
xpress.manual, 93
xpress.max, 94
xpress.min, 95
xpress.Or, 96
xpress.Prod, 98
xpress.pwl, 97436

Indexxpress.removecbmsghandler, 99
xpress.setarchconsistency, 100
xpress.setcheckedmode, 101
xpress.setdefaultcontrol, 103
xpress.setdefaults, 102
xpress.sign, 104
xpress.sin, 105
xpress.sqrt, 106
xpress.Sum, 107
xpress.tan, 108
xpress.user, 109
xpress.vars, 110

Fair Isaac Corporation Conﬁdential and Proprietary Information

437