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.math4.legacy.optim.linear;
18
19 import org.apache.commons.math4.legacy.linear.ArrayRealVector;
20 import org.apache.commons.math4.legacy.linear.RealVector;
21
22 /**
23 * A linear constraint for a linear optimization problem.
24 * <p>
25 * A linear constraint has one of the forms:
26 * <ul>
27 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
28 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
29 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
30 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
31 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
32 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <=
33 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
34 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
35 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
36 * </ul>
37 * 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>
38 * are the coordinates of the current point and v is the value of the constraint.
39 *
40 * @since 2.0
41 */
42 public class LinearConstraint {
43 /** Coefficients of the constraint (left hand side). */
44 private final RealVector coefficients;
45 /** Relationship between left and right hand sides {@code (=, <=, >=)}. */
46 private final Relationship relationship;
47 /** Value of the constraint (right hand side). */
48 private final double value;
49
50 /**
51 * Build a constraint involving a single linear equation.
52 * <p>
53 * A linear constraint with a single linear equation has one of the forms:
54 * <ul>
55 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
56 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
57 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
58 * </ul>
59 *
60 * @param coefficients The coefficients of the constraint (left hand side)
61 * @param relationship The type of (in)equality used in the constraint
62 * @param value The value of the constraint (right hand side)
63 */
64 public LinearConstraint(final double[] coefficients,
65 final Relationship relationship,
66 final double value) {
67 this(new ArrayRealVector(coefficients), relationship, value);
68 }
69
70 /**
71 * Build a constraint involving a single linear equation.
72 * <p>
73 * A linear constraint with a single linear equation has one of the forms:
74 * <ul>
75 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
76 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li>
77 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
78 * </ul>
79 *
80 * @param coefficients The coefficients of the constraint (left hand side)
81 * @param relationship The type of (in)equality used in the constraint
82 * @param value The value of the constraint (right hand side)
83 */
84 public LinearConstraint(final RealVector coefficients,
85 final Relationship relationship,
86 final double value) {
87 this.coefficients = coefficients;
88 this.relationship = relationship;
89 this.value = value;
90 }
91
92 /**
93 * Build a constraint involving two linear equations.
94 * <p>
95 * A linear constraint with two linear equation has one of the forms:
96 * <ul>
97 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
98 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
99 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <=
100 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
101 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
102 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
103 * </ul>
104 *
105 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
106 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
107 * @param relationship The type of (in)equality used in the constraint
108 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
109 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
110 */
111 public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant,
112 final Relationship relationship,
113 final double[] rhsCoefficients, final double rhsConstant) {
114 double[] sub = new double[lhsCoefficients.length];
115 for (int i = 0; i < sub.length; ++i) {
116 sub[i] = lhsCoefficients[i] - rhsCoefficients[i];
117 }
118 this.coefficients = new ArrayRealVector(sub, false);
119 this.relationship = relationship;
120 this.value = rhsConstant - lhsConstant;
121 }
122
123 /**
124 * Build a constraint involving two linear equations.
125 * <p>
126 * A linear constraint with two linear equation has one of the forms:
127 * <ul>
128 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
129 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
130 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <=
131 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
132 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
133 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
134 * </ul>
135 *
136 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
137 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
138 * @param relationship The type of (in)equality used in the constraint
139 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
140 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
141 */
142 public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant,
143 final Relationship relationship,
144 final RealVector rhsCoefficients, final double rhsConstant) {
145 this.coefficients = lhsCoefficients.subtract(rhsCoefficients);
146 this.relationship = relationship;
147 this.value = rhsConstant - lhsConstant;
148 }
149
150 /**
151 * Gets the coefficients of the constraint (left hand side).
152 *
153 * @return the coefficients of the constraint (left hand side).
154 */
155 public RealVector getCoefficients() {
156 return coefficients;
157 }
158
159 /**
160 * Gets the relationship between left and right hand sides.
161 *
162 * @return the relationship between left and right hand sides.
163 */
164 public Relationship getRelationship() {
165 return relationship;
166 }
167
168 /**
169 * Gets the value of the constraint (right hand side).
170 *
171 * @return the value of the constraint (right hand side).
172 */
173 public double getValue() {
174 return value;
175 }
176
177 /** {@inheritDoc} */
178 @Override
179 public boolean equals(Object other) {
180 if (this == other) {
181 return true;
182 }
183 if (other instanceof LinearConstraint) {
184 LinearConstraint rhs = (LinearConstraint) other;
185 return relationship == rhs.relationship &&
186 value == rhs.value &&
187 coefficients.equals(rhs.coefficients);
188 }
189 return false;
190 }
191
192 /** {@inheritDoc} */
193 @Override
194 public int hashCode() {
195 return relationship.hashCode() ^
196 Double.valueOf(value).hashCode() ^
197 coefficients.hashCode();
198 }
199 }