001    package net.sf.cpsolver.ifs.example.rpp;
002    
003    import java.util.ArrayList;
004    
005    import 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 Tomas Muller<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     */
032    public 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    }