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> <= 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> <=
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 (=, <=, >=). */
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> <= 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> <= 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> <=
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> <=
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 }