I am trying to understand a problem and would like to generate all extreme rays for a given set of linear constraints. With the Python interface of CPLEX, I was able to generate a single ray (not sure if it is guaranteed to be extreme) but is there a way to get all extreme rays?
On a theoretical level, I know that in my problem, 0 is always a feasible solution and if $x$ is feasible and $\lambda \ge 0$ then $\lambda x$ is feasible (I think this means that the constraints describe a pointed polyhedral cone). So as far as I understand that means that there is a ray through every feasible point. But how do I find the extreme ones out of this infinite set?
Edit Thanks to the helpful comments below, I learned about the double description algorithm and found implementations in sagemath.org and polymake. Unfortunately, I had problems with both implementations. The first could not handle a matrix with a rank smaller than the number of columns. The second returns a set of rays but I think it must be missing some because there are solutions to the original constraints that cannot be expressed as a non-negative combination of the rays. I'm not certain about using polymake correctly, so let me give an example:
Example (in polymake)
$inequalities=new Matrix<Rational>([
[0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0,-1, 0, 0, 0, 0],
[0, 1, 0, 0, 1,-1, 0, 0, 0],
[0, 0, 1, 0, 0, 1,-1, 0, 0],
[0, 0, 0, 1, 0, 1, 0,-1, 0],
[0, 1, 0, 0, 0, 0, 1,-1, 0],
[0, 0, 0, 0, 0, 0, 0, 1,-1]]);
$p=new Polytope<Rational>(INEQUALITIES=>$inequalities);
print_constraints($p->INEQUALITIES);
0: x4 >= 0
1: -x4 >= 0
2: x1 + x4 - x5 >= 0
3: x2 + x5 - x6 >= 0
4: x3 + x5 - x7 >= 0
5: x1 + x6 - x7 >= 0
6: x7 - x8 >= 0
7: 0 >= -1
# All variables are general, i.e., not restricted to non-negative values.
print $p->VERTICES;
1 0 0 0 0 0 0 0 0
0 1 -1 -1 0 1 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 1 1 0 -1 0 0 0
0 1 -1 0 0 1 0 1 0
Now, I think the first coordinate indicates whether the following row vector is an extreme point (1) or ray (0). Since this is a pointed cone, it makes sense that the only extreme point is 0 and all other rows are rays. However, I thought that every solution to the constraints should be expressible as a non-negative combination of these rows. But there are solutions with $x_8 = 1$ even though all rays have $x_8 = 0$. For example, $(1, 0, 0, 0, 1, 1, 1, 1)$ should be a solution. Can someone help me understand this?
Second Edit
The trick with polymake was that rays $r$ where $r$ and $-r$ are extreme rays are not part of RAYS
. Instead they are given as LINEALITY_SPACE
. Including them and their negative values gave me the answer I was looking for.
print $p->LINEALITY_SPACE;
0 -1 2 1 0 -1 1 0 0
0 1/2 0 1/2 0 1/2 1/2 1 1