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