com.inform.jamps.solver.gurobi.GurobiVariable.java Source code

Java tutorial

Introduction

Here is the source code for com.inform.jamps.solver.gurobi.GurobiVariable.java

Source

/*
 * Copyright (C) 2015 The Jamps Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package com.inform.jamps.solver.gurobi;

import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.math3.util.Precision;

import com.inform.jamps.modeling.Variable;
import com.inform.jamps.modeling.VariableType;

import gurobi.GRBVar;

public class GurobiVariable implements Variable {

    protected final static VariableType DEFAULT_VARIABLE_TYPE = VariableType.CONTINUOUS;

    private final static AtomicLong AUTO_NAME_COUNTER = new AtomicLong(0);

    private final GurobiProgram program;

    private final String name;

    private final VariableType type;

    private double lowerBound;

    private double upperBound;

    private Double initialValue;

    private transient GRBVar nativeVar;

    protected GurobiVariable(final GurobiProgram program) {
        this(program, DEFAULT_VARIABLE_TYPE);
    }

    protected GurobiVariable(final GurobiProgram program, final VariableType type) {
        this(program, "x" + AUTO_NAME_COUNTER.incrementAndGet(), type);
    }

    protected GurobiVariable(final GurobiProgram program, final String name, final VariableType type) {
        if (program == null) {
            throw new IllegalArgumentException("Parameter program is mandatory and may not be null");
        }
        if (name == null) {
            throw new IllegalArgumentException("Parameter name is mandatory and may not be null");
        }
        if (type == null) {
            throw new IllegalArgumentException("Parameter type is mandatory and may not be null");
        }

        this.program = program;
        this.name = name;
        this.type = type;

        if (type == VariableType.BINARY) {
            lowerBound = 0.0;
            upperBound = 1.0;
        } else {
            lowerBound = Double.NEGATIVE_INFINITY;
            upperBound = Double.POSITIVE_INFINITY;
        }
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public VariableType getType() {
        return type;
    }

    @Override
    public double getLowerBound() {
        return lowerBound;
    }

    @Override
    public void setLowerBound(final double lowerBound) {
        this.lowerBound = lowerBound;
    }

    @Override
    public double getUpperBound() {
        return upperBound;
    }

    @Override
    public void setUpperBound(final double upperBound) {
        this.upperBound = upperBound;
    }

    @Override
    public boolean hasInitialValue() {
        return initialValue != null;
    }

    @Override
    public double getInitialValue() {
        if (!hasInitialValue()) {
            throw new IllegalStateException("Variable has no initial value set");
        }
        return initialValue;
    }

    @Override
    public void setInitialValue(final double initialValue) {
        this.initialValue = initialValue;
    }

    protected GurobiProgram getProgram() {
        return program;
    }

    protected void setNativeVariable(final GRBVar grbVar) {
        if (grbVar == null) {
            throw new IllegalArgumentException("GRBVar parameter is mandatory and may not be null");
        }

        this.nativeVar = grbVar;
    }

    protected GRBVar getNativeVariable() {
        return nativeVar;
    }

    @Override
    public int compareTo(final Variable var) {
        if (!(var instanceof GurobiVariable)) {
            return -1;
        }

        int result = name.compareTo(var.getName());
        if (result != 0) {
            return result;
        }

        result = type.compareTo(var.getType());
        if (result != 0) {
            return result;
        }

        result = Double.compare(lowerBound, var.getLowerBound());
        if (result != 0) {
            return result;
        }

        return Double.compare(upperBound, var.getUpperBound());
    }

    @Override
    public final int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + name.hashCode();
        result = prime * result + type.hashCode();
        long temp;
        temp = Double.doubleToLongBits(lowerBound);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(upperBound);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public final boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof GurobiVariable)) {
            return false;
        }
        final GurobiVariable other = (GurobiVariable) obj;
        if (!name.equals(other.name)) {
            return false;
        }
        if (type != other.type) {
            return false;
        }
        if (Double.doubleToLongBits(lowerBound) != Double.doubleToLongBits(other.lowerBound)) {
            return false;
        }
        return Double.doubleToLongBits(upperBound) == Double.doubleToLongBits(other.upperBound);
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder(200);
        switch (type) {
        case BINARY:
            sb.append("Binary ");
            break;
        case CONTINUOUS:
            sb.append("Continuous ");
            break;
        case INTEGER:
            sb.append("Integer ");
            break;
        case SEMI_CONTINUOUS:
            sb.append("Semi-Continuous ");
            break;
        case SEMI_INTEGER:
            sb.append("Semi-Integer ");
            break;
        default:
            break;
        }
        sb.append(name);
        if (lowerBound > Double.NEGATIVE_INFINITY || upperBound < Double.POSITIVE_INFINITY) {
            if (Precision.equals(lowerBound, Double.NEGATIVE_INFINITY)) {
                sb.append(" (,");
            } else {
                sb.append(" [");
                sb.append(lowerBound);
                sb.append(',');
            }
            if (Precision.equals(upperBound, Double.POSITIVE_INFINITY)) {
                sb.append(')');
            } else {
                sb.append(' ');
                sb.append(upperBound);
                sb.append(']');
            }
        } else {
            sb.append(" (unbounded)");
        }
        return sb.toString();
    }
}