Logo Search packages:      
Sourcecode: tablix2 version File versions  Download package

preferredroom.c

/* TABLIX, PGA general timetable solver                              */
/* Copyright (C) 2002-2005 Tomaz Solc                                      */

/* This program is free software; you can redistribute it and/or modify    */
/* it under the terms of the GNU General Public License as published by    */
/* the Free Software Foundation; either version 2 of the License, or       */
/* (at your option) any later version.                                     */

/* This program is distributed in the hope that it will be useful,         */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of          */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           */
/* GNU General Public License for more details.                            */

/* You should have received a copy of the GNU General Public License       */
/* along with this program; if not, write to the Free Software             */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

/* $Id: preferredroom.c,v 1.1.2.3 2005/09/02 19:30:38 avian Exp $ */

/** @module
 *
 * @author Nick Robinson 
 * @author-email npr@bottlehall.co.uk
 *
 * @brief Adds a weight whenever a class, teacher or an event is not in a
 * preferred room.
 *
 * In case multiple conflicting "preferred-room" restrictions are defined
 * for an event, the restriction with the highest priority is used. 
 *
 * Event restrictions have the highest priority, class resource restrictions 
 * have a middle priority and teacher resource restrictions have the lowest
 * priority.
 *
 * @ingroup School scheduling
 */

/** @resource-restriction preferred-room
 *
 * <restriction type="preferred-room">room name</restriction>
 *
 * This restriction can be used in teacher or class resources and specifies 
 * that current class or teacher should teach have all lessons scheduled in the 
 * room specified in the restriction.
 */

/** @tuple-restriction preferred-room
 *
 * <restriction type="preferred-room">room name</restriction>
 *
 * This restriction specifies the current lesson should be scheduled in the 
 * room specified in the restriction.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>

#include "module.h"

/* Arrays holding preferred rooms for teachers, classes, events. Sorted
 * by resource id, tuple id. "-1" if no preferred room was specified. */
static int *ptroom;
static int *pcroom;
static int *peroom;

static resourcetype *roomtype;

int gettroom(char *restriction, char *cont, resource *res1)
{
      resource *res2;
      res2=res_find(roomtype, cont);
      if(res2==NULL) {
            error(_("invalid room in preferred-room restriction"));
            return(-1);
      }

      if(ptroom[res1->resid]!=-1) {
            error(_("Only one restriction per resource allowed"));
            return(-1);
      }
      ptroom[res1->resid]=res2->resid;

      return 0;
}

int getcroom(char *restriction, char *cont, resource *res1)
{
      resource *res2;
      res2=res_find(roomtype, cont);
      if(res2==NULL) {
            error(_("invalid room in preferred-room restriction"));
            return(-1);
      }

      if(pcroom[res1->resid]!=-1) {
            error(_("Only one restriction per resource allowed"));
            return(-1);
      }
      pcroom[res1->resid]=res2->resid;

      return 0;
}

int geteroom(char *restriction, char *cont, tupleinfo *tuple)
{
      resource *res2;
      res2=res_find(roomtype, cont);
      if(res2==NULL) {
            error(_("invalid room in preferred-room restriction"));
            return(-1);
      }

      if(peroom[tuple->tupleid]!=-1) {
            error(_("Only one restriction per resource allowed"));
            return(-1);
      }
      peroom[tuple->tupleid]=res2->resid;

      return 0;
}

int module_fitness(chromo **c, ext **e, slist **s)
{
      int m, sum;
      chromo *time, *room, *teacher, *class;
      time = c[0];
      teacher = c[1];
      room = c[2];
      class = c[3];
      
      sum=0;
      for(m=0;m<time->gennum;m++) {
            if ( peroom[m] != -1 ) {
                  if (room->gen[m] != peroom[m]) sum++;
            }
            else
            if (pcroom[class->gen[m]] != -1 )
            {
                  if ( room->gen[m] != pcroom[class->gen[m]]) sum++;
            }
            else if (ptroom[teacher->gen[m]] != -1 && room->gen[m] != ptroom[teacher->gen[m]]) sum++;
      }
      return(sum);
}

int module_precalc(moduleoption *opt) 
{
      int c;
      int unused = 1;
      /*
      for(c=0; c<restype_find("teacher")->resnum; c++) {
            debug("troom[%d]=%d", c, ptroom[c] );
      }
      for(c=0; c<restype_find("class")->resnum; c++) {
            debug("croom[%d]=%d", c, pcroom[c] );
      }
      for( c=0; c<dat_tuplenum; c++ ) {
            debug("eroom[%d]=%d", c, peroom[c] );
      }
      */
      for(c=0;c<restype_find("teacher")->resnum&&ptroom[c]==-1;c++);

      if((unused=(c==restype_find("teacher")->resnum))) {
            for(c=0;c<restype_find("class")->resnum&&pcroom[c]==-1;c++);

            if((unused=(c==restype_find("class")->resnum))) {
                  for(c=0;c<dat_tuplenum&&peroom[c]==-1;c++);
            }
      }     
      if ( unused ) {
            error(_("module '%s' has been loaded, but not used"), 
                        "preferredroom.so");
      }
      
      return( 0 );
}

int module_init(moduleoption *opt) 
{
      int c;
      ptroom=malloc(sizeof(*ptroom)*restype_find("teacher")->resnum);
      for(c=0;c<restype_find("teacher")->resnum;c++) ptroom[c]=-1;

      pcroom=malloc(sizeof(*pcroom)*restype_find("class")->resnum);
      for(c=0;c<restype_find("class")->resnum;c++) pcroom[c]=-1;

      peroom=malloc(sizeof(*peroom)*dat_tuplenum);
      for(c=0;c<dat_tuplenum;c++) peroom[c]=-1;

      roomtype=restype_find("room");
      if(roomtype==NULL) {
            error(_("Required resource type '%s' not found"), "room");
            return(-1);
      }
      
      fitnessfunc *fitness;

      precalc_new(module_precalc);

      handler_res_new("teacher", "preferred-room", gettroom);
      handler_res_new("class", "preferred-room", getcroom);
      handler_tup_new("preferred-room", geteroom);

      fitness=fitness_new("teacher preferred", 
                  option_int(opt, "weight"), 
                  option_int(opt, "mandatory"), 
                  module_fitness);
      if(fitness==NULL) return -1;

      if(fitness_request_chromo(fitness, "time")) return -1;
      if(fitness_request_chromo(fitness, "teacher")) return -1;
      if(fitness_request_chromo(fitness, "room")) return -1;
      if(fitness_request_chromo(fitness, "class")) return -1;

      return(0);
}

Generated by  Doxygen 1.6.0   Back to index