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 package org.apache.commons.math3.optim.linear;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.io.Serializable;
23 import org.apache.commons.math3.linear.MatrixUtils;
24 import org.apache.commons.math3.linear.RealVector;
25 import org.apache.commons.math3.linear.ArrayRealVector;
26
27 /**
28 * A linear constraint for a linear optimization problem.
29 * <p>
30 * A linear constraint has one of the forms:
31 * <ul>
32 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
33 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
34 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
35 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
36 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
37 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <=
38 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
39 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
40 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
41 * </ul>
42 * 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>
43 * are the coordinates of the current point and v is the value of the constraint.
44 * </p>
45 *
46 * @version $Id: LinearConstraint.java 1435539 2013-01-19 13:27:24Z tn $
47 * @since 2.0
48 */
49 public class LinearConstraint implements Serializable {
50 /** Serializable version identifier. */
51 private static final long serialVersionUID = -764632794033034092L;
52 /** Coefficients of the constraint (left hand side). */
53 private final transient RealVector coefficients;
54 /** Relationship between left and right hand sides (=, <=, >=). */
55 private final Relationship relationship;
56 /** Value of the constraint (right hand side). */
57 private final double value;
58
59 /**
60 * Build a constraint involving a single linear equation.
61 * <p>
62 * A linear constraint with a single linear equation has one of the forms:
63 * <ul>
64 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
65 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
66 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
67 * </ul>
68 * </p>
69 * @param coefficients The coefficients of the constraint (left hand side)
70 * @param relationship The type of (in)equality used in the constraint
71 * @param value The value of the constraint (right hand side)
72 */
73 public LinearConstraint(final double[] coefficients,
74 final Relationship relationship,
75 final double value) {
76 this(new ArrayRealVector(coefficients), relationship, value);
77 }
78
79 /**
80 * Build a constraint involving a single linear equation.
81 * <p>
82 * A linear constraint with a single linear equation has one of the forms:
83 * <ul>
84 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
85 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
86 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
87 * </ul>
88 * </p>
89 * @param coefficients The coefficients of the constraint (left hand side)
90 * @param relationship The type of (in)equality used in the constraint
91 * @param value The value of the constraint (right hand side)
92 */
93 public LinearConstraint(final RealVector coefficients,
94 final Relationship relationship,
95 final double value) {
96 this.coefficients = coefficients;
97 this.relationship = relationship;
98 this.value = value;
99 }
100
101 /**
102 * Build a constraint involving two linear equations.
103 * <p>
104 * A linear constraint with two linear equation has one of the forms:
105 * <ul>
106 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
107 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
108 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <=
109 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
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 * </ul>
113 * </p>
114 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
115 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
116 * @param relationship The type of (in)equality used in the constraint
117 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
118 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
119 */
120 public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant,
121 final Relationship relationship,
122 final double[] rhsCoefficients, final double rhsConstant) {
123 double[] sub = new double[lhsCoefficients.length];
124 for (int i = 0; i < sub.length; ++i) {
125 sub[i] = lhsCoefficients[i] - rhsCoefficients[i];
126 }
127 this.coefficients = new ArrayRealVector(sub, false);
128 this.relationship = relationship;
129 this.value = rhsConstant - lhsConstant;
130 }
131
132 /**
133 * Build a constraint involving two linear equations.
134 * <p>
135 * A linear constraint with two linear equation has one of the forms:
136 * <ul>
137 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
138 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
139 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <=
140 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
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 * </ul>
144 * </p>
145 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
146 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
147 * @param relationship The type of (in)equality used in the constraint
148 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
149 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
150 */
151 public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant,
152 final Relationship relationship,
153 final RealVector rhsCoefficients, final double rhsConstant) {
154 this.coefficients = lhsCoefficients.subtract(rhsCoefficients);
155 this.relationship = relationship;
156 this.value = rhsConstant - lhsConstant;
157 }
158
159 /**
160 * Gets the coefficients of the constraint (left hand side).
161 *
162 * @return the coefficients of the constraint (left hand side).
163 */
164 public RealVector getCoefficients() {
165 return coefficients;
166 }
167
168 /**
169 * Gets the relationship between left and right hand sides.
170 *
171 * @return the relationship between left and right hand sides.
172 */
173 public Relationship getRelationship() {
174 return relationship;
175 }
176
177 /**
178 * Gets the value of the constraint (right hand side).
179 *
180 * @return the value of the constraint (right hand side).
181 */
182 public double getValue() {
183 return value;
184 }
185
186 @Override
187 public boolean equals(Object other) {
188 if (this == other) {
189 return true;
190 }
191 if (other instanceof LinearConstraint) {
192 LinearConstraint rhs = (LinearConstraint) other;
193 return relationship == rhs.relationship &&
194 value == rhs.value &&
195 coefficients.equals(rhs.coefficients);
196 }
197 return false;
198 }
199
200 @Override
201 public int hashCode() {
202 return relationship.hashCode() ^
203 Double.valueOf(value).hashCode() ^
204 coefficients.hashCode();
205 }
206
207 /**
208 * Serialize the instance.
209 * @param oos stream where object should be written
210 * @throws IOException if object cannot be written to stream
211 */
212 private void writeObject(ObjectOutputStream oos)
213 throws IOException {
214 oos.defaultWriteObject();
215 MatrixUtils.serializeRealVector(coefficients, oos);
216 }
217
218 /**
219 * Deserialize the instance.
220 * @param ois stream from which the object should be read
221 * @throws ClassNotFoundException if a class in the stream cannot be found
222 * @throws IOException if object cannot be read from the stream
223 */
224 private void readObject(ObjectInputStream ois)
225 throws ClassNotFoundException, IOException {
226 ois.defaultReadObject();
227 MatrixUtils.deserializeRealVector(this, "coefficients", ois);
228 }
229 }