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.math3.optim.linear;
18  
19  import java.io.IOException;
20  import java.io.ObjectInputStream;
21  import java.io.ObjectOutputStream;
22  import java.io.Serializable;
23  import org.apache.commons.math3.linear.MatrixUtils;
24  import org.apache.commons.math3.linear.RealVector;
25  import org.apache.commons.math3.linear.ArrayRealVector;
26  
27  /**
28   * A linear constraint for a linear optimization problem.
29   * <p>
30   * A linear constraint has one of the forms:
31   * <ul>
32   *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
33   *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
34   *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
35   *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
36   *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
37   *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
38   *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
39   *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
40   *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
41   * </ul>
42   * 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>
43   * are the coordinates of the current point and v is the value of the constraint.
44   * </p>
45   *
46   * @version $Id: LinearConstraint.java 1435539 2013-01-19 13:27:24Z tn $
47   * @since 2.0
48   */
49  public class LinearConstraint implements Serializable {
50      /** Serializable version identifier. */
51      private static final long serialVersionUID = -764632794033034092L;
52      /** Coefficients of the constraint (left hand side). */
53      private final transient RealVector coefficients;
54      /** Relationship between left and right hand sides (=, &lt;=, >=). */
55      private final Relationship relationship;
56      /** Value of the constraint (right hand side). */
57      private final double value;
58  
59      /**
60       * Build a constraint involving a single linear equation.
61       * <p>
62       * A linear constraint with a single linear equation has one of the forms:
63       * <ul>
64       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
65       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
66       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
67       * </ul>
68       * </p>
69       * @param coefficients The coefficients of the constraint (left hand side)
70       * @param relationship The type of (in)equality used in the constraint
71       * @param value The value of the constraint (right hand side)
72       */
73      public LinearConstraint(final double[] coefficients,
74                              final Relationship relationship,
75                              final double value) {
76          this(new ArrayRealVector(coefficients), relationship, value);
77      }
78  
79      /**
80       * Build a constraint involving a single linear equation.
81       * <p>
82       * A linear constraint with a single linear equation has one of the forms:
83       * <ul>
84       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
85       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
86       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
87       * </ul>
88       * </p>
89       * @param coefficients The coefficients of the constraint (left hand side)
90       * @param relationship The type of (in)equality used in the constraint
91       * @param value The value of the constraint (right hand side)
92       */
93      public LinearConstraint(final RealVector coefficients,
94                              final Relationship relationship,
95                              final double value) {
96          this.coefficients = coefficients;
97          this.relationship = relationship;
98          this.value        = value;
99      }
100 
101     /**
102      * Build a constraint involving two linear equations.
103      * <p>
104      * A linear constraint with two linear equation has one of the forms:
105      * <ul>
106      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
107      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
108      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
109      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
110      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
111      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
112      * </ul>
113      * </p>
114      * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
115      * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
116      * @param relationship The type of (in)equality used in the constraint
117      * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
118      * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
119      */
120     public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant,
121                             final Relationship relationship,
122                             final double[] rhsCoefficients, final double rhsConstant) {
123         double[] sub = new double[lhsCoefficients.length];
124         for (int i = 0; i < sub.length; ++i) {
125             sub[i] = lhsCoefficients[i] - rhsCoefficients[i];
126         }
127         this.coefficients = new ArrayRealVector(sub, false);
128         this.relationship = relationship;
129         this.value        = rhsConstant - lhsConstant;
130     }
131 
132     /**
133      * Build a constraint involving two linear equations.
134      * <p>
135      * A linear constraint with two linear equation has one of the forms:
136      * <ul>
137      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
138      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
139      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
140      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
141      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
142      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
143      * </ul>
144      * </p>
145      * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
146      * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
147      * @param relationship The type of (in)equality used in the constraint
148      * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
149      * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
150      */
151     public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant,
152                             final Relationship relationship,
153                             final RealVector rhsCoefficients, final double rhsConstant) {
154         this.coefficients = lhsCoefficients.subtract(rhsCoefficients);
155         this.relationship = relationship;
156         this.value        = rhsConstant - lhsConstant;
157     }
158 
159     /**
160      * Gets the coefficients of the constraint (left hand side).
161      *
162      * @return the coefficients of the constraint (left hand side).
163      */
164     public RealVector getCoefficients() {
165         return coefficients;
166     }
167 
168     /**
169      * Gets the relationship between left and right hand sides.
170      *
171      * @return the relationship between left and right hand sides.
172      */
173     public Relationship getRelationship() {
174         return relationship;
175     }
176 
177     /**
178      * Gets the value of the constraint (right hand side).
179      *
180      * @return the value of the constraint (right hand side).
181      */
182     public double getValue() {
183         return value;
184     }
185 
186     @Override
187     public boolean equals(Object other) {
188         if (this == other) {
189             return true;
190         }
191         if (other instanceof LinearConstraint) {
192             LinearConstraint rhs = (LinearConstraint) other;
193             return relationship == rhs.relationship &&
194                 value == rhs.value &&
195                 coefficients.equals(rhs.coefficients);
196         }
197         return false;
198     }
199 
200     @Override
201     public int hashCode() {
202         return relationship.hashCode() ^
203             Double.valueOf(value).hashCode() ^
204             coefficients.hashCode();
205     }
206 
207     /**
208      * Serialize the instance.
209      * @param oos stream where object should be written
210      * @throws IOException if object cannot be written to stream
211      */
212     private void writeObject(ObjectOutputStream oos)
213         throws IOException {
214         oos.defaultWriteObject();
215         MatrixUtils.serializeRealVector(coefficients, oos);
216     }
217 
218     /**
219      * Deserialize the instance.
220      * @param ois stream from which the object should be read
221      * @throws ClassNotFoundException if a class in the stream cannot be found
222      * @throws IOException if object cannot be read from the stream
223      */
224     private void readObject(ObjectInputStream ois)
225       throws ClassNotFoundException, IOException {
226         ois.defaultReadObject();
227         MatrixUtils.deserializeRealVector(this, "coefficients", ois);
228     }
229 }