LinearConstraint.java

  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.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.optim.linear;

  22. import java.io.IOException;
  23. import java.io.ObjectInputStream;
  24. import java.io.ObjectOutputStream;
  25. import java.io.Serializable;

  26. import org.hipparchus.linear.ArrayRealVector;
  27. import org.hipparchus.linear.RealVector;

  28. /**
  29.  * A linear constraint for a linear optimization problem.
  30.  * <p>* A linear constraint has one of the forms:</p>
  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> &lt;= v</li>
  34.  *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= 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> &lt;=
  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> &gt;=
  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.  * <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>
  43.  * are the coordinates of the current point and v is the value of the constraint.
  44.  * </p>
  45.  *
  46.  */
  47. public class LinearConstraint implements Serializable {
  48.     /** Serializable version identifier. */
  49.     private static final long serialVersionUID = -764632794033034092L;
  50.     /** Coefficients of the constraint (left hand side). */
  51.     private final transient RealVector coefficients;
  52.     /** Relationship between left and right hand sides (=, &lt;=, &gt;=). */
  53.     private final Relationship relationship;
  54.     /** Value of the constraint (right hand side). */
  55.     private final double value;

  56.     /**
  57.      * Build a constraint involving a single linear equation.
  58.      * <p>A linear constraint with a single linear equation has one of the forms:</p>
  59.      * <ul>
  60.      *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
  61.      *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
  62.      *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= v</li>
  63.      * </ul>
  64.      * @param coefficients The coefficients of the constraint (left hand side)
  65.      * @param relationship The type of (in)equality used in the constraint
  66.      * @param value The value of the constraint (right hand side)
  67.      */
  68.     public LinearConstraint(final double[] coefficients,
  69.                             final Relationship relationship,
  70.                             final double value) {
  71.         this(new ArrayRealVector(coefficients), relationship, value);
  72.     }

  73.     /**
  74.      * Build a constraint involving a single linear equation.
  75.      * <p>A linear constraint with a single linear equation has one of the forms:</p>
  76.      * <ul>
  77.      *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
  78.      *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
  79.      *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &gt;= v</li>
  80.      * </ul>
  81.      * @param coefficients The coefficients of the constraint (left hand side)
  82.      * @param relationship The type of (in)equality used in the constraint
  83.      * @param value The value of the constraint (right hand side)
  84.      */
  85.     public LinearConstraint(final RealVector coefficients,
  86.                             final Relationship relationship,
  87.                             final double value) {
  88.         this.coefficients = coefficients;
  89.         this.relationship = relationship;
  90.         this.value        = value;
  91.     }

  92.     /**
  93.      * Build a constraint involving two linear equations.
  94.      * <p>A linear constraint with two linear equation has one of the forms:</p>
  95.      * <ul>
  96.      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
  97.      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
  98.      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
  99.      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
  100.      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &gt;=
  101.      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
  102.      * </ul>
  103.      * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
  104.      * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
  105.      * @param relationship The type of (in)equality used in the constraint
  106.      * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
  107.      * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
  108.      */
  109.     public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant,
  110.                             final Relationship relationship,
  111.                             final double[] rhsCoefficients, final double rhsConstant) {
  112.         double[] sub = new double[lhsCoefficients.length];
  113.         for (int i = 0; i < sub.length; ++i) {
  114.             sub[i] = lhsCoefficients[i] - rhsCoefficients[i];
  115.         }
  116.         this.coefficients = new ArrayRealVector(sub, false);
  117.         this.relationship = relationship;
  118.         this.value        = rhsConstant - lhsConstant;
  119.     }

  120.     /**
  121.      * Build a constraint involving two linear equations.
  122.      * <p>A linear constraint with two linear equation has one of the forms:</p>
  123.      * <ul>
  124.      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
  125.      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
  126.      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
  127.      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
  128.      *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &gt;=
  129.      *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
  130.      * </ul>
  131.      * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
  132.      * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
  133.      * @param relationship The type of (in)equality used in the constraint
  134.      * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
  135.      * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
  136.      */
  137.     public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant,
  138.                             final Relationship relationship,
  139.                             final RealVector rhsCoefficients, final double rhsConstant) {
  140.         this.coefficients = lhsCoefficients.subtract(rhsCoefficients);
  141.         this.relationship = relationship;
  142.         this.value        = rhsConstant - lhsConstant;
  143.     }

  144.     /**
  145.      * Gets the coefficients of the constraint (left hand side).
  146.      *
  147.      * @return the coefficients of the constraint (left hand side).
  148.      */
  149.     public RealVector getCoefficients() {
  150.         return coefficients;
  151.     }

  152.     /**
  153.      * Gets the relationship between left and right hand sides.
  154.      *
  155.      * @return the relationship between left and right hand sides.
  156.      */
  157.     public Relationship getRelationship() {
  158.         return relationship;
  159.     }

  160.     /**
  161.      * Gets the value of the constraint (right hand side).
  162.      *
  163.      * @return the value of the constraint (right hand side).
  164.      */
  165.     public double getValue() {
  166.         return value;
  167.     }

  168.     /** {@inheritDoc} */
  169.     @Override
  170.     public boolean equals(Object other) {
  171.         if (this == other) {
  172.             return true;
  173.         }
  174.         if (other instanceof LinearConstraint) {
  175.             LinearConstraint rhs = (LinearConstraint) other;
  176.             return relationship == rhs.relationship &&
  177.                 value == rhs.value &&
  178.                 coefficients.equals(rhs.coefficients);
  179.         }
  180.         return false;
  181.     }

  182.     /** {@inheritDoc} */
  183.     @Override
  184.     public int hashCode() {
  185.         return relationship.hashCode() ^
  186.             Double.valueOf(value).hashCode() ^
  187.             coefficients.hashCode();
  188.     }

  189.     /**
  190.      * Serialize the instance.
  191.      * @param oos stream where object should be written
  192.      * @throws IOException if object cannot be written to stream
  193.      */
  194.     private void writeObject(ObjectOutputStream oos)
  195.         throws IOException {
  196.         oos.defaultWriteObject();
  197.         final int n = coefficients.getDimension();
  198.         oos.writeInt(n);
  199.         for (int i = 0; i < n; ++i) {
  200.             oos.writeDouble(coefficients.getEntry(i));
  201.         }
  202.     }

  203.     /**
  204.      * Deserialize the instance.
  205.      * @param ois stream from which the object should be read
  206.      * @throws ClassNotFoundException if a class in the stream cannot be found
  207.      * @throws IOException if object cannot be read from the stream
  208.      */
  209.     private void readObject(ObjectInputStream ois)
  210.       throws ClassNotFoundException, IOException {
  211.         ois.defaultReadObject();

  212.         // read the vector data
  213.         final int n = ois.readInt();
  214.         final double[] data = new double[n];
  215.         for (int i = 0; i < n; ++i) {
  216.             data[i] = ois.readDouble();
  217.         }

  218.         try {
  219.             // create the instance
  220.             ArrayRealVector vector = new ArrayRealVector(data, false);
  221.             final java.lang.reflect.Field f = getClass().getDeclaredField("coefficients");
  222.             f.setAccessible(true); // NOPMD
  223.             f.set(this, vector);
  224.         } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
  225.             IOException ioe = new IOException();
  226.             ioe.initCause(e);
  227.             throw ioe;
  228.         }

  229.     }
  230. }