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.math4.legacy.optim.linear; 018 019import org.apache.commons.math4.legacy.linear.ArrayRealVector; 020import org.apache.commons.math4.legacy.linear.RealVector; 021 022/** 023 * A linear constraint for a linear optimization problem. 024 * <p> 025 * A linear constraint has one of the forms: 026 * <ul> 027 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> 028 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> 029 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> 030 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = 031 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 032 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= 033 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 034 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= 035 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 036 * </ul> 037 * 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> 038 * are the coordinates of the current point and v is the value of the constraint. 039 * 040 * @since 2.0 041 */ 042public class LinearConstraint { 043 /** Coefficients of the constraint (left hand side). */ 044 private final RealVector coefficients; 045 /** Relationship between left and right hand sides {@code (=, <=, >=)}. */ 046 private final Relationship relationship; 047 /** Value of the constraint (right hand side). */ 048 private final double value; 049 050 /** 051 * Build a constraint involving a single linear equation. 052 * <p> 053 * A linear constraint with a single linear equation has one of the forms: 054 * <ul> 055 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> 056 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> 057 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> 058 * </ul> 059 * 060 * @param coefficients The coefficients of the constraint (left hand side) 061 * @param relationship The type of (in)equality used in the constraint 062 * @param value The value of the constraint (right hand side) 063 */ 064 public LinearConstraint(final double[] coefficients, 065 final Relationship relationship, 066 final double value) { 067 this(new ArrayRealVector(coefficients), relationship, value); 068 } 069 070 /** 071 * Build a constraint involving a single linear equation. 072 * <p> 073 * A linear constraint with a single linear equation has one of the forms: 074 * <ul> 075 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> 076 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> 077 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> 078 * </ul> 079 * 080 * @param coefficients The coefficients of the constraint (left hand side) 081 * @param relationship The type of (in)equality used in the constraint 082 * @param value The value of the constraint (right hand side) 083 */ 084 public LinearConstraint(final RealVector coefficients, 085 final Relationship relationship, 086 final double value) { 087 this.coefficients = coefficients; 088 this.relationship = relationship; 089 this.value = value; 090 } 091 092 /** 093 * Build a constraint involving two linear equations. 094 * <p> 095 * A linear constraint with two linear equation has one of the forms: 096 * <ul> 097 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = 098 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 099 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= 100 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 101 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= 102 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 103 * </ul> 104 * 105 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint 106 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint 107 * @param relationship The type of (in)equality used in the constraint 108 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint 109 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint 110 */ 111 public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant, 112 final Relationship relationship, 113 final double[] rhsCoefficients, final double rhsConstant) { 114 double[] sub = new double[lhsCoefficients.length]; 115 for (int i = 0; i < sub.length; ++i) { 116 sub[i] = lhsCoefficients[i] - rhsCoefficients[i]; 117 } 118 this.coefficients = new ArrayRealVector(sub, false); 119 this.relationship = relationship; 120 this.value = rhsConstant - lhsConstant; 121 } 122 123 /** 124 * Build a constraint involving two linear equations. 125 * <p> 126 * A linear constraint with two linear equation has one of the forms: 127 * <ul> 128 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = 129 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 130 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= 131 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> 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 * </ul> 135 * 136 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint 137 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint 138 * @param relationship The type of (in)equality used in the constraint 139 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint 140 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint 141 */ 142 public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant, 143 final Relationship relationship, 144 final RealVector rhsCoefficients, final double rhsConstant) { 145 this.coefficients = lhsCoefficients.subtract(rhsCoefficients); 146 this.relationship = relationship; 147 this.value = rhsConstant - lhsConstant; 148 } 149 150 /** 151 * Gets the coefficients of the constraint (left hand side). 152 * 153 * @return the coefficients of the constraint (left hand side). 154 */ 155 public RealVector getCoefficients() { 156 return coefficients; 157 } 158 159 /** 160 * Gets the relationship between left and right hand sides. 161 * 162 * @return the relationship between left and right hand sides. 163 */ 164 public Relationship getRelationship() { 165 return relationship; 166 } 167 168 /** 169 * Gets the value of the constraint (right hand side). 170 * 171 * @return the value of the constraint (right hand side). 172 */ 173 public double getValue() { 174 return value; 175 } 176 177 /** {@inheritDoc} */ 178 @Override 179 public boolean equals(Object other) { 180 if (this == other) { 181 return true; 182 } 183 if (other instanceof LinearConstraint) { 184 LinearConstraint rhs = (LinearConstraint) other; 185 return relationship == rhs.relationship && 186 value == rhs.value && 187 coefficients.equals(rhs.coefficients); 188 } 189 return false; 190 } 191 192 /** {@inheritDoc} */ 193 @Override 194 public int hashCode() { 195 return relationship.hashCode() ^ 196 Double.valueOf(value).hashCode() ^ 197 coefficients.hashCode(); 198 } 199}