Giter Club home page Giter Club logo

timetabling-solver's Introduction

timetabling-solver

A library which exposes a genetic algorithm to solve (one of) the timetabling problem.

TL;DR: I want to assign things to time slots and minimize by the number of collisions between things

Problem

Given:

  • a list of time slots
  • a list of bookables that can be assigned to a specific time slot
  • a list of constraints in the form of:
    • a list of bookables which shouldn't overlap

Find the optimal assignment for bookables in time slots in order to minimize the number of collisions between bookables

Description

The genetic algorithm presented:

  • Generates a population of random timetables
  • Evaluates the fitness of the population
  • Applies mutation or crossover to the population to obtain another population

Crossover generates two timetables starting from two timetables. The parents are selected using genetic-js fittest and tournament2 algorithms. The crossover is a classic 2 points crossover:

  • A randomly sorted list of bookables get divided in 2 points
  • The bookables in the first and last segments will use the time slot selected in the first parent
  • The bookables in the middle semgent will use the time slot selected in the second parent

Mutation is specifically tuned to mutate a random collisions with a random element. The idea behind targeting a random collision and not a random element is that we want to target the problematic areas. Following this approaches increased performances greatly and reduced the number of cases in which the algorithm was getting stuck repeatedly on populations with very low number of collisions.

Basic Example

const solve = require('timetabling-solver').minCollisions

const slots = ['8:00', '10:00', '12:00']
const bookables = ['Tennis', 'Climbing', 'Gymnastic', 'Trapeze', 'Handstands']
const constraints = [ //list of non overlapping constraints
  ['Tennis', 'Climbing'],
  ['Handstands', 'Climbing'],
  ['Trapeze', 'Tennis'],
  ['Tennis', 'Handstands', 'Trapeze']
]

solve({ slots, bookables, constraints }, {}, (table, fitness) => console.log(table, fitness))

{ '10:00': [ 'Trapeze', 'Climbing' ],
  '12:00': [ 'Handstands', 'Gymnastic' ],
  '8:00': [ 'Tennis' ] } 0

Custom Constraints

From version 0.3.2 you can add custom constraints to your problems.

Instead of adding a list of colliding entries, you need to provide a function.

A custom constraint is a function which accept a timetable and returns a list of collisions:

  • Returning an empty array means there are no collisions according to your constraint.
  • Returning an array with values from your bookables means they're colliding
const solve = require('timetabling-solver').minCollisions

const slots = ['8:00', '10:00']
const bookables = ['Tennis', 'Climbing']
const constraints = [ //list of non overlapping constraints
  ['Tennis', 'Climbing'],
  (timetable) => timetable['8:00'].indexOf('Climbing') !== -1 ? ['Climbing'] : []
  //Climbing can't be at 8:00
]

solve({ slots, bookables, constraints }, {}, (table, fitness) => console.log(table, fitness))

API

require('timetabling-solver').minCollisions(data, config, callback, partialCallback)
  data = {              // Object which represents the specification of the problem
    slots               // List of time slots 
    bookables           // List of bookables that can be assigned to a specific time slot
    constraints: [      // List of constraints
      constraint        // List of bookables which shouldn't overlap
    ]  
  }
  config = {            // Object which contains extra configuration    
    iterations: 1000,   // Maximum number of generations before stopping the algorithm
    size: 250,          // Size of the population
    crossover: 0.3,     // Probability of crossover happening
    mutation: 0.8,      // Probability of a mutation happening
    skip: 20,           // Numnber of generations to skip before calling partialCallback
    debug?: false,      // provide additional data to callbacks, for easier debugging
    ...more: check out genetic-js documentation
  }
  callback = (timetable, meta) //Function called at the end of the computation
  partialCallback = (timetable, meta) //Function called after the number of generations set in skip
    timetable =         //Fittest timetable 
    meta = { 
      fitness,          //Fitness number which represent the number of collisions
      generation,       //Number of generation of elapsed
      stats,            //Stats as per genetic-js
      pop,              //Current population
      popTables,        //Same as pop, but each entity is converted into proper timetable. Available ONLY if config.debug is set
      collisions        //Collisions in the fittest timetable
    }

Examples

Check out the examples (the advanced one in particular).

Contributions

I love small and big contributions. Whether you want to solve another entire timetabling problem or whether you found a default configuration which yields better results in a demonstrable way - I'm always happy to review PRs and discuss about the project.

Unfortunately I benefited from this code a long time ago - aka I'm not using it actively and don't have too much time to work on it.

Contributors

Credits

timetabling-solver's People

Contributors

framp avatar sithmel avatar alenl avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.