View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.optim.linear;
18  
19  import org.apache.commons.math4.legacy.linear.ArrayRealVector;
20  import org.apache.commons.math4.legacy.linear.RealVector;
21  
22  /**
23   * A linear constraint for a linear optimization problem.
24   * <p>
25   * A linear constraint has one of the forms:
26   * <ul>
27   *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
28   *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
29   *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= v</li>
30   *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
31   *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
32   *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
33   *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
34   *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &gt;=
35   *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
36   * </ul>
37   * The c<sub>i</sub>, l<sub>i</sub> or r<sub>i</sub> are the coefficients of the constraints, the x<sub>i</sub>
38   * are the coordinates of the current point and v is the value of the constraint.
39   *
40   * @since 2.0
41   */
42  public class LinearConstraint {
43      /** Coefficients of the constraint (left hand side). */
44      private final RealVector coefficients;
45      /** Relationship between left and right hand sides {@code (=, <=, >=)}. */
46      private final Relationship relationship;
47      /** Value of the constraint (right hand side). */
48      private final double value;
49  
50      /**
51       * Build a constraint involving a single linear equation.
52       * <p>
53       * A linear constraint with a single linear equation has one of the forms:
54       * <ul>
55       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
56       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
57       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= v</li>
58       * </ul>
59       *
60       * @param coefficients The coefficients of the constraint (left hand side)
61       * @param relationship The type of (in)equality used in the constraint
62       * @param value The value of the constraint (right hand side)
63       */
64      public LinearConstraint(final double[] coefficients,
65                              final Relationship relationship,
66                              final double value) {
67          this(new ArrayRealVector(coefficients), relationship, value);
68      }
69  
70      /**
71       * Build a constraint involving a single linear equation.
72       * <p>
73       * A linear constraint with a single linear equation has one of the forms:
74       * <ul>
75       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
76       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
77       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= v</li>
78       * </ul>
79       *
80       * @param coefficients The coefficients of the constraint (left hand side)
81       * @param relationship The type of (in)equality used in the constraint
82       * @param value The value of the constraint (right hand side)
83       */
84      public LinearConstraint(final RealVector coefficients,
85                              final Relationship relationship,
86                              final double value) {
87          this.coefficients = coefficients;
88          this.relationship = relationship;
89          this.value        = value;
90      }
91  
92      /**
93       * Build a constraint involving two linear equations.
94       * <p>
95       * A linear constraint with two linear equation has one of the forms:
96       * <ul>
97       *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
98       *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
99       *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
100      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
101      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &gt;=
102      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
103      * </ul>
104      *
105      * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
106      * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
107      * @param relationship The type of (in)equality used in the constraint
108      * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
109      * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
110      */
111     public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant,
112                             final Relationship relationship,
113                             final double[] rhsCoefficients, final double rhsConstant) {
114         double[] sub = new double[lhsCoefficients.length];
115         for (int i = 0; i < sub.length; ++i) {
116             sub[i] = lhsCoefficients[i] - rhsCoefficients[i];
117         }
118         this.coefficients = new ArrayRealVector(sub, false);
119         this.relationship = relationship;
120         this.value        = rhsConstant - lhsConstant;
121     }
122 
123     /**
124      * Build a constraint involving two linear equations.
125      * <p>
126      * A linear constraint with two linear equation has one of the forms:
127      * <ul>
128      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
129      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
130      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
131      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
132      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &gt;=
133      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
134      * </ul>
135      *
136      * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
137      * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
138      * @param relationship The type of (in)equality used in the constraint
139      * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
140      * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
141      */
142     public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant,
143                             final Relationship relationship,
144                             final RealVector rhsCoefficients, final double rhsConstant) {
145         this.coefficients = lhsCoefficients.subtract(rhsCoefficients);
146         this.relationship = relationship;
147         this.value        = rhsConstant - lhsConstant;
148     }
149 
150     /**
151      * Gets the coefficients of the constraint (left hand side).
152      *
153      * @return the coefficients of the constraint (left hand side).
154      */
155     public RealVector getCoefficients() {
156         return coefficients;
157     }
158 
159     /**
160      * Gets the relationship between left and right hand sides.
161      *
162      * @return the relationship between left and right hand sides.
163      */
164     public Relationship getRelationship() {
165         return relationship;
166     }
167 
168     /**
169      * Gets the value of the constraint (right hand side).
170      *
171      * @return the value of the constraint (right hand side).
172      */
173     public double getValue() {
174         return value;
175     }
176 
177     /** {@inheritDoc} */
178     @Override
179     public boolean equals(Object other) {
180         if (this == other) {
181             return true;
182         }
183         if (other instanceof LinearConstraint) {
184             LinearConstraint rhs = (LinearConstraint) other;
185             return relationship == rhs.relationship &&
186                 value == rhs.value &&
187                 coefficients.equals(rhs.coefficients);
188         }
189         return false;
190     }
191 
192     /** {@inheritDoc} */
193     @Override
194     public int hashCode() {
195         return relationship.hashCode() ^
196             Double.valueOf(value).hashCode() ^
197             coefficients.hashCode();
198     }
199 }