/*
 * StrategieVyberu.java
 *
 * Created on 12. říjen 2000, 14:01
 * Documented 18. 7. 2001
 */

package timetable.solver.strategy.variable;

import timetable.data.*;
import timetable.util.*;
/** Implicitní heuristika výběru nenaplánované aktivity. Snaha je vybrat nejhůře naplánovatelnou aktivitu.
 *
 * @author  Tomáš Müller
 * @version 1.0
 */
public class WorstFirstVariableSelection implements VariableSelectionInterface {
    /** konfigurace */
    Config config = null;

    /** Konstruktor.
     * @param config konfigurace
     */
    public WorstFirstVariableSelection(Config config) {
        this.config=config;
    }
    
    /** Ohodnocení nenaplánované aktivity - hledá se aktivita s minimální hodnotou.
     * @param a nenaplánovaná aktivita
     * @param dependences množina závislostí mezi aktivitami
     * @return ohodnocení aktivity
     */
    private int value( Activity a, ActivityDependenceGroup dependences ) throws TimetableException {
        int sum = 0;
        sum += config.getInt("VYBER_PROM_VAHA_MISTA_BEZ_KONFLIKTU") * a.countScheduleWithoutCollision(dependences);
        sum += config.getInt("VYBER_PROM_VAHA_MISTA") * a.countSchedule(dependences);
        sum -= config.getInt("VYBER_PROM_VAHA_VYHOZENI") * a.nrRemoves;
        sum -= config.getInt("VYBER_PROM_VAHA_ZAVISLOSTI") * dependences.countDependences(a);
        return sum;
    }

    /** Výběr nenaplánované aktivity.
     * @param notScheduledActivities množina nenaplánovaných aktivit
     * @param dependences množina závislostí mezi aktivitami
     * @return vybraná aktivita
     */
    public Activity select(ActivityGroup notScheduledActivities,ActivityDependenceGroup dependences) throws TimetableException {
        if (config.getInt("VYBER_PROM_NAHODNE")==1) return notScheduledActivities.get(timetable.util.Math.random(notScheduledActivities.size()));
        boolean all = (config.getInt("VYBER_PROM_VSECHNY")==1);
        if (notScheduledActivities==null || notScheduledActivities.size()==0) return null;
        if (notScheduledActivities.size()==1) return notScheduledActivities.get(0);
        Activity selected=notScheduledActivities.get(timetable.util.Math.random(notScheduledActivities.size()));
        int min=value(selected,dependences);
        for (int i=0;i<notScheduledActivities.size();i++) {
            if (all || timetable.util.Math.random(5)==0) {
                int adept=value(notScheduledActivities.get(i),dependences);
                if (min>adept || (min==adept && timetable.util.Math.random(3)==0)) {
                    min=adept;
                    selected=notScheduledActivities.get(i);
                }
            }
        }
        return selected;
    }

}
