1 // Copyright 2010-2021 Google LLC 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package com.google.ortools.sat; 15 16 import com.google.ortools.sat.CpModelProto; 17 import com.google.ortools.sat.IntegerVariableProto; 18 import com.google.ortools.util.Domain; 19 20 /** An integer variable. */ 21 public final class IntVar implements Literal, LinearExpr { IntVar(CpModelProto.Builder builder, Domain domain, String name)22 IntVar(CpModelProto.Builder builder, Domain domain, String name) { 23 this.modelBuilder = builder; 24 this.variableIndex = modelBuilder.getVariablesCount(); 25 this.varBuilder = modelBuilder.addVariablesBuilder(); 26 this.varBuilder.setName(name); 27 for (long b : domain.flattenedIntervals()) { 28 this.varBuilder.addDomain(b); 29 } 30 this.negation_ = null; 31 } 32 IntVar(CpModelProto.Builder builder, int index)33 IntVar(CpModelProto.Builder builder, int index) { 34 this.modelBuilder = builder; 35 this.variableIndex = index; 36 this.varBuilder = modelBuilder.getVariablesBuilder(index); 37 this.negation_ = null; 38 } 39 40 @Override toString()41 public String toString() { 42 return varBuilder.toString(); 43 } 44 45 /** Returns the name of the variable given upon creation. */ getName()46 public String getName() { 47 return varBuilder.getName(); 48 } 49 50 /** Internal, returns the index of the variable in the underlying CpModelProto. */ 51 @Override getIndex()52 public int getIndex() { 53 return variableIndex; 54 } 55 56 /** Returns the variable protobuf builder. */ getBuilder()57 public IntegerVariableProto.Builder getBuilder() { 58 return varBuilder; 59 } 60 61 // LinearExpr interface. 62 @Override numElements()63 public int numElements() { 64 return 1; 65 } 66 67 @Override getVariable(int index)68 public IntVar getVariable(int index) { 69 assert (index == 0); 70 return this; 71 } 72 73 @Override getCoefficient(int index)74 public long getCoefficient(int index) { 75 assert (index == 0); 76 return 1; 77 } 78 79 @Override getOffset()80 public long getOffset() { 81 return 0; 82 } 83 84 /** Returns a short string describing the variable. */ 85 @Override getShortString()86 public String getShortString() { 87 if (varBuilder.getName().isEmpty()) { 88 if (varBuilder.getDomainCount() == 2 && varBuilder.getDomain(0) == varBuilder.getDomain(1)) { 89 return String.format("%d", varBuilder.getDomain(0)); 90 } else { 91 return String.format("var_%d(%s)", getIndex(), displayBounds()); 92 } 93 } else { 94 return String.format("%s(%s)", getName(), displayBounds()); 95 } 96 } 97 98 /** Returns the domain as a string without the enclosing []. */ displayBounds()99 public String displayBounds() { 100 String out = ""; 101 for (int i = 0; i < varBuilder.getDomainCount(); i += 2) { 102 if (i != 0) { 103 out += ", "; 104 } 105 if (varBuilder.getDomain(i) == varBuilder.getDomain(i + 1)) { 106 out += String.format("%d", varBuilder.getDomain(i)); 107 } else { 108 out += String.format("%d..%d", varBuilder.getDomain(i), varBuilder.getDomain(i + 1)); 109 } 110 } 111 return out; 112 } 113 114 /** Returns the negation of a boolean variable. */ 115 @Override not()116 public Literal not() { 117 if (negation_ == null) { 118 negation_ = new NotBooleanVariable(this); 119 } 120 return negation_; 121 } 122 123 /** Returns the domain of the variable. */ getDomain()124 public Domain getDomain() { 125 return CpSatHelper.variableDomain(varBuilder.build()); 126 } 127 128 private final CpModelProto.Builder modelBuilder; 129 private final int variableIndex; 130 private final IntegerVariableProto.Builder varBuilder; 131 private NotBooleanVariable negation_ = null; 132 } 133