Package: hackathonbaobab2020
hackathon baobab 2020We want to schedule all jobs by deciding when and in which mode to execute each job. There are precedence relationships between pairs of jobs. There are two types of resources. Renewable resources (R) are consumedeach periodand have an availability that is recovered each period of time. Non-renewable resources (N) are consumedonce per joband have an availability for the whole planning horizon.
The objective is to reduce the finishing time (start time + duration) of the last job.As an example the following image shows the input data (left), and the optimal solution (center: gantt, resource usage: right) for the instancec159_7.mm:The instances for the problem are found here:http://www.om-db.wi.tum.de/psplib/getdata_mm.htmlOn thedatadirectory of this repository we have copied the smallest instances.
For the format of the solution, since there is no example that we know of, we'll be using the one indata/solutions/c15mm/c1564_9.output.jsonBelow are the instructions to use the helper functions and checker (they are optional).
To understand the format of the input data file, you can check how we parse it in python in the functionInstance.from_mm(path)in the filehackathonbaobab2020/core/instance.pyInstallationpython>=3.5 is needed. I'm assuming a Windows installation.To install from source:cd hackathonbaobab2020
python -m venv venv
venv/Scripts/activate
pip install -r requirements.txtAlternatively, it's possible to install it as a pypi package.
Here there is more control on which packages are installed.Install only the core dependencies (core, schemas, default solver)::pip install hackathonbaobab2020Install all dependencies ('benchmark' to generate graphs, 'solvers' to install solver dependencies). The second line installs (in Ubuntu) the cbc solver::pip install hackathonbaobab2020[benchmark,solvers]
sudo apt install coinor-cbcHow to add a new solverThese are the steps to add a solver and make it compatible with the command line and the python functions:Add a file inside thehackathonbaobab2020/solverdirectory with a subclass ofhackathonbaobab2020.core.experiment.Experimentthat implements, at least, thesolve()methodwith the same argument names.Yoursolvemethod needs to return an integer with the status of the solving process. Current values are{4: "Optimal", 2: "Feasible", 3: "Infeasible", 0: "Unknown"}.Yoursolvemethod also needs to store the best solution found inself.solution. It needs to be an instance of theSolutionobject.Edit thehackathonbaobab2020/solver/__init__.pyto import your solver and edit thesolversdictionary by giving your solver a name.If therequirements.txtfile is missing some package you need for your solver, add it to the list undersolvers. Also edit thesetup.pyand add the dependency onsolverswithin theextras_requiredictionary.Additional considerations:One way to see if the solver is correctly integrated is to test solving with it via the command line (see below).Everything that your solver needs should be inside thehackathonbaobab2020/solverdirectory (you can put more than one file). Do not edit the files outside thesolverdirectories with code from your solver!How to run testsThese tests are run also in github and test some small example problems with atimelimitof 120 s (check theoptionsdictionary).python tests/tests.pyCommand lineThe command line app has three main ways to use it.To execute instancesTo get all possible commands just run:python hackathonbaobab2020/main.py solve-scenarios --helpThe following assumes you have downloaded the zipj30.mm.zipof input instances, and you have stored it in thedatadirectory. It solves instancej301_1.mmwith the solver that is inhackathonbaobab2020/solver/algorithm1nameddefaultinhackathonbaobab2020/solver/__init__.py.python hackathonbaobab2020/main.py solve-scenarios --directory=data --scenario=j30.mm.zip --solver=default --instance=j3010_1.mm --no-testYou can also solve multiple scenarios or multiple instances by passing the--instancesand--scenariosarguments. Just be careful with the string format:python hackathonbaobab2020/main.py solve-scenarios --directory=data --scenarios='["c15.mm.zip", "c21.mm.zip", "j10.mm.zip", "j30.mm.zip", "m1.mm.zip", "m5.mm.zip", "n0.mm.zip", "n1.mm.zip", "n3.mm.zip", "r1.mm.zip", "r4.mm.zip", "r5.mm.zip"]' --solver=defaultWith the option argument, a json with the solving configuration is passed:python hackathonbaobab2020/main.py solve-scenarios --directory=data --scenario=j30.mm.zip --solver=brute_EJ --instance=j3010_1.mm --no-test --options='{"DEBUG": 1, "timeLimit": 120}'Finally, if you pass thezipoption you create a nice little zip at the end.The output format is always the same:solver_name/scenario_name/instance_name/(input.json, output.json, options.json)Theoptions.jsonfile contains some information from the solver such as the time it took to solve, the status (Optimal, Feasible, Infeasible, etc.), the name of the solver, etc.To get statistics from a solutionYou first need to have a zip with the results you want to get statistics from. For this, the easiest is to pass thezipoption to thesolve-scenariosfunction above.Then you do something like:python hackathonbaobab2020/main.py export-table --path=data/default.zip --path_out=data_default.csvThis generates a table in a csv with several columns: scenario, name (instance), objective (function value), solver, (solving) time, (number of) errors (in the solution).To easily read the contents you can do:importpandasaspddf=pd.read_csv('data_default.csv')print(df.head().to_markdown())Which should print something like this:scenarionameobjectivesolvertimeerrors0n3.mmn311_1.mm44default0.00028258111n0.mmn013_7.mm35default0.00022732602r4.mmr452_6.mm46default0.0002589313n3.mmn343_4.mm37default0.00026872314n1.mmn121_4.mm55default0.0002543370Benchmarking solversInhackathonbaobab2020/execution/benchmark.pythere are functions to automate the comparison of solvers. Functionsolve_all()executes a set of random instances. They require previously downloading the corresponding zips from the dataset site. Functioncompareproduce a summary table based on the results. Finally,graphsuse the generated table to produce graphs of the results.Example of a resulting graph:Using python objectsWe use the following helper objects:Instanceto represent input data.Solutionto represent a solution.Experimentto represent input data+solution.Algorithm(Experiment)to represent a resolution approach.An example of the last one (4) is found inhackathonbaobab2020/solver/algorithm1.py. It schedules one job at a time while respecting the sequence. It passes all tests except the non-renewables, sometimes.There are helper functions to read and write an instance and a solution to/from a file.A small example of how to use the existing code is available inhackathonbaobab2020/execution/test_script.py.
Below an example:fromhackathonbaobab2020.coreimportInstancefromhackathonbaobab2020.solverimportget_solver# get mm filepath="data/c15.mm/c154_3.mm"# initialize an instance objectinstance=Instance.from_mm(path)# get the default solver (in solver/algorithm1.py)solver=get_solver('default')# initialize the solver with the instanceexp=solver(instance=instance)# solve the instance using the solverexp.solve({})# The next functions do not depend on the solver and should not be overwritten:# print the possible errors on the solution obtained from the solverprint(exp.check_solution())# print the objective function of the solutionprint(exp.get_objective())# produce a gantt chart of the job's schedule, with a color per mode.exp.graph()