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