001    package net.sf.cpsolver.coursett;
002    
003    import java.io.File;
004    import java.util.Enumeration;
005    
006    import net.sf.cpsolver.coursett.model.Lecture;
007    import net.sf.cpsolver.coursett.model.TimetableModel;
008    import net.sf.cpsolver.ifs.util.CSVFile;
009    import net.sf.cpsolver.ifs.util.DataProperties;
010    import net.sf.cpsolver.ifs.util.ToolBox;
011    
012    /**
013     * Create domain chart of the given input problem as CSV file
014     * (3 dimensions: #rooms, #times, #variables with the given number of rooms/times)
015     * 
016     * @version
017     * CourseTT 1.1 (University Course Timetabling)<br>
018     * Copyright (C) 2007 Tomáš Müller<br>
019     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
020     * Lazenska 391, 76314 Zlin, Czech Republic<br>
021     * <br>
022     * This library is free software; you can redistribute it and/or
023     * modify it under the terms of the GNU Lesser General Public
024     * License as published by the Free Software Foundation; either
025     * version 2.1 of the License, or (at your option) any later version.
026     * <br><br>
027     * This library is distributed in the hope that it will be useful,
028     * but WITHOUT ANY WARRANTY; without even the implied warranty of
029     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
030     * Lesser General Public License for more details.
031     * <br><br>
032     * You should have received a copy of the GNU Lesser General Public
033     * License along with this library; if not, write to the Free Software
034     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
035     */
036    public class DomainChart {
037        protected int iSizeX = 60, iSizeY = 100;
038        protected TimetableModel iModel;
039        protected double[][] iTable = null;
040        protected boolean iShowZero = false;
041        protected String iName = null;
042        protected String[] iHeader = null;
043        protected String[] iTitle = null;
044        
045        public DomainChart(String name, TimetableModel model, int sizeX, int sizeY) {
046            iModel = model; iName = name;
047            iSizeX = sizeX; iSizeY = sizeY;
048        }
049        
050        public DomainChart(File xmlFile, int sizeX, int sizeY) throws Exception {
051            this(xmlFile.getName().substring(0, xmlFile.getName().lastIndexOf('.')),new TimetableModel(new DataProperties()),sizeX,sizeY);
052            TimetableXMLLoader loader = new TimetableXMLLoader(iModel);
053            loader.setInputFile(xmlFile);
054            loader.load();
055        }
056        
057        protected void clearTable() {
058            iTable = new double[2+iSizeX][2+iSizeY];
059            for (int i=0;i<iTable.length;i++)
060                for (int j=0;j<iTable[i].length;j++)
061                    iTable[i][j]=0;
062            iHeader = new String[iSizeX+2];
063            for (int i=0;i<=iSizeX;i++)
064                iHeader[i]=String.valueOf(i);
065            iHeader[iSizeX+1]=(iSizeX+1)+"+";
066            iTitle = new String[iSizeY+2];
067            for (int i=0;i<=iSizeY;i++)
068                iTitle[i]=String.valueOf(i);
069            iTitle[iSizeY+1]=(iSizeY+1)+"+";
070        }
071        
072        protected void add(int x, int y, double val) {
073            iTable[x<=iSizeX?x:1+iSizeX][y<=iSizeY?y:1+iSizeY] += val;
074        }
075        
076        protected void computeTable() {
077            clearTable();
078            for (Enumeration e=iModel.variables().elements();e.hasMoreElements();) {
079                Lecture lecture = (Lecture)e.nextElement();
080                if (lecture.getNrRooms()>1)
081                    add(lecture.nrTimeLocations(),(int)Math.round(Math.pow(lecture.nrRoomLocations(),1.0/lecture.getNrRooms())),1);
082                else
083                    add(lecture.nrTimeLocations(),lecture.nrRoomLocations(),1);
084            }
085        }
086        
087        public CSVFile createTable() {
088            computeTable();
089            CSVFile csv = new CSVFile();
090            CSVFile.CSVField[] header = new CSVFile.CSVField[2+iSizeX+(iShowZero?1:0)];
091            header[0]=new CSVFile.CSVField(iName);
092            for (int i=(iShowZero?0:1);i<=iSizeX+1;i++)
093                header[(iShowZero?1:0)+i]=new CSVFile.CSVField(iHeader[i]);
094            csv.setHeader(header);
095            for (int y=(iShowZero?0:1);y<=1+iSizeY;y++) {
096                CSVFile.CSVField[] line = new CSVFile.CSVField[2+iSizeX+(iShowZero?1:0)];
097                line[0]=new CSVFile.CSVField(iTitle[y]);
098                if (y==1+iSizeY)
099                    line[0]=new CSVFile.CSVField((1+iSizeY)+"+");
100                for (int x=(iShowZero?0:1);x<=1+iSizeX;x++)
101                    line[(iShowZero?1:0)+x]=new CSVFile.CSVField(iTable[x][y]);
102                csv.addLine(line);
103            }
104            return csv;
105        }
106        
107        public static void main(String args[]) {
108            try {
109                ToolBox.configureLogging();
110                File input = new File(args[0]);
111                int sizeX = Integer.parseInt(args[1]);
112                int sizeY = Integer.parseInt(args[2]);
113                File output = null;
114                if (args.length>3) { 
115                    output = new File(args[3]);
116                    if (output.exists() && output.isDirectory())
117                        output = new File(output,input.getName().substring(0,input.getName().lastIndexOf('.'))+"_domain.csv");
118                } else {
119                    output = new File(input.getParentFile(),input.getName().substring(0,input.getName().lastIndexOf('.'))+"_domain.csv");
120                }
121                new DomainChart(input,sizeX,sizeY).createTable().save(output);
122            } catch (Exception e) {
123                e.printStackTrace();
124            }
125        }
126    }