/* 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 * * @credits * This module is a minor modification of consecutive2 module by Tomaz Solc * Original consecutive module by Nick Robinson * * @brief Adds a weight whenever events are not scheduled in blocks of * consecutive periods. * * @ingroup School scheduling */ /** @tuple-restriction periods-per-block * * periods * * This restriction specifies that the repeats of the current event need to * be scheduled in blocks of 'periods' consecutive periods. */ #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; static int time; 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; } void updater(int src, int dst, table *tab) { int src_time; src_time=tab->chr[time].gen[src]; debug ("SRC: %d DST: %d (%d)", src, dst, src_time); if(src_time%periods<(periods-1)) { /* not on the last period of the day. */ /* next consecutive event can be scheduled on the same day. */ debug ("Ajustando %d en %d", dst, src_time+1); tab->chr[time].gen[dst]=src_time+1; } else { tab->chr[time].gen[dst]=src_time; } } int module_precalc(moduleoption *opt) { int c, m; int ps; if(connum<1) { info(_("module '%s' has been loaded, but not used"), "timeblocks.so"); } for(c=0;c= con[c].ppb) { ps = 1; m++; /* skip the first event in next block */ } } } return(0); } int module_init(moduleoption *opt) { int c, days; 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("periods-per-block", getevent); return(0); }