/* 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 */ /** @module * * @author Antonio Duran * @author-email antonio.duran.terres@gmail.com * * @brief * Adds a weight if two timeblocks are scheduled on the same day. * * @ingroup School scheduling */ /** @tuple-restriction periods-per-block * * periods * * If this module is loaded, blocks of events with this restriction will be * scheduled on different days. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "module.h" struct cons_t { int *tuples; int tuplenum; int ppb; /* Periods per block */ }; static struct cons_t *con=NULL; static int connum=0; static int periods, days; 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 periods) { error(_("Invalid number of periods")); return(-1); } tupleid1=tuple->tupleid; tupleid2=tuple->tupleid-1; n=known_event(tupleid2); if(tupleid1>0&&events_equal(tupleid1, tupleid2)&&n>-1) { con[n].tuples[con[n].tuplenum]=tupleid1; con[n].tuplenum++; } else { con=realloc(con, sizeof(*con)*(connum+1)); con[connum].tuples=malloc( sizeof(*(con[connum].tuples))*dat_tuplenum); con[connum].tuples[0]=tupleid1; con[connum].tuplenum=1; con[connum].ppb=d; connum++; } return 0; } int module_fitness(chromo **c, ext **e, slist **s) { int sum; int i,j,k; int day1, day2; int times_today; chromo *time=c[0]; sum=0; for(i=0;igen[con[i].tuples[j]]/periods; times_today = 1; for(k=0;kgen[con[i].tuples[k]]/periods; if (day1==day2) { if (times_today < con[i].ppb) times_today++; else sum++; } } } } return(sum); } int module_init(moduleoption *opt) { int c; fitnessfunc *fitness; c=res_get_matrix(restype_find("time"), &days, &periods); if(c) { error(_("Resource type 'time' is not a matrix")); return -1; } handler_tup_new("periods-per-block", getevent); fitness=fitness_new("timeblocks_sameday", option_int(opt, "weight"), option_int(opt, "mandatory"), module_fitness); if(fitness_request_chromo(fitness, "time")) return -1; return 0; }