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}