{"id":21962439,"url":"https://github.com/scipopt/papilo","last_synced_at":"2026-02-21T04:33:20.907Z","repository":{"id":54864320,"uuid":"356219239","full_name":"scipopt/papilo","owner":"scipopt","description":"Parallel Presolve for Integer and Linear Optimization ","archived":false,"fork":false,"pushed_at":"2026-01-29T08:01:33.000Z","size":18027,"stargazers_count":83,"open_issues_count":0,"forks_count":25,"subscribers_count":10,"default_branch":"main","last_synced_at":"2026-01-29T22:54:12.871Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Mathematical Programming System","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scipopt.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-04-09T09:47:29.000Z","updated_at":"2026-01-29T07:49:13.000Z","dependencies_parsed_at":"2023-02-18T02:30:47.347Z","dependency_job_id":"cd7eebec-d7a8-49a7-aae3-06bdab9f5575","html_url":"https://github.com/scipopt/papilo","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/scipopt/papilo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scipopt%2Fpapilo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scipopt%2Fpapilo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scipopt%2Fpapilo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scipopt%2Fpapilo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scipopt","download_url":"https://codeload.github.com/scipopt/papilo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scipopt%2Fpapilo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29673785,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T03:11:15.450Z","status":"ssl_error","status_checked_at":"2026-02-21T03:10:34.920Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T10:40:26.445Z","updated_at":"2026-02-21T04:33:20.881Z","avatar_url":"https://github.com/scipopt.png","language":"Mathematical Programming System","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PaPILO \u0026mdash; Parallel Presolve for Integer and Linear Optimization\n\nPaPILO, a C++14-based software package, provides parallel presolve routines for (mixed integer) linear programming problems. The routines\nare implemented using templates which allows switching to higher precision or rational arithmetic using the boost multiprecision package.\n\nAdditionally to the distribution here under the LGPLv3, PaPILO is also distributed as part of the\nSCIP Optimization Suite which is available under https://scipopt.org/.\n\nPaPILO can be used as a header-based library and also provides an executable.\nUsing the executable it is possible to presolve and postsolve MILP instances based on files.\nAdditionally, PaPILO can be linked to SCIP, SoPlex, Gurobi, Glop, and HiGHS (https://github.com/ERGO-Code/HiGHS) solvers and act as a frontend. In this setting PaPILO passes the presolved problem to those solvers and applies the postsolve step to the optimal solution.\nWhen PaPILO is compiled as part of the SCIP Optimization Suite linking of SoPlex and SCIP solvers is performed automatically.\nFurther, a Julia wrapper is available [here](https://github.com/scipopt/PaPILO.jl).\n\n\n*Note:* The original instance of this repository is hosted at  [git.zib.de](https://git.zib.de) and a read-only mirror is\navailable at [github.com/scipopt/papilo](https://github.com/scipopt/papilo).\n\n# Dependencies\n\nExternal dependencies that need to be installed by the user are the Intel TBB \u003e= 2020, or TBB from oneAPI runtime library and boost \u003e= 1.65 headers.\nThe executable additionally requires some of the boost runtime libraries that are not required when PaPILO is used as\na library.\nUnder the folder `external/` there are additional packages that are directly included within PaPILO and have a\nliberal open-source license.\n\nIf TBB is not found, then the current builds fails. The user has then the option to either enable the automatic download by adding `-DTBB_DOWNLOAD` to the cmake command or to disable it by adding `-DTBB=off` instead.\nHowever, it is strongly recommended to install an Intel TBB runtime library since it improves the runtime drastically.\n\nWe test PaPILO on some Debian, Ubuntu, macOS, and Windows system.\nWhile Papilo is likely to build and run on a wide variety of systems, compatibility is not guaranteed and support is limited.\n\n\n# Building\n\nBuilding PaPILO works with the standard cmake workflow:\n(_we recommend running the make command without specifying the number of jobs\nthat can run simultaneously (no -j n), since this may cause large memory consumption and freeze of the machine_)\n\n```\nmkdir build\ncd build\ncmake ..\nmake\n```\n\nBuilding PaPILO with SCIP, HiGHS, SoPlex or OrTools works also with the standard cmake workflow:\n```\nmkdir build\ncd build\ncmake -DSCIP_DIR=PATH_TO_SCIP_BUILD_DIR ..\nmake\n```\nAfter this, your PaPILO binary should be found in the `bin` folder.\nTo install into your system, run `sudo make install`.\n\nTo install PaPILO into a folder, add `-DCMAKE_INSTALL_PREFIX=/path/to/install/dir/` to the cmake call and run `make install` after the build.\n\nIf you use a relative path to SCIP, then the reference point is the location of the `CMakeLists.txt`.\nIf you want to build PaPILO with a provided Boost version please add one of these option to the cmake command:\n```\n-DBOOST_ROOT=../boost_1_72_0\n-DBOOST_INCLUDEDIR=../boost_1_72_0/include\n```\n\nSolvers that are found in the system are automatically linked to the executable.\nAdditionally one can specify the locations of solvers, e.g. with `-DSCIP_DIR=\u003clocation of scip-config.cmake\u003e`, to allow\nPaPILO to find them in non-standard locations.\n\nWhen tests are not necessary or fail to build, then use `-DBUILD_TESTING=OFF` to turn these off.\n\n# Usage of the binary\n\nThe PaPILO binary provides a list of all available functionality when the help flag `-h` or `--help` is specified.\nThe binary provides the three subcommands `solve`, `presolve`, and `postsolve`. If no solvers are linked the `solve` subcommand will fail and print an error message.\n\nNext we provide a small example of how the binary can be used to apply presolving and postsolving based on files.\n\nAssuming a problem instance is stored in the file `problem.mps` the following call will apply presolving with standard settings and write the reduced problem to `reduced.mps` and all information that is needed for postsolve to the binary archive `reduced.postsolve`.\n```\npapilo presolve -f problem.mps -r reduced.mps -v reduced.postsolve\n```\n_Not all presolver are able to dual-postsolve the dual solution (and the reduced costs and the basis information). Please use the settings file lp_presolvers_with_basis.set._\n\nNow we can use the reduced problem `reduced.mps` to obtain a solution\nusing any solver or from any other source to the file `reduced.sol`.\nThe format of the solution should be one value per line given like this:\n```\n\u003cvariable name\u003e        \u003cvalue\u003e\n```\nThis is compatible with the solutions given on the MIPLIB 2017 homepage https://miplib.zib.de and with the solutions written by the SCIP solver.\nVariable names that are not found in the reduced problem are ignored.\n\nThe command for applying the postsolve step to the solution `reduced.sol` is then\n```\npapilo postsolve -v reduced.postsolve -u reduced.sol -l problem.sol\n```\nGiving the parameter `-l problem.sol` is optional and will store the solution transformed to the original space under `problem.sol`.\nThe output of papilo contains some information about violations and objective value of the solution.\n\nIf PaPILO was linked to a suitable solver, then the above can also be achieved by using the `solve` subcommand like this:\n```\npapilo solve -f problem.mps -l problem.sol\n```\nThis will presolve the problem, pass the reduced problem to a solver, and subsequently transform back the optimal solution returned by the solver and write it to problem.sol.\n\n\u003e For the format of the solution and basis files please refer to Format.md\n\n\n# Using PaPILO as a library\n\nPaPILO provides a templated C++ interface that allows to specify the type used for numerical computations. During configuration time PaPILO scans the system and provides the fastest available numeric types for quadprecision and for exact rational arithmetic in the file\n`papilo/misc/MultiPrecision.hpp`. Including this file will currently introduce the types\n```\npapilo::Quad\npapilo::Float100\npapilo::Float500\npapilo::Float1000\npapilo::Rational\n```\nThe numeric type used by PaPILO will be referred to as REAL in the following section. It can be any of the above types as well as simply `double` for using standard double precision arithmetic.\n\nTo avoid confusion with types a short note on types like `papilo:Vec` and `papilo::String`.\nThose types are aliases for types from the standard library, `std::vector` and `std::string`, that possibly use an adjusted allocator. If nothing is altered regarding the allocator then the type `papilo::Vec` will be exactly the same as `std::vector`.\nIt can be changed by adding a partial specialization of `papilo::AllocatorTraits\u003cT\u003e` after including `papilo/misc/Alloc.hpp` but before including any other header of PaPILO.\n\nThe C++ interface for using PaPILO mainly revolves around the classes\n*   `papilo::Presolve\u003cREAL\u003e`, which controls the presolving routines,\n*   `papilo::Problem\u003cREAL\u003e`, which holds the problem instance, and\n*   `papilo::Postsolve\u003cREAL\u003e`, which can transform solutions in the reduced space into solutions for the original problem space.\nThe includes for those classes are under `papilo/core/{Problem,Postsolve,Presolve}.hpp`.\n\n## Creating an instance of `papilo::Problem\u003cREAL\u003e`\n\nThe PaPILO binary uses the MPS parsing routine to construct an instance of `papilo::Problem\u003cREAL\u003e` with the call `papilo::MpsParser\u003cREAL\u003e::loadProblem(\"problem.mps\")`.\n\nFor feeding a problem to PaPILO programmatically, there is the class\n`papilo::ProblemBuilder\u003cREAL\u003e`. This class allows to efficiently build an `papilo::Problem\u003cREAL\u003e` incrementally.\nThe problem definition that PaPILO supports does not use a row sense, but uses left and right hand sides $l$ and $u$ of rows defined as\n$\\text{l} \\leq a^\\top x \\leq \\text{u}$. For defining a row that is an equation with right hand side $b$ one has to set $l = u = b$. For inequalities either $l$ or $u$ are set to infinity.\nOne thing where PaPILO differs from many solvers is how infinite values are encoded. Whether for column bounds or left/right hand sides of rows PaPILO encodes the infinite value as a logical condition.\nThis ensures that regardless of numerical type used for `REAL`, that infinite values are always treated the same.\n\nThe member functions for initializing the rows and columns are\n```\nsetNumCols( int ncols )\nsetNumRows( int nrows )\n```\nAfter calling those functions the problem will have no nonzero entries but the given number of columns and rows. The left and right hand side values of rows the rows are set to $0$ as well as the lower and upper bounds of the columns. Additionally all columns are initialized as continuous columns.\n\nNext the following member functions can be used to alter the bound information about rows and columns as well as the objective coefficients and integrality flags of the columns.\n\n*   alter objective coefficient for columns\n    ```\n    setObj( int col, REAL val )\n    ```\n*   alter bound information for columns\n    ```\n    setColLb( int col, REAL lb )\n    setColLbInf( int col, bool isInfinite )\n    setColUb( int col, REAL ub )\n    setColUbInf( int col, bool isInfinite )\n    ```\n*   mark column to be restricted to integral values or not\n    ```\n    setColIntegral( int col, bool isIntegral )\n    ```\n*   alter left and right hand sides of rows\n    ```\n    setRowLhsInf( int row, bool isInfinite )\n    setRowRhsInf( int row, bool isInfinite )\n    setRowLhs( int row, REAL lhsval )\n    setRowRhs( int row, REAL rhsval )\n    ```\n*   set names of rows, columns, and the problem\n    ```\n    setRowName( int row, Str\u0026\u0026 name )\n    setColName( int col, Str\u0026\u0026 name )\n    setProblemName( Str\u0026\u0026 name )\n    ```\n\nAdding nonzeros to the problem can be done with individual nonzero values, row-based, or column-based using the following functions:\n```\n   /// add the nonzero entries for the given column\n   addColEntries( int col, int len, const int* rows, const R* vals )\n   /// add a nonzero entry for the given row and column\n   addEntry( int row, int col, const REAL\u0026 val )\n   /// add the nonzero entries for the given row\n   addRowEntries( int row, int len, const int* cols, const R* vals )\n```\nAll those functions can be called multiple times, but a nonzero entry for a particular column in a particular row should only be added once.\nFor maximum efficiency the member function\n`papilo::ProblemBuilder\u003cREAL\u003e::reserve(int nnz, int nrows, int ncols)` should be used to reserve all required memory before adding nonzeros.\n\nFinally calling `papilo::ProblemBuilder\u003cREAL\u003e::build()` will return an instance of `papilo::Problem\u003cREAL\u003e` with the information that was given to the builder. The builder can be reused afterwards.\n\n## Presolving an instance of `papilo::Problem\u003cREAL\u003e`\n\nFor this section we assume a problem instance is stored in a variable `problem` of type `papilo::Problem\u003cREAL\u003e`.\n\nIn order to presolve a problem instance we need to setup an instance of `papilo::Presolve\u003cREAL\u003e` and then call `papilo::Presolve\u003cREAL\u003e::apply(problem)`.\n\nThe same instance of `papilo::Presolve\u003cREAL\u003e` can be used for presolving multiple problem instances.\nIt stores the basic configuration of the presolving routine and constructing it with the default presolvers and settings to presolve the problem is straight forward:\n```\npapilo::Presolve\u003cREAL\u003e presolve;\npresolve.addDefaultPresolvers();\npapilo::PresolveResult\u003cREAL\u003e result = presolve.apply(problem);\n```\n\nAfter the above call `result.status` will contain an enum class of the following type:\n```\n/// result codes of a presolving routine\nenum class PresolveStatus : int\n{\n   /// problem was not changed\n   kUnchanged = 0,\n\n   /// problem was reduced\n   kReduced = 1,\n\n   /// problem was detected to be unbounded or infeasible\n   kUnbndOrInfeas = 2,\n\n   /// problem was detected to be unbounded\n   kUnbounded = 3,\n\n   /// problem was detected to be infeasible\n   kInfeasible = 4,\n};\n```\n\nAnd `result.postsolve` contains an instance of the class `papilo::Postsolve\u003cREAL\u003e`.\n\n## Postsolve of a solution in the reduced problem space\n\nFirst we construct a `papilo::Solution\u003cREAL\u003e` from a `papilo::Vec\u003cREAL\u003e` of reduced solution values and an empty instance of `papilo::Solution\u003cREAL\u003e` to hold the original space solution.\nThe interface here is not the simplest for the current functionality. It is like this to support\npostsolve of dual solutions in the future. The class `papilo::Solution\u003cREAL\u003e` cannot only hold primal solutions but also dual solution values, even though the postsolve routine does not yet support this step.\n\nObtaining the original space solution\n```\npapilo::Vec\u003cREAL\u003e reducedsolvals;\n...\n// set up the values of the reduced solution in the reduced index space\n...\n// create reduced solution and original solution\npapilo::Solution\u003cREAL\u003e reducedsol(std::move(reducedsolvals));\npapilo::Solution\u003cREAL\u003e origsol;\n\n// transform the reduced solution into the original problem space\nPostsolveStatus status = result.postsolve.undo(reducedsol, origsol, postsolve_storage);\n```\n\nThe value of `status` is `PostsolveStatus::kOk` if everything worked or `PostsolveStatus::kFail` otherwise.\nIf everything worked then the vector `origsol.primal` contains the primal solution values in the original problem space.\n\n# Presolve parameters\n\nThere are several parameters that can be adjusted to influence the behavior during presolving.\nAll the parameters and their default values are listed in the file `parameters.txt`.\nAdjusting a parameter via the command line when using the PaPILO exectuable works like this:\n```\npapilo solve -f problem.mps -l problem.sol --presolve.randomseed=42\n```\nThis call will use an adjusted random seed for the presolve routine.\n\nAlternatively a file with the same format as `parameters.txt` can be used to set multiple parameters by\npassing the setting file with the `-p`/`--parameter-settings` flag.\n\nPassing the `--print-params` flag will print the parameters in a format similar to the one of `parameters.txt` before starting presolving.\nThe printed parameters will have the values they were set to, not the default values.\n\nFor adjusting the parameters programatically there are two ways.\nThe first way is to obtain an instance of `papilo::ParameterSet` by calling `papilo::Presolve\u003cREAL\u003e::getParameters()`.\nIt is important to call this member function after all presolvers have been added to the `papilo::Presolve\u003cREAL\u003e` class.\nOtherwise, not all parameters are available, e.g. the ones that are added by individual presolvers.\nNow we can call `papilo::ParameterSet::setParameter( key, val )` to set parameters to their desired values.\n\nIf we want to adjust the random seed programmatically this would look like\n```\npapilo::Presolve\u003cREAL\u003e presolve;\n...\n// add all presolvers\n...\npapilo::ParameterSet paramset = presolve.getParameters();\nparamset.setParameter(\"presolve.randomseed\", 42);\n```\nThe function `papilo::ParameterSet::setParameter()` will throw exceptions if anything goes wrong,\ne.g. if the parameter key was not recognized or the type of the value is not suitable.\nPossible exceptions are of the types `std::out_of_range`, `std::domain_error`, or `std::invalid_argument` and contain a suitable error message.\nFor debugging it can be helpful to print the parameters stored within a `papilo::ParameterSet` which can be achieved by calling `paramset.printParams(std::cout)` and produces an output similar to the one in `parameters.txt`.\n\nThe second way to set a subset of parameters is by directly accessing the instance of `papilo::PresolveOptions` that is stored within each instance of `papilo::Presolve\u003cREAL\u003e`.\nSetting the random seed with this method can simply be achieved by `presolve.getPresolveOptions().randomseed = 42`.\nThe caveat with directly accessing the `papilo::PresolveOptions` is, that parameters added by individual presolvers cannot be set and that no error checking is performed in case the user sets a parameter to an invalid value.\nNevertheless, this can be convenient for setting basic things like tolerances, time limits, and thread limits.\n\n# Adding a presolver\n\nAdding a presolver to PaPILO requires the following steps. First create a class for your presolver that inherits publically from `papilo::PresolveMethod\u003cREAL\u003e`.\nIn the constructor at least adjust the name and the timing of the new presolver.\nFor the constraint propagation presolver this is done in the constructor by the following calls:\n```\nthis-\u003esetName( \"propagation\" );\nthis-\u003esetTiming( PresolverTiming::kFast );\n```\nUse the following rules to set a suitable value for `PresolverTiming`.\n* `PresolverTiming::kFast` for presolvers that work only on altered parts of the problem.\n  E.g. the constraint propagation presolver will only look at rows for which the activity was adjusted\n* `PresolverTiming::kMedium` for presolvers that run in $O(n \\log n)$ of the problem size (number of rows/columns/nonzeros).\n  E.g. the parallel row/column presolvers compute hash values and sort on the order of the rows and columns.\n  Technically the runtime becomes quadratic in the worst case when many collisions occur, but practically the presolvers are fast.\n  They are the slowest in the category of medium timing presolvers included in the default.\n* `PresolverTiming::kExhaustive` for presolvers that neither fit into the fast or medium categories\n\nIn addition, depending on the presolve method, it might be good to add restrictions on what type of problems a presolver is called.\nFor this the `setType(PresolveType)` member function of `papilo::PresolveMethod\u003cREAL\u003e` should be used.\nIf the type is set to `PresolverType::KIntegralCols` or `PresolverType::kContinuousCols` then the presolver only runs if integral or continuous columns are present respectively. The type `PresolverType::kMixedCols` runs only if both integral and continuous columns are present which is suitable for the implied integer detection presolver.\n\nFor presolve methods that require internal state two additional virtual member functions need to be overriden.\nAn example for this can be seen in the `papilo::Probing\u003cREAL\u003e` presolver.\nThe probing presolver stores how often a variable has been probed between calls.\nFor this it overrides the `papilo::PresolveMethod\u003cREAL\u003e::initialize()` member function which clears the internal data and\nadjusts it to the given problems dimension. The function must return a boolean value.\nThe value `false` indicates that the presolver does not need to be informed in case the index space of the columns changes\nand the value `true` indicates the opposite. When `true` is returned in the initialize member function `papilo::PresolveMethod\u003cREAL\u003e::compress()`\nshould additionally be overriden. The function is called with a mapping for the rows and columns and is called when\nPaPILO compresses the index space of the problem.\nIn the compress callback the probing presolver uses the given column mapping to compress the vector that stores how often each variable has been probed.\n\nIf the presolve method needs to add parameters that can be adjusted via the `papilo::ParameterSet`, then the member function `papilo::PresolveMethod\u003cREAL\u003e::addPresolverParams()` should be overridden.\n\nThe member function `papilo::PresolveMethod\u003cREAL\u003e::execute()` is a pure virtual function and therefore must be implemented for every presolve method.\nThis is where the presolver actually runs. The method grants read-only access to the `papilo::Problem\u003cREAL\u003e` that is being presolved\nand grants write access to an instance of `papilo::Reductions\u003cREAL\u003e`. A presolve method should scan the problem for possible reductions and add them\nto the reductions class. This is only the broad picture and there are some more details that we omit here for brevity.\nLooking at some of the default implemented presolvers can help for understanding further details and also the resources in the next section.\n\nFinally when a new presolve method is implemented it needs to be added to the `papilo::Presolve\u003cREAL\u003e` instance that is used for presolving.\nAssuming the new presolve method is called `MyPresolveMethod` this is achiev\ned by the following call:\n```\npresolve.addPresolver( std::unique_ptr\u003cpapilo::PresolveMethod\u003cREAL\u003e\u003e( new MyPresolveMethod\u003cREAL\u003e() ) );\n```\nGetting the PaPILO binary to call your presolver could be achieved by adding an include for your presolver in `papilo/core/Presolve.hpp` and then adding it together with the other default presolvers in the member function `papilo::Presolve\u003cREAL\u003e::addDefaultPresolvers()`.\n\n# Evaluating PaPILO #\n\n## Experiments ##\n\nYou can run your performance tests by executing the command `make test` in the root directory or sent the jobs to a slurm cluster with `make testcluster`.\n\nThe options of the make command are explained here:\n\n```\n  make test EXECUTABLE=build/bin/papilo TEST=short SETTINGS=default\n```\n- `EXECUTABLE` Location of the papilo executable from the root repository\n- `TEST` all instances  of the current experiments. File should be located at check/testset. For an example please refer to short.test.\n- `SETTINGS` settings file located in the settings folder\n- `PAPILO_SOLVE_COMMAND` `solve` or `presolve`\n- `TIME` timelimit\n- `MEM` maximal memory\n- `OUTPUTDIR` output directory where the results are stored\n- `QUEUE` queue (only make testcluster)\n\nThe make command generates an `.out` and `.err` file for each instance specified in the `TEST` file and in case of `make test` also an overall `out` file is created containing logs of all instances.\nIf `make testcluster` is used the overall `out` file must be generated with `./evalcheck_cluster.sh  results/name.eval`\n\nNote that the options all have default values. Executing a plain make test will run experiments on the short testset.\n\n\n# References and how to cite\n\nAny publication for which PaPILO is used must include an acknowledgement and a reference to the following article:\n```` \n@article{GGHpapilo,\nauthor    = {Ambros Gleixner and Leona Gottwald and Alexander Hoen},\npublisher = {INFORMS Journal on Computing},\ntitle     = {{PaPILO}: A Parallel Presolving Library for Integer and Linear Programming with Multiprecision Support},\nyear      = {2023},\njournal   = {INFORMS Journal on Computing},\ndoi       = {10.1287/ijoc.2022.0171.cd},\nurl =       {https://github.com/INFORMSJoC/2022.0171},\n}\n````\n\nMost of the presolve methods implemented in PaPILO are described in the paper \"Presolve Reductions in Mixed Integer Programming\" by Achterberg et al.\nwhich is available under https://opus4.kobv.de/opus4-zib/files/6037/Presolve.pdf.\n\nSome details on how PaPILO works internally are presented in a talk given during the SCIP workshop 2020 which has been recorded\nand is available under https://www.youtube.com/watch?v=JKAyyWXGeQM.\n\n# Licensing\n\nTo avoid confusion about licensing a short note on the LGPLv3.\nThis note is just an explanation and legally only the license text itself is of relevance.\n\nWhen PaPILO is used as a header-based library then only section 3 of LGPLv3 is relevant, and not section 4. Therefore PaPILO in that setting could be used in a software that is distributed under the terms of a different license when the conditions of section 3 are met, which are\n\n    a) Give prominent notice with each copy of the object code (refers to binary distributions of your software) that the Library (refers to PaPILO) is used in it and that the Library and its use are covered by this License (refers to the LGPLv3).\n    b) Accompany the object code with a copy of the GNU GPL and this license document.\n\nModifications of PaPILO itself, however, must be distributed under LGPLv3.\n\n# Contributors\n\n[Ambros Gleixner](https://www.zib.de/members/gleixner) ([@ambros-gleixner](https://github.com/ambros-gleixner)) \u0026mdash; project head\n\n[Alexander Hoen](https://www.zib.de/members/hoen)  ([@alexhoen](https://github.com/alexhoen)) \u0026mdash; main developer\n\n[Dominik Kamp](https://www.wm.uni-bayreuth.de/de/team/kamp_dominik/index.php)  ([@DominikKamp](https://github.com/DominikKamp)) \u0026mdash; developer\n\n\n#### Former Contributors\n\nIvet Galabova ([@galabovaa](https://github.com/galabovaa)) \u0026mdash; initial draft for dual postsolve\n\n[Leona Gottwald](https://www.zib.de/members/gottwald)  ([@lgottwald](https://github.com/lgottwald)) \u0026mdash; creator and former main developer\n\n[Katrin Halbig](https://www.datascience.nat.fau.eu/research/groups/amio/members/katrin-halbig/) ([@khalbig](https://github.com/khalbig)) \u0026mdash; presolver for GCD based reductions on inequalities (SimplifyIneq), strengthening in DualFix\n\nGabriel Kressin ([@GabrielKP](https://github.com/GabrielKP)) \u0026mdash; numerical statistics, testing\n\n[Julian Manns](https://www.zib.de/members/manns)  ([@ju-manns](https://github.com/ju-manns))  \u0026mdash; build system\n\nAnass Meskini \u0026mdash; general development and contributions to substitution presolver in terms of internship\n\n[Daniel Rehfeldt](https://www.zib.de/members/rehfeldt) ([@dRehfeldt](https://github.com/dRehfeldt)) \u0026mdash; core data structures and MPS parsing\n\n[Franziska Schlösser](https://www.zib.de/members/schloesser)  ([@fschloesser](https://github.com/fschloesser)) \u0026mdash; build system\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscipopt%2Fpapilo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscipopt%2Fpapilo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscipopt%2Fpapilo/lists"}