1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.math.optimization.linear;
19
20 import java.io.IOException;
21 import java.io.ObjectInputStream;
22 import java.io.ObjectOutputStream;
23 import java.io.Serializable;
24
25 import org.apache.commons.math.linear.MatrixUtils;
26 import org.apache.commons.math.linear.RealVector;
27 import org.apache.commons.math.linear.ArrayRealVector;
28
29
30 /**
31 * A linear constraint for a linear optimization problem.
32 * <p>
33 * A linear constraint has one of the forms:
34 * <ul>
35 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
36 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
37 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
38 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
39 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
40 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <=
41 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
42 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
43 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
44 * </ul>
45 * 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>
46 * are the coordinates of the current point and v is the value of the constraint.
47 * </p>
48 * @version $Revision: 783702 $ $Date: 2009-06-11 04:54:02 -0400 (Thu, 11 Jun 2009) $
49 * @since 2.0
50 */
51 public class LinearConstraint implements Serializable {
52
53 /** Serializable version identifier. */
54 private static final long serialVersionUID = -764632794033034092L;
55
56 /** Coefficients of the constraint (left hand side). */
57 private final transient RealVector coefficients;
58
59 /** Relationship between left and right hand sides (=, <=, >=). */
60 private final Relationship relationship;
61
62 /** Value of the constraint (right hand side). */
63 private final double value;
64
65 /**
66 * Build a constraint involving a single linear equation.
67 * <p>
68 * A linear constraint with a single linear equation has one of the forms:
69 * <ul>
70 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
71 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
72 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
73 * </ul>
74 * </p>
75 * @param coefficients The coefficients of the constraint (left hand side)
76 * @param relationship The type of (in)equality used in the constraint
77 * @param value The value of the constraint (right hand side)
78 */
79 public LinearConstraint(final double[] coefficients, final Relationship relationship,
80 final double value) {
81 this(new ArrayRealVector(coefficients), relationship, value);
82 }
83
84 /**
85 * Build a constraint involving a single linear equation.
86 * <p>
87 * A linear constraint with a single linear equation has one of the forms:
88 * <ul>
89 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
90 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
91 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
92 * </ul>
93 * </p>
94 * @param coefficients The coefficients of the constraint (left hand side)
95 * @param relationship The type of (in)equality used in the constraint
96 * @param value The value of the constraint (right hand side)
97 */
98 public LinearConstraint(final RealVector coefficients, final Relationship relationship,
99 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 == null) {
196 return false;
197 }
198
199 try {
200
201 LinearConstraint rhs = (LinearConstraint) other;
202 return (relationship == rhs.relationship) &&
203 (value == rhs.value) &&
204 coefficients.equals(rhs.coefficients);
205
206 } catch (ClassCastException ex) {
207 // ignore exception
208 return false;
209 }
210
211 }
212
213 /** {@inheritDoc} */
214 @Override
215 public int hashCode() {
216 return relationship.hashCode() ^
217 Double.valueOf(value).hashCode() ^
218 coefficients.hashCode();
219 }
220
221 /** Serialize the instance.
222 * @param oos stream where object should be written
223 * @throws IOException if object cannot be written to stream
224 */
225 private void writeObject(ObjectOutputStream oos)
226 throws IOException {
227 oos.defaultWriteObject();
228 MatrixUtils.serializeRealVector(coefficients, oos);
229 }
230
231 /** Deserialize the instance.
232 * @param ois stream from which the object should be read
233 * @throws ClassNotFoundException if a class in the stream cannot be found
234 * @throws IOException if object cannot be read from the stream
235 */
236 private void readObject(ObjectInputStream ois)
237 throws ClassNotFoundException, IOException {
238 ois.defaultReadObject();
239 MatrixUtils.deserializeRealVector(this, "coefficients", ois);
240 }
241
242 }