Package de.timefinder.algo.io

Source Code of de.timefinder.algo.io.DataPool4Track2

/*
* DataPool.java
*
* Created on 21.09.2007, 22:23:54
*
* This file is part of the TimeFinder project.
* Visit http://www.timefinder.de for more information.
* Copyright 2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.timefinder.algo.io;

import de.timefinder.data.algo.DataPoolSettings;
import de.timefinder.algo.MyStatusBar;
import de.timefinder.algo.constraint.EventOrderConstraint;
import de.timefinder.algo.constraint.PersonITCRasterConstraint;
import de.timefinder.algo.constraint.RasterConstraint;
import de.timefinder.data.DataPool;
import de.timefinder.data.DataPoolImpl;
import de.timefinder.data.Event;
import de.timefinder.data.Feature;
import de.timefinder.data.Location;
import de.timefinder.data.Person;
import de.timefinder.data.access.Dao;
import de.timefinder.data.set.RasterEnum;
import de.timefinder.data.set.WeekRaster;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* @author Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net
*/
public class DataPool4Track2 {

    private final Log logger = LogFactory.getLog(getClass());
    private DataPoolSettings poolSettings;
    private String fileName;
    private Reader reader;
    private DataPool dataPool;
    private MyStatusBar statusBar;

    public DataPool4Track2() {
        dataPool = new DataPoolImpl();
    }

    /**
     * This constructor creates a new instance of DataPool.
     * Now you can call startOptimization. See the class description for more
     * information.
     */
    public void setSettings(DataPoolSettings poolSettings) {
        this.poolSettings = poolSettings;
    }

    public DataPoolSettings getSettings() {
        return poolSettings;
    }

    public void setDataPool(DataPool dataPool) {
        this.dataPool = dataPool;
    }

    public DataPool getDataPool() {
        return dataPool;
    }

    public Dao<Event> getEventDao() {
        return getDataPool().getDao(Event.class);
    }

    public Dao<Feature> getFeatureDao() {
        return getDataPool().getDao(Feature.class);
    }

    public Dao<Person> getPersonDao() {
        return getDataPool().getDao(Person.class);
    }

    public Dao<Location> getLocationDao() {
        return getDataPool().getDao(Location.class);
    }

    public String getFileName() {
        if (fileName == null) {
            fileName = "ncp-solution";
        }
        return fileName;
    }

    public void setSource(Object file) {
        if (file instanceof String) {
            fileName = (String) file;
        } else if (file instanceof File) {
            fileName = ((File) file).getAbsolutePath();
        } else {
            reader = (Reader) file;
        }
    }

    public Reader getReader() throws FileNotFoundException {
        if (reader == null) {
            // return a fresh reader on every get, because multiple reads should be possible:
            return new FileReader(fileName);
        }
        return reader;
    }

    public void doWork() {
        try {
            parse(getReader());
        } catch (FileNotFoundException ex) {
            logger.error("Cannot find file to load timetabling data.", ex);
            throw new RuntimeException("File not found! " + ex.getMessage());
        } catch (IOException ex) {
            logger.error("Cannot load timetabling data.", ex);
            throw new RuntimeException("Cannot load file! " + ex.getMessage());
        }
    }

    public void save() {
        try {
            writeToFile(getEventDao().getAll(), fileName);
        } catch (IOException ex) {
            logger.error("Couldn't save timetabling data.", ex);
        }
    }

    public void setStatusBar(MyStatusBar bar) {
        statusBar = bar;
    }

    public void updateStatus(int percentage) {
        if (statusBar != null)
            statusBar.getMyProgressMonitor().worked(percentage);
    }

    /**
     * This method writes the solution to a file.
     */
    public void writeToFile(Collection<? extends Event> optTIs, String fileName)
            throws IOException {

        BufferedWriter writer = new BufferedWriter(new FileWriter(fileName + ".sln"));
        logger.debug("Write to file: " + fileName + ".sln");

        try {
            for (Event ti : optTIs) {
                Location r = ti.getLocation();
                assert ti.getStart() == -1 ? r == null : true;

                // Hint: If a Event was not assigned to the timetable the
                // starttime is null and the room is null, so this is fine:
                // writer.write("-1 -1");
                writer.write(ti.getStart() + " " + indexOfLocation(r) + "\n");
            }
        } finally {
            writer.close();
        }
    }

