or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants-enums.mdcore-modeling.mdfile-io.mdindex.mdmathematical-operations.mdsolver-interfaces.mdutility-functions.md

constants-enums.mddocs/

0

# Constants and Enums

1

2

Essential constants for variable categories, problem senses, constraint types, and status codes used throughout PuLP's modeling system. These constants provide standardized values for optimization problem specification and solution interpretation.

3

4

## Capabilities

5

6

### Package Metadata

7

8

Version information and precision constants for the PuLP package.

9

10

```python { .api }

11

VERSION: str = "3.2.2" # PuLP package version

12

EPS: float = 1e-7 # Default numerical precision tolerance

13

```

14

15

### Variable Categories

16

17

Constants defining the types of decision variables supported in optimization problems.

18

19

```python { .api }

20

LpContinuous: str = "Continuous" # Continuous variables (real numbers)

21

LpInteger: str = "Integer" # Integer variables (whole numbers)

22

LpBinary: str = "Binary" # Binary variables (0 or 1)

23

24

LpCategories: dict = {

25

LpContinuous: "Continuous",

26

LpInteger: "Integer",

27

LpBinary: "Binary"

28

} # Mapping of category constants to string representations

29

```

30

31

Usage examples:

32

33

```python

34

# Create variables with different categories

35

x_cont = LpVariable("x", cat=LpContinuous) # Can take any real value

36

y_int = LpVariable("y", cat=LpInteger) # Must be whole number

37

z_bin = LpVariable("z", cat=LpBinary) # Must be 0 or 1

38

39

# Check variable category

40

if x_cont.cat == LpContinuous:

41

print("x is a continuous variable")

42

43

# Use in bulk creation

44

binary_vars = LpVariable.dicts("decision", range(10), cat=LpBinary)

45

```

46

47

### Optimization Senses

48

49

Constants specifying whether the optimization problem seeks to minimize or maximize the objective function.

50

51

```python { .api }

52

LpMinimize: int = 1 # Minimize the objective function

53

LpMaximize: int = -1 # Maximize the objective function

54

55

LpSenses: dict = {

56

LpMinimize: "Minimize",

57

LpMaximize: "Maximize"

58

} # Mapping of sense constants to string representations

59

60

LpSensesMPS: dict = {

61

LpMaximize: "MAX",

62

LpMinimize: "MIN"

63

} # MPS format sense representations

64

```

65

66

Usage examples:

67

68

```python

69

# Create problems with different senses

70

min_prob = LpProblem("Cost_Minimization", LpMinimize)

71

max_prob = LpProblem("Profit_Maximization", LpMaximize)

72

73

# Check problem sense

74

if min_prob.sense == LpMinimize:

75

print("This is a minimization problem")

76

77

# Convert sense to string

78

print(f"Problem sense: {LpSenses[min_prob.sense]}")

79

```

80

81

### Problem Status Constants

82

83

Status codes returned after solving optimization problems, indicating the solution state.

84

85

```python { .api }

86

LpStatusNotSolved: int = 0 # Problem has not been solved yet

87

LpStatusOptimal: int = 1 # Optimal solution found

88

LpStatusInfeasible: int = -1 # Problem has no feasible solution

89

LpStatusUnbounded: int = -2 # Problem is unbounded (infinite optimum)

90

LpStatusUndefined: int = -3 # Solution status is undefined/unknown

91

92

LpStatus: dict = {

93

LpStatusNotSolved: "Not Solved",

94

LpStatusOptimal: "Optimal",

95

LpStatusInfeasible: "Infeasible",

96

LpStatusUnbounded: "Unbounded",

97

LpStatusUndefined: "Undefined"

98

} # Mapping of status codes to descriptive strings

99

```

100

101

Usage examples:

102

103

```python

104

# Solve problem and check status

105

status = prob.solve()

106

107

if status == LpStatusOptimal:

108

print("Optimal solution found!")

109

print(f"Objective value: {value(prob.objective)}")

110

elif status == LpStatusInfeasible:

111

print("Problem is infeasible - no solution exists")

112

elif status == LpStatusUnbounded:

113

print("Problem is unbounded - infinite optimum")

114

else:

115

print(f"Solution status: {LpStatus[status]}")

116

117

# Robust status checking

118

def interpret_solution(status):

119

return LpStatus.get(status, f"Unknown status: {status}")

120

121

print(interpret_solution(status))

122

```

123

124

### Solution Status Constants

125

126

Detailed solution status codes providing more granular information about the solution quality and type.

127

128

```python { .api }

129

LpSolutionNoSolutionFound: int = 0 # No solution found by solver

130

LpSolutionOptimal: int = 1 # Optimal solution found

131

LpSolutionIntegerFeasible: int = 2 # Integer feasible solution (may not be optimal)

132

LpSolutionInfeasible: int = -1 # No feasible solution exists

133

LpSolutionUnbounded: int = -2 # Unbounded solution

134

135

LpSolution: dict = {

136

LpSolutionNoSolutionFound: "No Solution Found",

137

LpSolutionOptimal: "Optimal",

138

LpSolutionIntegerFeasible: "Integer Feasible",

139

LpSolutionInfeasible: "Infeasible",

140

LpSolutionUnbounded: "Unbounded"

141

} # Solution status to string mappings

142

143

LpStatusToSolution: dict = {

144

LpStatusNotSolved: LpSolutionNoSolutionFound,

145

LpStatusOptimal: LpSolutionOptimal,

146

LpStatusInfeasible: LpSolutionInfeasible,

147

LpStatusUnbounded: LpSolutionUnbounded,

148

LpStatusUndefined: LpSolutionNoSolutionFound

149

} # Mapping from problem status to solution status

150

```

