Home | History | Annotate | Download | only in linear
      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> &lt;= 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> &lt;=
     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: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $
     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 (=, &lt;=, >=). */
     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> &lt;= 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> &lt;= 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> &lt;=
    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> &lt;=
    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 instanceof LinearConstraint) {
    196           LinearConstraint rhs = (LinearConstraint) other;
    197           return (relationship == rhs.relationship) &&
    198                  (value        == rhs.value) &&
    199                  coefficients.equals(rhs.coefficients);
    200       }
    201       return false;
    202     }
    203 
    204     /** {@inheritDoc} */
    205     @Override
    206     public int hashCode() {
    207         return relationship.hashCode() ^
    208                Double.valueOf(value).hashCode() ^
    209                coefficients.hashCode();
    210     }
    211 
    212     /** Serialize the instance.
    213      * @param oos stream where object should be written
    214      * @throws IOException if object cannot be written to stream
    215      */
    216     private void writeObject(ObjectOutputStream oos)
    217         throws IOException {
    218         oos.defaultWriteObject();
    219         MatrixUtils.serializeRealVector(coefficients, oos);
    220     }
    221 
    222     /** Deserialize the instance.
    223      * @param ois stream from which the object should be read
    224      * @throws ClassNotFoundException if a class in the stream cannot be found
    225      * @throws IOException if object cannot be read from the stream
    226      */
    227     private void readObject(ObjectInputStream ois)
    228       throws ClassNotFoundException, IOException {
    229         ois.defaultReadObject();
    230         MatrixUtils.deserializeRealVector(this, "coefficients", ois);
    231     }
    232 
    233 }
    234