001package org.cpsolver.ifs.example.rpp; 002 003import java.util.ArrayList; 004 005import org.cpsolver.ifs.model.Variable; 006 007 008 009/** 010 * Rectangle (variable). It encodes the name, width and height of the rectangle, 011 * minimal and maximal position of the rectangle. It also contains an 012 * information about prohibited X and Y coordinate (for MPP). 013 * 014 * @version IFS 1.3 (Iterative Forward Search)<br> 015 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 016 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 017 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 018 * <br> 019 * This library is free software; you can redistribute it and/or modify 020 * it under the terms of the GNU Lesser General Public License as 021 * published by the Free Software Foundation; either version 3 of the 022 * License, or (at your option) any later version. <br> 023 * <br> 024 * This library is distributed in the hope that it will be useful, but 025 * WITHOUT ANY WARRANTY; without even the implied warranty of 026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 027 * Lesser General Public License for more details. <br> 028 * <br> 029 * You should have received a copy of the GNU Lesser General Public 030 * License along with this library; if not see 031 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 032 */ 033public class Rectangle extends Variable<Rectangle, Location> { 034 private String iName; 035 private int iMinX, iMaxX, iMinY, iMaxY; 036 private int iHeight, iWidth; 037 private int iProhibitedX = -1, iProhibitedY = -1; 038 039 /** 040 * Constructor. 041 * 042 * @param name 043 * variable's name 044 * @param width 045 * width of the rectangle 046 * @param height 047 * height of the rectangle 048 * @param minX 049 * minimal X-coordinate 050 * @param maxX 051 * maximal X-coordinate 052 * @param minY 053 * minimal Y-coordinate 054 * @param maxY 055 * maximal Y-coordinate 056 * @param initialLocation 057 * initial location (null if none) 058 */ 059 public Rectangle(String name, int width, int height, int minX, int maxX, int minY, int maxY, 060 Location initialLocation) { 061 super(initialLocation); 062 iName = name; 063 iWidth = width; 064 iHeight = height; 065 iMinX = minX; 066 iMaxX = maxX; 067 iMinY = minY; 068 iMaxY = maxY; 069 setValues(computeValues()); 070 } 071 072 /** 073 * Prohibits given X and Y coordinates (for MPP). 074 * @param x X coordinate 075 * @param y Y coordinate 076 */ 077 public void setProhibited(int x, int y) { 078 iProhibitedX = x; 079 iProhibitedY = y; 080 setValues(computeValues()); 081 if (getInitialAssignment() != null && !values(null).contains(getInitialAssignment())) 082 setInitialAssignment(null); 083 } 084 085 /** 086 * Prohibits given initial location (for MPP). 087 */ 088 public void setProhibited() { 089 if (getInitialAssignment() == null) 090 return; 091 setProhibited((getInitialAssignment()).getX(), (getInitialAssignment()).getY()); 092 } 093 094 /** 095 * Returns true if the given location is prohibited. This means that either 096 * X or Y equals to the prohibited X or Y coordinate respectively. 097 * @param x X coordinate 098 * @param y Y coordinate 099 * @return true if the given location is prohibited 100 */ 101 public boolean isProhibited(int x, int y) { 102 return (iProhibitedX == x || iProhibitedY == y); 103 } 104 105 public int getProhibitedX() { 106 return iProhibitedX; 107 } 108 109 public int getProhibitedY() { 110 return iProhibitedY; 111 } 112 113 public int getMinX() { 114 return iMinX; 115 } 116 117 public int getMaxX() { 118 return iMaxX; 119 } 120 121 public int getMinY() { 122 return iMinY; 123 } 124 125 public int getMaxY() { 126 return iMaxY; 127 } 128 129 /** Returns width of the rectangle 130 * @return width of the rectangle 131 **/ 132 public int getWidth() { 133 return iWidth; 134 } 135 136 /** Returns height of the rectangle 137 * @return height of the rectangle 138 **/ 139 public int getHeight() { 140 return iHeight; 141 } 142 143 /** Returns name of the rectangle */ 144 @Override 145 public String getName() { 146 return iName; 147 } 148 149 /** Set the bounds (minimal and maximal values of X and Y coordinates). 150 * @param minX X minimum 151 * @param maxX X maximum 152 * @param minY Y minimum 153 * @param maxY Y maximum 154 **/ 155 public void setBounds(int minX, int maxX, int minY, int maxY) { 156 iMinX = minX; 157 iMaxX = maxX; 158 iMinY = minY; 159 iMaxY = maxY; 160 if (getInitialAssignment() != null && !values(null).contains(getInitialAssignment())) 161 setInitialAssignment(null); 162 } 163 164 private ArrayList<Location> computeValues() { 165 ArrayList<Location> locations = new ArrayList<Location>((iMaxX - iMinX) * (iMaxY - iMinY)); 166 for (int x = iMinX; x <= iMaxX; x++) { 167 for (int y = iMinY; y <= iMaxY; y++) { 168 if (!isProhibited(x, y)) { 169 Location val = new Location(this, x, y); 170 locations.add(val); 171 if (getInitialAssignment() != null && getInitialAssignment().equals(val)) 172 setInitialAssignment(val); 173 if (getBestAssignment() != null && getBestAssignment().equals(val)) 174 setBestAssignment(val, 0l); 175 } 176 } 177 } 178 return locations; 179 } 180 181 /** String representation (for printing and debugging purposes) */ 182 @Override 183 public String toString() { 184 return "Rectangle{name='" + getName() + "', size=[" + getWidth() + "," + getHeight() + "], bounds=[" + iMinX 185 + ".." + iMaxX + "," + iMinY + ".." + iMaxY + "], super=" + super.toString() + "}"; 186 } 187 188 /** Compares two rectangles (based on rectangle names) */ 189 @Override 190 public boolean equals(Object o) { 191 return ((Rectangle) o).getName().equals(getName()); 192 } 193}