    /**
     * This method parses an input file with a special timetabling format.
     * Download those special files here:
     * http://downloads.sourceforge.net/timefinder/track2.zip
     *
     * @see http://www.cs.qub.ac.uk/eventmap/postenrolcourse/course_post_index_files/Inputformat.htm
     */
    public void parse(Reader reader) throws FileNotFoundException, IOException {
        if (reader == null)
            throw new NullPointerException("Reader cannot be null!");

        if (fileName != null)
            logger.info("Parse file:" + fileName);

        // first of all remove existent objects
        getPersonDao().detachAll();
        getFeatureDao().detachAll();
        getLocationDao().detachAll();
        getEventDao().detachAll();

        BufferedReader bReader = new BufferedReader(reader);

        updateStatus(10);
        try {
            //1. The first line defines the number of some data:
            String numberOf[] = bReader.readLine().split(" ");
            int noOfEvents = Integer.parseInt(numberOf[0]);
            int noOfLocations = Integer.parseInt(numberOf[1]);
            int noOfFeatures = Integer.parseInt(numberOf[2]);
            int noOfPersons = Integer.parseInt(numberOf[3]);

            // 2. Every line contains the capacity of one room
            for (int i = 0; i < noOfLocations; i++) {
                Location location = createLocation(Integer.parseInt(bReader.readLine()));
                location.putConstraint(newRasterConstraint());
//                EventSetConstraint esc = (EventSetConstraint) appCtx.getBean(ES_CONSTRAINT);
//                location.putConstraint(esc);
            }

            // initialize events
            for (int i = 0; i < noOfEvents; i++) {
                createEvent();
            }

            // initialize features
            for (int i = 0; i < noOfFeatures; i++) {
                createFeature();
            }

            updateStatus(30);
            double tmp = 10.0 / (noOfPersons + 1);
            // 3. 'noOfSubjects'-lines describes the choice of one person (student/event)
            Person currentPerson;
            for (int p = 0; p < noOfPersons; p++) {
                updateStatus(30 + (int) (p * tmp));

                currentPerson = createPerson();
                currentPerson.putConstraint(newRasterConstraint());

                for (Event event : getEventDao().getAll()) {
                    if ((Integer.parseInt(bReader.readLine()) > 0)) {
                        currentPerson.addEvent(event, true);
                    }
                }
            }

            updateStatus(40);
            // 4. Now 'noOfFeatures'-lines describes the features of one room (room/feature)
            for (Location currentLocation : getLocationDao().getAll()) {
                for (Feature feature : getFeatureDao().getAll()) {
                    if ((Integer.parseInt(bReader.readLine()) > 0)) {
                        currentLocation.addFeature(feature);
                    }
                }
            }

            updateStatus(50);
            // 5. 'noOfFeatures'-lines describes the features-requirements of one subject (event/feature)
            for (Event currentSubject : getEventDao().getAll()) {
                for (Feature feature : getFeatureDao().getAll()) {
                    if ((Integer.parseInt(bReader.readLine()) != 0)) {
                        currentSubject.addFeature(feature);
                    }
                }
            }

            updateStatus(60);
            // 6. 'noOfTimeSlots'-lines describes the valid assignments of one subject (event/timeslot)
            int noOfTimeSlots = poolSettings.getTimeslotsPerWeek();
            for (Event currentEvent : getEventDao().getAll()) {
                RasterConstraint rc = newRasterConstraint();
                currentEvent.putConstraint(rc);
                WeekRaster raster = rc.getRaster();
                for (int ts = 0; ts < noOfTimeSlots; ts++) {
                    //String s = reader.readLine(); sb.append(s);
                    if (Integer.parseInt(bReader.readLine()) != 0) {
                        raster.set(ts, RasterEnum.ALLOWED);
                    }
                }
            }

            updateStatus(70);
            // 7. 'noOfSubjects'-lines describes the 'follow/before'-matrix of one subject (event/event)
            for (Event firstEvent : getEventDao().getAll()) {
                for (Event secEvent : getEventDao().getAll()) {
                    int i = Integer.parseInt(bReader.readLine());
                    if (i == 1) {
                        // add the constraint to the both event
                        EventOrderConstraint firstConstraint = firstEvent.getConstraint(EventOrderConstraint.class);
                        if (firstConstraint == null) {
                            firstConstraint = new EventOrderConstraint(firstEvent);
                            firstEvent.putConstraint(firstConstraint);
                        }
                        firstConstraint.addFollow(secEvent);

                        EventOrderConstraint secConstraint = secEvent.getConstraint(EventOrderConstraint.class);
                        if (secConstraint == null) {
                            secConstraint = new EventOrderConstraint(secEvent);
                            secEvent.putConstraint(secConstraint);
                        }
                        secConstraint.addBefore(firstEvent);
                    } else if (i == -1) {
                        // We could check now the priviously added followers and beforers,
                        // but this is not possible because '-1' could occur the
                        // first time (instead of expected '1')
                    }
                }
            }

            updateStatus(80);
//            getMagicNumbersOfDataPool();

            String line = bReader.readLine();
            if (line != null) {
                logger.fatal("End of file should be reached. But content of line was:" + line);
                int counter = 0;
                while ((line = bReader.readLine()) != null) {
                    counter++;
                }
                logger.fatal("Further " + counter + " unprocessed lines detected");
            }
        } finally {
            //log.info(sb.toString());
            reader.close();
        }
    }

//    private void getMagicNumbersOfDataPool() {
//        int sFeatures = 0;
//        int lFeatures = 0;
//        int l2Features = 0;
//        int sRaster = 0;
//        int lRaster = 0;
//        int pRaster = 0;
//        int lCap = 0;
//        int visitors = 0;
//        int visitors2 = 0;
//        int events = 0;
//
//        for (Event sub : getEventDao().getAll()) {
//            visitors += sub.getPersons().size();
//            visitors2 += sub.getPersons().size();
//            sFeatures += sub.getFeatures().size();
//            sRaster += sub.getConstraint(RasterConstraint.class).getRaster().getForbidden().getAssignments();
//            if (sub.getFeatures().size() > 4) {
//                log.info(sub + " features:" + sub.getFeatures());
//            }
//        }
//        for (Person p : getPersonDao().getAll()) {
//            pRaster += p.getConstraint(RasterConstraint.class).getRaster().getForbidden().getAssignments();
//            events += p.getEvents().size();
//        }
//        for (Location r : getLocationDao().getAll()) {
//            lRaster += r.getConstraint(RasterConstraint.class).getRaster().getForbidden().getAssignments();
//            lCap += r.getCapacity();
//            lFeatures += r.getFeatures().size();
//            l2Features += r.getFeatureSet().getAssignments();
//            log.info(r + " features=" + r.getFeatures());
//        }
//
//        log.info("sFeatures:" + sFeatures);
//        log.info("lFeatures:" + lFeatures);
//        log.info("l2Features:" + l2Features);
//        log.info("sRaster:" + sRaster);
//        log.info("lRaster:" + lRaster);
//        log.info("pRaster:" + pRaster);
//        log.info("lCap:" + lCap);
//        log.info("visitors:" + visitors);
//        log.info("visitors2:" + visitors2);
//        log.info("#events:" + events);
//    }
    private int indexOfLocation(Location r) {
        int index = 0;
        for (Location room : getLocationDao().getAll()) {
            if (room.equals(r)) {
                return index;
            }
            index++;
        }
        return -1;
    }

