All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.oliviercailloux.jlp.elements.Constraint Maven / Gradle / Ivy

Go to download

Java Linear Programming: specify and solve linear programs in object-oriented fashion.

The newest version!
package io.github.oliviercailloux.jlp.elements;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

import java.util.Objects;

import com.google.common.base.MoreObjects;

/**
 * 

* A constraint in a linear program, or mixed linear program, consisting of a * linear expression on the left hand side (lhs) and a constant on the right * hand side (rhs), and an equality or inequality sign (as a * {@link ComparisonOperator}) in between. *

*

* A constraint has a description. It is recommended for clarity (but not * mandatory) to use descriptions that identify with no ambiguity one * constraint. Thus, two constraints should be equal, as judged per * {@link #equals(Object)}, iff they have the same descriptions. (This object * guarantees anyway that equality implies same description, the other direction * is up to the user.) *

*

* A constraint {@link #equals(Object)} an other constraint iff they have the * same description, left hand side, operator, and right hand side. *

*

* Objects of this class are immutable (provided variables are). *

*

* Rationale for equality: we want to allow that the user does not use * descriptions, by choosing (for example) an empty description for every * constraints. Hence, equality has to rely on the rest of the attributes at * least. But we also want to permit for the following case. Constraint * “structural x”: x < y. Constraint “conjonctural x”: x < y. The second * constraint might be perceived as different than the first one, and the user * might genuinely want both of them to appear in the MP, because the second * constraint might have a general form x < C×y, with a value C depending on * some data of the problem, with C=1 being one possibility. In such a case, * only the description would permit to distinguish both constraints. *

* * @author Olivier Cailloux * */ public class Constraint { static public Constraint of(String descr, SumTerms lhs, ComparisonOperator op, double rhs) { return new Constraint(descr, lhs, op, rhs); } /** * Not null. */ private final String descr; private final SumTerms lhs; private final ComparisonOperator op; private final double rhs; /** * @param description * not null. * @param lhs * not null, not empty. * @param op * not null. * @param rhs * a finite number. */ private Constraint(String description, SumTerms lhs, ComparisonOperator op, double rhs) { this.descr = requireNonNull(description); checkArgument(lhs.size() >= 1); this.lhs = requireNonNull(lhs); this.op = requireNonNull(op); checkArgument(Double.isFinite(rhs)); this.rhs = rhs; } /** * Returns true iff the given object is also a constraint and has * same description, left hand side, operator, and right hand side as this * object. */ @Override public boolean equals(Object obj) { if (!(obj instanceof Constraint)) { return false; } final Constraint c2 = (Constraint) obj; if (c2 == this) { return true; } return descr.equals(c2.descr) && lhs.equals(c2.lhs) && op.equals(c2.op) && rhs == c2.rhs; } /** * Retrieves the constraint description. * * @return not null. */ public String getDescription() { return descr; } /** * @return not null, not empty. */ public SumTerms getLhs() { return lhs; } /** * @return the op */ public ComparisonOperator getOperator() { return op; } /** * @return the rhs */ public double getRhs() { return rhs; } @Override public int hashCode() { return Objects.hash(descr, lhs, op, rhs); } /** * Returns a string representation of this constraint (useful for debug). * */ @Override public String toString() { final String expr = lhs + " " + op + " " + rhs; return MoreObjects.toStringHelper(this).add("description", descr).add("expression", expr).toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy