001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.math3.optim.linear; 018 019 import java.io.IOException; 020 import java.io.ObjectInputStream; 021 import java.io.ObjectOutputStream; 022 import java.io.Serializable; 023 import org.apache.commons.math3.linear.MatrixUtils; 024 import org.apache.commons.math3.linear.RealVector; 025 import org.apache.commons.math3.linear.ArrayRealVector; 026 027 /** 028 * A linear constraint for a linear optimization problem. 029 * <p> 030 * A linear constraint has one of the forms: 031 * <ul> 032 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> 033 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> 034 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> 035 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = 036 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 037 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= 038 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 039 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= 040 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 041 * </ul> 042 * 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> 043 * are the coordinates of the current point and v is the value of the constraint. 044 * </p> 045 * 046 * @version $Id: LinearConstraint.java 1416643 2012-12-03 19:37:14Z tn $ 047 * @since 2.0 048 */ 049 public class LinearConstraint implements Serializable { 050 /** Serializable version identifier. */ 051 private static final long serialVersionUID = -764632794033034092L; 052 /** Coefficients of the constraint (left hand side). */ 053 private final transient RealVector coefficients; 054 /** Relationship between left and right hand sides (=, <=, >=). */ 055 private final Relationship relationship; 056 /** Value of the constraint (right hand side). */ 057 private final double value; 058 059 /** 060 * Build a constraint involving a single linear equation. 061 * <p> 062 * A linear constraint with a single linear equation has one of the forms: 063 * <ul> 064 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> 065 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> 066 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> 067 * </ul> 068 * </p> 069 * @param coefficients The coefficients of the constraint (left hand side) 070 * @param relationship The type of (in)equality used in the constraint 071 * @param value The value of the constraint (right hand side) 072 */ 073 public LinearConstraint(final double[] coefficients, 074 final Relationship relationship, 075 final double value) { 076 this(new ArrayRealVector(coefficients), relationship, value); 077 } 078 079 /** 080 * Build a constraint involving a single linear equation. 081 * <p> 082 * A linear constraint with a single linear equation has one of the forms: 083 * <ul> 084 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> 085 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> 086 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> 087 * </ul> 088 * </p> 089 * @param coefficients The coefficients of the constraint (left hand side) 090 * @param relationship The type of (in)equality used in the constraint 091 * @param value The value of the constraint (right hand side) 092 */ 093 public LinearConstraint(final RealVector coefficients, 094 final Relationship relationship, 095 final double value) { 096 this.coefficients = coefficients; 097 this.relationship = relationship; 098 this.value = value; 099 } 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 }