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 */ 017package org.apache.commons.math3.optim.linear; 018 019import java.io.IOException; 020import java.io.ObjectInputStream; 021import java.io.ObjectOutputStream; 022import java.io.Serializable; 023import org.apache.commons.math3.linear.MatrixUtils; 024import org.apache.commons.math3.linear.RealVector; 025import 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 * @since 2.0 047 */ 048public class LinearConstraint implements Serializable { 049 /** Serializable version identifier. */ 050 private static final long serialVersionUID = -764632794033034092L; 051 /** Coefficients of the constraint (left hand side). */ 052 private final transient RealVector coefficients; 053 /** Relationship between left and right hand sides (=, <=, >=). */ 054 private final Relationship relationship; 055 /** Value of the constraint (right hand side). */ 056 private final double value; 057 058 /** 059 * Build a constraint involving a single linear equation. 060 * <p> 061 * A linear constraint with a single linear equation has one of the forms: 062 * <ul> 063 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> 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 * </ul> 067 * </p> 068 * @param coefficients The coefficients of the constraint (left hand side) 069 * @param relationship The type of (in)equality used in the constraint 070 * @param value The value of the constraint (right hand side) 071 */ 072 public LinearConstraint(final double[] coefficients, 073 final Relationship relationship, 074 final double value) { 075 this(new ArrayRealVector(coefficients), relationship, value); 076 } 077 078 /** 079 * Build a constraint involving a single linear equation. 080 * <p> 081 * A linear constraint with a single linear equation has one of the forms: 082 * <ul> 083 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> 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 * </ul> 087 * </p> 088 * @param coefficients The coefficients of the constraint (left hand side) 089 * @param relationship The type of (in)equality used in the constraint 090 * @param value The value of the constraint (right hand side) 091 */ 092 public LinearConstraint(final RealVector coefficients, 093 final Relationship relationship, 094 final double value) { 095 this.coefficients = coefficients; 096 this.relationship = relationship; 097 this.value = value; 098 } 099 100 /** 101 * Build a constraint involving two linear equations. 102 * <p> 103 * A linear constraint with two linear equation has one of the forms: 104 * <ul> 105 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = 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> <= 108 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 109 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= 110 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 111 * </ul> 112 * </p> 113 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint 114 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint 115 * @param relationship The type of (in)equality used in the constraint 116 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint 117 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint 118 */ 119 public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant, 120 final Relationship relationship, 121 final double[] rhsCoefficients, final double rhsConstant) { 122 double[] sub = new double[lhsCoefficients.length]; 123 for (int i = 0; i < sub.length; ++i) { 124 sub[i] = lhsCoefficients[i] - rhsCoefficients[i]; 125 } 126 this.coefficients = new ArrayRealVector(sub, false); 127 this.relationship = relationship; 128 this.value = rhsConstant - lhsConstant; 129 } 130 131 /** 132 * Build a constraint involving two linear equations. 133 * <p> 134 * A linear constraint with two linear equation has one of the forms: 135 * <ul> 136 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = 137 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 138 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= 139 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 140 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= 141 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 142 * </ul> 143 * </p> 144 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint 145 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint 146 * @param relationship The type of (in)equality used in the constraint 147 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint 148 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint 149 */ 150 public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant, 151 final Relationship relationship, 152 final RealVector rhsCoefficients, final double rhsConstant) { 153 this.coefficients = lhsCoefficients.subtract(rhsCoefficients); 154 this.relationship = relationship; 155 this.value = rhsConstant - lhsConstant; 156 } 157 158 /** 159 * Gets the coefficients of the constraint (left hand side). 160 * 161 * @return the coefficients of the constraint (left hand side). 162 */ 163 public RealVector getCoefficients() { 164 return coefficients; 165 } 166 167 /** 168 * Gets the relationship between left and right hand sides. 169 * 170 * @return the relationship between left and right hand sides. 171 */ 172 public Relationship getRelationship() { 173 return relationship; 174 } 175 176 /** 177 * Gets the value of the constraint (right hand side). 178 * 179 * @return the value of the constraint (right hand side). 180 */ 181 public double getValue() { 182 return value; 183 } 184 185 /** {@inheritDoc} */ 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 /** {@inheritDoc} */ 201 @Override 202 public int hashCode() { 203 return relationship.hashCode() ^ 204 Double.valueOf(value).hashCode() ^ 205 coefficients.hashCode(); 206 } 207 208 /** 209 * Serialize the instance. 210 * @param oos stream where object should be written 211 * @throws IOException if object cannot be written to stream 212 */ 213 private void writeObject(ObjectOutputStream oos) 214 throws IOException { 215 oos.defaultWriteObject(); 216 MatrixUtils.serializeRealVector(coefficients, oos); 217 } 218 219 /** 220 * Deserialize the instance. 221 * @param ois stream from which the object should be read 222 * @throws ClassNotFoundException if a class in the stream cannot be found 223 * @throws IOException if object cannot be read from the stream 224 */ 225 private void readObject(ObjectInputStream ois) 226 throws ClassNotFoundException, IOException { 227 ois.defaultReadObject(); 228 MatrixUtils.deserializeRealVector(this, "coefficients", ois); 229 } 230}