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.math3.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.math3.linear.MatrixUtils;
026    import org.apache.commons.math3.linear.RealVector;
027    import org.apache.commons.math3.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 $Id: LinearConstraint.java 1422230 2012-12-15 12:11:13Z erans $
049     * @deprecated As of 3.1 (to be removed in 4.0).
050     * @since 2.0
051     */
052    @Deprecated
053    public class LinearConstraint implements Serializable {
054    
055        /** Serializable version identifier. */
056        private static final long serialVersionUID = -764632794033034092L;
057    
058        /** Coefficients of the constraint (left hand side). */
059        private final transient RealVector coefficients;
060    
061        /** Relationship between left and right hand sides (=, &lt;=, >=). */
062        private final Relationship relationship;
063    
064        /** Value of the constraint (right hand side). */
065        private final double value;
066    
067        /**
068         * Build a constraint involving a single linear equation.
069         * <p>
070         * A linear constraint with a single linear equation has one of the forms:
071         * <ul>
072         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
073         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
074         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
075         * </ul>
076         * </p>
077         * @param coefficients The coefficients of the constraint (left hand side)
078         * @param relationship The type of (in)equality used in the constraint
079         * @param value The value of the constraint (right hand side)
080         */
081        public LinearConstraint(final double[] coefficients, final Relationship relationship,
082                                final double value) {
083            this(new ArrayRealVector(coefficients), relationship, value);
084        }
085    
086        /**
087         * Build a constraint involving a single linear equation.
088         * <p>
089         * A linear constraint with a single linear equation has one of the forms:
090         * <ul>
091         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
092         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
093         *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
094         * </ul>
095         * </p>
096         * @param coefficients The coefficients of the constraint (left hand side)
097         * @param relationship The type of (in)equality used in the constraint
098         * @param value The value of the constraint (right hand side)
099         */
100        public LinearConstraint(final RealVector coefficients, final Relationship relationship,
101                                final double value) {
102            this.coefficients = coefficients;
103            this.relationship = relationship;
104            this.value        = value;
105        }
106    
107        /**
108         * Build a constraint involving two linear equations.
109         * <p>
110         * A linear constraint with two linear equation has one of the forms:
111         * <ul>
112         *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
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> &lt;=
115         *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
116         *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
117         *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
118         * </ul>
119         * </p>
120         * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
121         * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
122         * @param relationship The type of (in)equality used in the constraint
123         * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
124         * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
125         */
126        public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant,
127                                final Relationship relationship,
128                                final double[] rhsCoefficients, final double rhsConstant) {
129            double[] sub = new double[lhsCoefficients.length];
130            for (int i = 0; i < sub.length; ++i) {
131                sub[i] = lhsCoefficients[i] - rhsCoefficients[i];
132            }
133            this.coefficients = new ArrayRealVector(sub, false);
134            this.relationship = relationship;
135            this.value        = rhsConstant - lhsConstant;
136        }
137    
138        /**
139         * Build a constraint involving two linear equations.
140         * <p>
141         * A linear constraint with two linear equation has one of the forms:
142         * <ul>
143         *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
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> &lt;=
146         *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
147         *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
148         *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
149         * </ul>
150         * </p>
151         * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
152         * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
153         * @param relationship The type of (in)equality used in the constraint
154         * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
155         * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
156         */
157        public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant,
158                                final Relationship relationship,
159                                final RealVector rhsCoefficients, final double rhsConstant) {
160            this.coefficients = lhsCoefficients.subtract(rhsCoefficients);
161            this.relationship = relationship;
162            this.value        = rhsConstant - lhsConstant;
163        }
164    
165        /**
166         * Get the coefficients of the constraint (left hand side).
167         * @return coefficients of the constraint (left hand side)
168         */
169        public RealVector getCoefficients() {
170            return coefficients;
171        }
172    
173        /**
174         * Get the relationship between left and right hand sides.
175         * @return relationship between left and right hand sides
176         */
177        public Relationship getRelationship() {
178            return relationship;
179        }
180    
181        /**
182         * Get the value of the constraint (right hand side).
183         * @return value of the constraint (right hand side)
184         */
185        public double getValue() {
186            return value;
187        }
188    
189        @Override
190        public boolean equals(Object other) {
191    
192          if (this == other) {
193            return true;
194          }
195    
196          if (other instanceof LinearConstraint) {
197              LinearConstraint rhs = (LinearConstraint) other;
198              return (relationship == rhs.relationship) &&
199                     (value        == rhs.value) &&
200                     coefficients.equals(rhs.coefficients);
201          }
202          return false;
203        }
204    
205        @Override
206        public int hashCode() {
207            return relationship.hashCode() ^
208                   Double.valueOf(value).hashCode() ^
209                   coefficients.hashCode();
210        }
211    
212        /**
213         * Serialize the instance.
214         * @param oos stream where object should be written
215         * @throws IOException if object cannot be written to stream
216         */
217        private void writeObject(ObjectOutputStream oos)
218            throws IOException {
219            oos.defaultWriteObject();
220            MatrixUtils.serializeRealVector(coefficients, oos);
221        }
222    
223        /**
224         * Deserialize the instance.
225         * @param ois stream from which the object should be read
226         * @throws ClassNotFoundException if a class in the stream cannot be found
227         * @throws IOException if object cannot be read from the stream
228         */
229        private void readObject(ObjectInputStream ois)
230          throws ClassNotFoundException, IOException {
231            ois.defaultReadObject();
232            MatrixUtils.deserializeRealVector(this, "coefficients", ois);
233        }
234    
235    }