001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math.optimization.linear;
019    
020    import java.io.IOException;
021    import java.io.ObjectInputStream;
022    import java.io.ObjectOutputStream;
023    import java.io.Serializable;
024    
025    import org.apache.commons.math.linear.MatrixUtils;
026    import org.apache.commons.math.linear.RealVector;
027    import org.apache.commons.math.linear.ArrayRealVector;
028    
029    
030    /**
031     * A linear constraint for a linear optimization problem.
032     * <p>
033     * A linear constraint has one of the forms:
034     * <ul>
035     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
036     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
037     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
038     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
039     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
040     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
041     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
042     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
043     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
044     * </ul>
045     * 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>
046     * are the coordinates of the current point and v is the value of the constraint.
047     * </p>
048     * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $
049     * @since 2.0
050     */
051    public class LinearConstraint implements Serializable {
052    
053        /** Serializable version identifier. */
054        private static final long serialVersionUID = -764632794033034092L;
055    
056        /** Coefficients of the constraint (left hand side). */
057        private final transient RealVector coefficients;
058    
059        /** Relationship between left and right hand sides (=, &lt;=, >=). */
060        private final Relationship relationship;
061    
062        /** Value of the constraint (right hand side). */
063        private final double value;
064    
065        /**
066         * Build a constraint involving a single linear equation.
067         * <p>
068         * A linear constraint with a single linear equation has one of the forms:
069         * <ul>
070         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
071         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
072         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
073         * </ul>
074         * </p>
075         * @param coefficients The coefficients of the constraint (left hand side)
076         * @param relationship The type of (in)equality used in the constraint
077         * @param value The value of the constraint (right hand side)
078         */
079        public LinearConstraint(final double[] coefficients, final Relationship relationship,
080                                final double value) {
081            this(new ArrayRealVector(coefficients), relationship, value);
082        }
083    
084        /**
085         * Build a constraint involving a single linear equation.
086         * <p>
087         * A linear constraint with a single linear equation has one of the forms:
088         * <ul>
089         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
090         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
091         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
092         * </ul>
093         * </p>
094         * @param coefficients The coefficients of the constraint (left hand side)
095         * @param relationship The type of (in)equality used in the constraint
096         * @param value The value of the constraint (right hand side)
097         */
098        public LinearConstraint(final RealVector coefficients, final Relationship relationship,
099                                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 instanceof LinearConstraint) {
196              LinearConstraint rhs = (LinearConstraint) other;
197              return (relationship == rhs.relationship) &&
198                     (value        == rhs.value) &&
199                     coefficients.equals(rhs.coefficients);
200          }
201          return false;
202        }
203    
204        /** {@inheritDoc} */
205        @Override
206        public int hashCode() {
207            return relationship.hashCode() ^
208                   Double.valueOf(value).hashCode() ^
209                   coefficients.hashCode();
210        }
211    
212        /** Serialize the instance.
213         * @param oos stream where object should be written
214         * @throws IOException if object cannot be written to stream
215         */
216        private void writeObject(ObjectOutputStream oos)
217            throws IOException {
218            oos.defaultWriteObject();
219            MatrixUtils.serializeRealVector(coefficients, oos);
220        }
221    
222        /** Deserialize the instance.
223         * @param ois stream from which the object should be read
224         * @throws ClassNotFoundException if a class in the stream cannot be found
225         * @throws IOException if object cannot be read from the stream
226         */
227        private void readObject(ObjectInputStream ois)
228          throws ClassNotFoundException, IOException {
229            ois.defaultReadObject();
230            MatrixUtils.deserializeRealVector(this, "coefficients", ois);
231        }
232    
233    }