View Javadoc
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    *      https://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  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.optim.linear;
23  
24  import java.io.IOException;
25  import java.io.ObjectInputStream;
26  import java.io.ObjectOutputStream;
27  import java.io.Serializable;
28  
29  import org.hipparchus.linear.ArrayRealVector;
30  import org.hipparchus.linear.RealVector;
31  
32  /**
33   * A linear constraint for a linear optimization problem.
34   * <p>* A linear constraint has one of the forms:</p>
35   * <ul>
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> &lt;= v</li>
38   *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= v</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   *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
42   *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
43   *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &gt;=
44   *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
45   * </ul>
46   * <p>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>
47   * are the coordinates of the current point and v is the value of the constraint.
48   * </p>
49   *
50   */
51  public class LinearConstraint implements Serializable {
52      /** Serializable version identifier. */
53      private static final long serialVersionUID = -764632794033034092L;
54      /** Coefficients of the constraint (left hand side). */
55      private final transient RealVector coefficients;
56      /** Relationship between left and right hand sides (=, &lt;=, &gt;=). */
57      private final Relationship relationship;
58      /** Value of the constraint (right hand side). */
59      private final double value;
60  
61      /**
62       * Build a constraint involving a single linear equation.
63       * <p>A linear constraint with a single linear equation has one of the forms:</p>
64       * <ul>
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> &lt;= v</li>
67       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= v</li>
68       * </ul>
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>A linear constraint with a single linear equation has one of the forms:</p>
82       * <ul>
83       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
84       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
85       *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= v</li>
86       * </ul>
87       * @param coefficients The coefficients of the constraint (left hand side)
88       * @param relationship The type of (in)equality used in the constraint
89       * @param value The value of the constraint (right hand side)
90       */
91      public LinearConstraint(final RealVector coefficients,
92                              final Relationship relationship,
93                              final double value) {
94          this.coefficients = coefficients;
95          this.relationship = relationship;
96          this.value        = value;
97      }
98  
99      /**
100      * Build a constraint involving two linear equations.
101      * <p>A linear constraint with two linear equation has one of the forms:</p>
102      * <ul>
103      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
104      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
105      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
106      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
107      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &gt;=
108      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
109      * </ul>
110      * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
111      * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
112      * @param relationship The type of (in)equality used in the constraint
113      * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
114      * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
115      */
116     public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant,
117                             final Relationship relationship,
118                             final double[] rhsCoefficients, final double rhsConstant) {
119         double[] sub = new double[lhsCoefficients.length];
120         for (int i = 0; i < sub.length; ++i) {
121             sub[i] = lhsCoefficients[i] - rhsCoefficients[i];
122         }
123         this.coefficients = new ArrayRealVector(sub, false);
124         this.relationship = relationship;
125         this.value        = rhsConstant - lhsConstant;
126     }
127 
128     /**
129      * Build a constraint involving two linear equations.
130      * <p>A linear constraint with two linear equation has one of the forms:</p>
131      * <ul>
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      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
135      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
136      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &gt;=
137      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
138      * </ul>
139      * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
140      * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
141      * @param relationship The type of (in)equality used in the constraint
142      * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
143      * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
144      */
145     public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant,
146                             final Relationship relationship,
147                             final RealVector rhsCoefficients, final double rhsConstant) {
148         this.coefficients = lhsCoefficients.subtract(rhsCoefficients);
149         this.relationship = relationship;
150         this.value        = rhsConstant - lhsConstant;
151     }
152 
153     /**
154      * Gets the coefficients of the constraint (left hand side).
155      *
156      * @return the coefficients of the constraint (left hand side).
157      */
158     public RealVector getCoefficients() {
159         return coefficients;
160     }
161 
162     /**
163      * Gets the relationship between left and right hand sides.
164      *
165      * @return the relationship between left and right hand sides.
166      */
167     public Relationship getRelationship() {
168         return relationship;
169     }
170 
171     /**
172      * Gets the value of the constraint (right hand side).
173      *
174      * @return the value of the constraint (right hand side).
175      */
176     public double getValue() {
177         return value;
178     }
179 
180     /** {@inheritDoc} */
181     @Override
182     public boolean equals(Object other) {
183         if (this == other) {
184             return true;
185         }
186         if (other instanceof LinearConstraint) {
187             LinearConstraint rhs = (LinearConstraint) other;
188             return relationship == rhs.relationship &&
189                 value == rhs.value &&
190                 coefficients.equals(rhs.coefficients);
191         }
192         return false;
193     }
194 
195     /** {@inheritDoc} */
196     @Override
197     public int hashCode() {
198         return relationship.hashCode() ^
199             Double.valueOf(value).hashCode() ^
200             coefficients.hashCode();
201     }
202 
203     /**
204      * Serialize the instance.
205      * @param oos stream where object should be written
206      * @throws IOException if object cannot be written to stream
207      */
208     private void writeObject(ObjectOutputStream oos)
209         throws IOException {
210         oos.defaultWriteObject();
211         final int n = coefficients.getDimension();
212         oos.writeInt(n);
213         for (int i = 0; i < n; ++i) {
214             oos.writeDouble(coefficients.getEntry(i));
215         }
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 
228         // read the vector data
229         final int n = ois.readInt();
230         final double[] data = new double[n];
231         for (int i = 0; i < n; ++i) {
232             data[i] = ois.readDouble();
233         }
234 
235         try {
236             // create the instance
237             ArrayRealVector vector = new ArrayRealVector(data, false);
238             final java.lang.reflect.Field f = getClass().getDeclaredField("coefficients");
239             f.setAccessible(true); // NOPMD
240             f.set(this, vector);
241         } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
242             IOException ioe = new IOException();
243             ioe.initCause(e);
244             throw ioe;
245         }
246 
247     }
248 }