001    package net.sf.cpsolver.ifs.example.rpp;
002    
003    import java.util.*;
004    
005    import net.sf.cpsolver.ifs.model.*;
006    import net.sf.cpsolver.ifs.util.*;
007    
008    /**
009     * Rectangle (variable). 
010     * It encodes the name, width and height of the rectangle, minimal and maximal position of the rectangle.
011     * It also contains an information about prohibited X and Y coordinate (for MPP).
012     * 
013     * @version
014     * IFS 1.1 (Iterative Forward Search)<br>
015     * Copyright (C) 2006 Tomáš Müller<br>
016     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
017     * Lazenska 391, 76314 Zlin, Czech Republic<br>
018     * <br>
019     * This library is free software; you can redistribute it and/or
020     * modify it under the terms of the GNU Lesser General Public
021     * License as published by the Free Software Foundation; either
022     * version 2.1 of the License, or (at your option) any later version.
023     * <br><br>
024     * This library is distributed in the hope that it will be useful,
025     * but 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.
028     * <br><br>
029     * You should have received a copy of the GNU Lesser General Public
030     * License along with this library; if not, write to the Free Software
031     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
032     */
033    public class Rectangle extends Variable {
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         * @param name variable's name
042         * @param width width of the rectangle
043         * @param height height of the rectangle
044         * @param minX minimal X-coordinate
045         * @param maxX maximal X-coordinate
046         * @param minY minimal Y-coordinate
047         * @param maxY maximal Y-coordinate
048         * @param initialLocation initial location (null if none)
049         */
050        public Rectangle(String name, int width, int height, int minX, int maxX, int minY, int maxY,Location initialLocation) {
051            super(initialLocation);
052            iName = name;
053            iWidth = width;
054            iHeight = height;
055            iMinX = minX;
056            iMaxX = maxX;
057            iMinY = minY;
058            iMaxY = maxY;
059            setValues(computeValues());
060        }
061        
062        /**
063         * Prohibits given X and Y coordinates (for MPP).
064         */
065        public void setProhibited(int x, int y) {
066            iProhibitedX = x;
067            iProhibitedY = y;
068            setValues(computeValues());
069            if (getInitialAssignment()!=null && !values().contains(getInitialAssignment()))
070                setInitialAssignment(null);
071        }
072        
073        /**
074         * Prohibits given initial location (for MPP).
075         */
076        public void setProhibited() {
077            if (getInitialAssignment()==null) return;
078            setProhibited(((Location)getInitialAssignment()).getX(),((Location)getInitialAssignment()).getY());
079        }
080        
081        /**
082         * Returns true if the given location is prohibited. This means that either X or Y equals to the prohibited X or Y coordinate respectively.
083         */
084        public boolean isProhibited(int x, int y) {
085            return (iProhibitedX == x || iProhibitedY == y);
086        }
087        
088        public int getProhibitedX() { return iProhibitedX; }
089        public int getProhibitedY() { return iProhibitedY; }
090        public int getMinX() { return iMinX; }
091        public int getMaxX() { return iMaxX; }
092        public int getMinY() { return iMinY; }
093        public int getMaxY() { return iMaxY; }
094        
095        /** Returns width of the rectangle */
096        public int getWidth() {
097            return iWidth;
098        }
099        
100        /** Returns height of the rectangle */
101        public int getHeight() {
102            return iHeight;
103        }
104        
105        /** Returns name of the rectangle */
106        public String getName() {
107            return iName;
108        }
109        
110        /** Set the bounds (minimal and maximal values of X and Y coordinates). */
111        public void setBounds(int minX, int maxX, int minY, int maxY) {
112            iMinX = minX;
113            iMaxX = maxX;
114            iMinY = minY;
115            iMaxY = maxY;
116            if (getInitialAssignment() != null && !values().contains(getInitialAssignment()))
117                setInitialAssignment(null);
118        }
119        
120        private Vector computeValues() {
121            Vector locations = new FastVector((iMaxX - iMinX) * (iMaxY - iMinY));
122            for (int x = iMinX; x <= iMaxX; x++) {
123                for (int y = iMinY; y <= iMaxY; y++) {
124                    if (!isProhibited(x, y)) {
125                        Value val = new Location(this, x, y);
126                        locations.addElement(val);
127                        if (getInitialAssignment() != null && getInitialAssignment().equals(val))
128                            setInitialAssignment(val);
129                        if (getBestAssignment() != null && getBestAssignment().equals(val))
130                            setBestAssignment(val);
131                    }
132                }
133            }
134            return locations;
135        }
136        
137        /** String representation (for printing and debugging purposes) */
138        public String toString() {
139            return "Rectangle{name='" + getName() + "', size=[" + getWidth() + "," + getHeight() + "], bounds=[" + iMinX + ".." + iMaxX + "," + iMinY + ".." + iMaxY + "], super=" + super.toString() + "}";
140        }
141        
142        /** Compares two rectangles (based on rectangle names)*/
143        public boolean equals(Object o) {
144            return ((Rectangle)o).getName().equals(getName());
145        }
146    }