151

152

Usage examples:

153

154

```python

155

# Get detailed solution information

156

status = prob.solve()

157

solution_status = LpStatusToSolution[status]

158

159

print(f"Problem status: {LpStatus[status]}")

160

print(f"Solution status: {LpSolution[solution_status]}")

161

162

# Handle different solution qualities

163

if solution_status == LpSolutionOptimal:

164

print("Found proven optimal solution")

165

elif solution_status == LpSolutionIntegerFeasible:

166

print("Found feasible integer solution (may not be optimal)")

167

```

168

169

### Constraint Senses

170

171

Constants defining the mathematical relationship types for constraints (less than or equal, equal, greater than or equal).

172

173

```python { .api }

174

LpConstraintLE: int = -1 # Less than or equal constraint (<=)

175

LpConstraintEQ: int = 0 # Equality constraint (=)

176

LpConstraintGE: int = 1 # Greater than or equal constraint (>=)

177

178

LpConstraintSenses: dict = {

179

LpConstraintLE: "<=",

180

LpConstraintEQ: "=",

181

LpConstraintGE: ">="

182

} # Constraint sense to symbol mapping

183

184

LpConstraintTypeToMps: dict = {

185

LpConstraintLE: "L",

186

LpConstraintEQ: "E",

187

LpConstraintGE: "G"

188

} # MPS format constraint type codes

189

```

190

191

Usage examples:

192

193

```python

194

# Create constraints with explicit senses

195

constraint1 = LpConstraint(x + y, LpConstraintLE, "capacity", 100) # x + y <= 100

196

constraint2 = LpConstraint(2*x, LpConstraintEQ, "balance", 50) # 2*x = 50

197

constraint3 = LpConstraint(y, LpConstraintGE, "minimum", 10) # y >= 10

198

199

# Add to problem

200

prob += constraint1

201

prob += constraint2

202

prob += constraint3

203

204

# Check constraint sense

205

print(f"Constraint sense: {LpConstraintSenses[constraint1.sense]}")

206

207

# Programmatic constraint generation

208

def create_constraint(expr, sense_type, rhs):

209

if sense_type == "<=":

210

sense = LpConstraintLE

211

elif sense_type == "=":

212

sense = LpConstraintEQ

213

elif sense_type == ">=":

214

sense = LpConstraintGE

215

else:

216

raise ValueError(f"Unknown constraint sense: {sense_type}")

217

218

return LpConstraint(expr, sense, rhs=rhs)

219

220

# Use constraint senses in loops

221

capacity_constraints = []

222

for i in range(n_facilities):

223

constraint = LpConstraint(

224

lpSum(production[i]),

225

LpConstraintLE,

226

f"capacity_{i}",

227

facility_capacity[i]

228

)

229

capacity_constraints.append(constraint)

230

prob += constraint

231

```

232

233

### File Format Constants

234

235

Constants for file formatting and solver compatibility, particularly for MPS and LP file formats.

236

237

```python { .api }

238

LpCplexLPLineSize: int = 78 # Maximum line length for CPLEX LP format files

239

```

240

241

Usage example:

242

243

```python

244

# Used internally when writing LP format files

245

# Ensures compatibility with CPLEX and other solvers that expect specific line lengths

246

prob.writeLP("problem.lp") # Automatically handles line length constraints

247

```

248

249

### Status and Error Checking Utilities

250

251

Utility functions and patterns for robust status checking and error handling.

252

253

```python

254

# Common status checking patterns

255

def check_solution_status(problem):

256

"""Check and report problem solution status."""

257

status = problem.status

258

259

if status == LpStatusOptimal:

260

return True, "Optimal solution found"

261

elif status == LpStatusInfeasible:

262

return False, "Problem is infeasible"

263

elif status == LpStatusUnbounded:

264

return False, "Problem is unbounded"

265

elif status == LpStatusNotSolved:

266

return False, "Problem not solved yet"

267

else:

268

return False, f"Unknown status: {LpStatus.get(status, status)}"

269

270

# Robust solution extraction

271

def safe_get_values(variables):

272

"""Safely extract variable values with status checking."""

273

results = {}

274

for var in variables:

275

val = value(var)

276

if val is not None:

277

results[var.name] = val

278

else:

279

results[var.name] = "Not solved"

280

return results

281

282

# Status-based decision making

283

def handle_solution(prob):

284

status = prob.solve()

285

286

if status in [LpStatusOptimal, LpSolutionIntegerFeasible]:

287

# Process successful solution

288

return extract_solution(prob)

289

elif status == LpStatusInfeasible:

290

# Analyze infeasibility

291

return analyze_infeasibility(prob)

292

elif status == LpStatusUnbounded:

293

# Handle unbounded case

294

return add_bounds_and_retry(prob)

295

else:

296

# Handle other cases

297

return handle_solve_failure(prob, status)

298

```

299

300

## Exception Types

301

302

```python { .api }

303

class PulpError(Exception):

304

"""

305

Base exception class for PuLP-specific errors.

306

Raised for general PuLP modeling and solving errors.

307

"""

308

309

class PulpSolverError(Exception):

310

"""

311

Exception class for solver-specific errors.

312

Raised when solver execution fails or returns unexpected results.

313

"""

314

```

315

316

Usage examples:

317

318

```python

319

try:

320

status = prob.solve(CPLEX_CMD())

321

except PulpSolverError as e:

322

print(f"Solver error: {e}")

323

# Try alternative solver

324

status = prob.solve(PULP_CBC_CMD())

325

except PulpError as e:

326

print(f"PuLP error: {e}")

327

# Handle general PuLP errors

328

```