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