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