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 * @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
053public 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}