Coverage for lpsolvers / cdd_.py: 88%
17 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-20 15:19 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-20 15:19 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# SPDX-License-Identifier: LGPL-3.0-or-later
5# Copyright (C) 2016-2022 Stéphane Caron
7"""Solver interface for cdd."""
9from typing import Optional
11import cdd
12import numpy as np
15def cdd_solve_lp(
16 c: np.ndarray,
17 G: np.ndarray,
18 h: np.ndarray,
19 A: Optional[np.ndarray] = None,
20 b: Optional[np.ndarray] = None,
21) -> np.ndarray:
22 r"""Solve a linear program using the LP solver from cdd.
24 The linear program is defined by:
26 .. math::
28 \\begin{split}\\begin{array}{ll}
29 \\mbox{minimize} &
30 c^T x \\\\
31 \\mbox{subject to}
32 & G x \\leq h \\\\
33 & A x = b
34 \\end{array}\\end{split}
36 It is solved using `cdd <https://github.com/mcmtroffaes/pycddlib>`_.
38 Parameters
39 ----------
40 c :
41 Linear cost vector.
42 G :
43 Linear inequality constraint matrix.
44 h :
45 Linear inequality constraint vector.
46 A :
47 Linear equality constraint matrix.
48 b :
49 Linear equality constraint vector.
50 solver :
51 Solver to use, default is GLPK if available
53 Returns
54 -------
55 :
56 Optimal (primal) solution of the linear program, if it exists.
58 Raises
59 ------
60 ValueError
61 If the linear program is not feasible.
62 """
63 if A is not None and b is not None:
64 v = np.hstack([h, b, -b])
65 U = np.vstack([G, A, -A])
66 else: # no equality constraint
67 v = h
68 U = G
69 v = v.reshape((v.shape[0], 1))
70 constraints = np.hstack([v, -U])
71 objective = np.hstack([[0.0], c])
72 lp = cdd.linprog_from_array(
73 np.vstack([constraints, objective]), # type: ignore
74 obj_type=cdd.LPObjType.MIN,
75 )
76 cdd.linprog_solve(lp)
77 if lp.status != cdd.LPStatusType.OPTIMAL:
78 raise ValueError(f"Linear program not feasible: {lp.status}")
79 return np.array(lp.primal_solution)