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

consecutive.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: consecutive.c,v 1.1.2.6 2005/09/13 17:36:08 avian Exp $ */

/** @module
 *
 * @author Nick Robinson 
 * @author-email npr@bottlehall.co.uk
 *
 * @brief Adds a weight whenever two events are not scheduled adjacent to one
 * another when they have been identified as needing to be.
 *
 * @ingroup School scheduling
 */

/** @tuple-restriction consecutive
 *
 * <restriction type="consecutive"/>
 *
 * This restriction specifies that the repeats of the current event need to 
 * be scheduled consecutively.
 */

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

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

#include "module.h"

static int*pevent;
static int periods;

static int events_equal(int tupleid1, int tupleid2) {
      int equal;
      int n;

      equal=0;
      if(!strcmp(dat_tuplemap[tupleid1].name, dat_tuplemap[tupleid2].name)) {
            /* Names of the tuples are equal */
            /* Check if they are using the same constant resources */
            equal=1;
            for(n=0;n<dat_typenum;n++) if(!dat_restype[n].var) {
                  if(dat_tuplemap[tupleid1].resid[n]!=
                              dat_tuplemap[tupleid2].resid[n]) {
                        equal=0;
                        break;
                  }
            }
      } 
      return equal;
}

int getevent(char *restriction, char *cont, tupleinfo *tuple)
{
      int tupleid1, tupleid2;

      if(strlen(cont)>0) {
            error(_("restriction 'consecutive' does not take an argument"));
            return(-1);
      }

      tupleid1=tuple->tupleid;
      tupleid2=tuple->tupleid-1;

      if(tupleid1>0&&events_equal(tupleid1, tupleid2)) {
            pevent[tupleid1]=tupleid2;
      }
      return 0;
}

int module_fitness(chromo **c, ext **e, slist **s)
{
      int sum;
      int tupleid, resid1, resid2;

      chromo *time;
      
      time=c[0];
      
      sum=0;
      for(tupleid=1;tupleid<time->gennum;tupleid++)
      {
            if(pevent[tupleid]!=-1)
            {
                  resid1=time->gen[tupleid];
                  resid2=time->gen[tupleid-1];

                  if(resid1/periods==resid2/periods) {
                        if(resid1%periods != resid2%periods+1) {
                              /* Tuples are scheduled on the same
                               * day but not in consecutive time
                               * slots */
                              sum++;
                        }
                  } else {
                        /* Tuples are scheduled on different days */
                        sum++;
                  }
            }
      }

      return(sum);
}

int module_precalc(moduleoption *opt) 
{
      int c;
      for(c=0;c<dat_tuplenum&&pevent[c]==-1;c++) /* null statement */;

      if(c==dat_tuplenum) {
            error( "module 'consecutive' has been loaded, but not used" );
      }
      return( 0 );
}

int module_init(moduleoption *opt) 
{
      int c, days;
      fitnessfunc *fitness;

      pevent=malloc(sizeof(*pevent)*dat_tuplenum);
      if(pevent==NULL) {
            error(_("Can't allocate memory"));
            return -1;
      }

      for(c=0;c<dat_tuplenum;c++) {
            pevent[c]=-1;
      }
      
      c=res_get_matrix(restype_find("time"), &days, &periods);
      if(c) {
            error(_("Resource type 'time' is not a matrix"));
            return -1;
      }
      
      precalc_new(module_precalc);

      handler_tup_new("consecutive", getevent);

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

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

      return(0);
}

Generated by  Doxygen 1.6.0   Back to index