001    package net.sf.cpsolver.coursett.criteria;
002    
003    import java.util.Collection;
004    import java.util.HashSet;
005    import java.util.Set;
006    
007    import net.sf.cpsolver.coursett.constraint.SpreadConstraint;
008    import net.sf.cpsolver.coursett.model.Lecture;
009    import net.sf.cpsolver.coursett.model.Placement;
010    
011    import net.sf.cpsolver.ifs.util.DataProperties;
012    
013    /**
014     * Same subpart balancing penalty. This criterion tries to spread classes of each
015     * scheduling subpart in time. It also includes all other spread in time distribution
016     * constraints. This criterion is counted by {@link SpreadConstraint}. 
017     * <br>
018     * 
019     * @version CourseTT 1.2 (University Course Timetabling)<br>
020     *          Copyright (C) 2006 - 2011 Tomas Muller<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     */
038    public class SameSubpartBalancingPenalty extends TimetablingCriterion {
039        
040        public SameSubpartBalancingPenalty() {
041            iValueUpdateType = ValueUpdateType.NoUpdate;
042        }
043        
044        @Override
045        public double getWeightDefault(DataProperties config) {
046            return 12.0 * config.getPropertyDouble("Comparator.SpreadPenaltyWeight", 1.0);
047        }
048    
049        @Override
050        public String getPlacementSelectionWeightName() {
051            return "Placement.SpreadPenaltyWeight";
052        }
053    
054        @Override
055        public double getValue(Placement value, Set<Placement> conflicts) {
056            double ret = 0.0;
057            for (SpreadConstraint sc: value.variable().getSpreadConstraints())
058                ret += sc.getPenalty(value);
059            return ret / 12.0;
060        }
061        
062        @Override
063        public double getValue() {
064            return iValue / 12.0;
065        }
066        
067        @Override
068        public double getValue(Collection<Lecture> variables) {
069            double ret = 0;
070            Set<SpreadConstraint> constraints = new HashSet<SpreadConstraint>();
071            for (Lecture lect: variables) {
072                for (SpreadConstraint sc: lect.getSpreadConstraints()) {
073                    if (!constraints.add(sc)) continue;
074                    ret += sc.getPenalty();
075                }
076            }
077            return ret / 12.0;
078        }
079        
080        @Override
081        public double[] getBounds() {
082            return new double[] { 0.0, 0.0 };
083        }
084        
085        @Override
086        public double[] getBounds(Collection<Lecture> variables) {
087            return new double[] { 0.0, 0.0 };
088        }
089    }