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