    public Location createLocation(int capacity) {
        Location loc = new Location();
        loc.setCapacity(capacity);
        getLocationDao().attach(loc);
        loc.setName("Room " + loc.getId());

        return loc;
    }

    public Event createEvent() {
        Event event = new Event();

        //startTime == [0, 45); duration == 1
        event.setDuration(1);
        getEventDao().attach(event);
        event.setName("Event " + event.getId());
        return event;
    }

    public Person createPerson() {
        Person person = new Person();
        person.putConstraint(new PersonITCRasterConstraint(person, poolSettings));
        getPersonDao().attach(person);
        person.setName("Person " + person.getId());

        return person;
    }

    public void createFeature() {
        Feature feature = new Feature();
        getFeatureDao().attach(feature);
        feature.setName("Feature " + feature.getId());
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("#Persons:");
        sb.append(getPersonDao().getAll().size());
        sb.append("\n#Rooms:");
        sb.append(getLocationDao().getAll().size());
        sb.append("\n#Events:");
        sb.append(getEventDao().getAll().size());

        sb.append("\nPersons:");
        sb.append(getPersonDao().getAll());
        sb.append("\nRooms:");
        sb.append(getLocationDao().getAll());
        sb.append("\nEvents:");
        sb.append(getEventDao().getAll());
        return sb.toString();
    }

    private RasterConstraint newRasterConstraint() {
        return new RasterConstraint(poolSettings.createWeekRaster());
    }

    public void changeSettings() {
        poolSettings.setNumberOfDays(5);
        poolSettings.setTimeslotsPerDay(9);
    }
}
TOP

Related Classes of de.timefinder.algo.io.DataPool4Track2

TOP
Copyright © 2015 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.