This replaces the dependencies and development
If on Ubuntu, install dependencies with:
./dependenciesfollowing the prompt instructions and typing in password for sudo (might have to exit and reopen shell) TODO: source cargo env
Then run the formatter + build in release mode with
makeThen install the pengwin binary with
sudo make installNow you can run the solver with
pengwin <SUBCOMMAND> [OPTIONS]It is recommended to use Linux or WSL since we use coin-or cbc, which is easier to set up on Linux.
First, install Rust using rustup by following the instructions on the website, by running
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shNext, install coin-or cbc, the LP solver we currently use by either running the below (for Linux) or following the instructions on their repo
sudo apt-get install coinor-cbc coinor-libcbc-devYou will need a C compiler:
sudo apt-get install gccIf you want to access the api:
sudo apt-get install pkg-config libssl-devThis command builds and runs the project
cargo run --release -- <SUBCOMMAND>OR equivalently,first build the project with
cargo build --releaseThen, in the root of the directory (or ensuring the inputs folder is in the same directory), run
./target/release/penguin-project <SUBCOMMAND>Or equivalently (this builds it for you)
This lists all available solvers
USAGE:
... api <size>Where size can be
- small (s)
- medium (m)
- large (l)
This queries the 170 leader board API to find which outputs have better/worse scores than the current ones.
The API is limited to 5 QPS, so the output pauses sometimes
USAGE:
... solve [OPTIONS] -s <SOLVER> <PATHS>..Where you can input any number of PATH arguments, each one in the form <size>/<ids>
<size>can besmall,medium, orlarge<ids>can be a single id or a range of ids
OPTIONS:
-wonly runs the solver on provided inputs we are worse than
solve -s lp large runs the lp solver on everything in the large folder
solve -s greedy small/1..220 medium/1 runs the greedy solver on ids 001 through 220 in the small folder and id 001 in the medium
solve -s benchmark small/1..40 -w runs the benchmark solver on small ids 001 through 040 that we are worse (higher) than
NOTE: We used a combination of rand_hillclimb and hillclimb to generate most outputs, as well as tuning some by hand. As a result, your results may vary when trying to run our solver as it inherently relies on randomness to generate solutions.
A github workflow runs rustfmt whenever pushing to main or creating a pull request to main but its a good idea to install and run:
rustup component add rustfmt
cargo fmtOn the Nightly toolchain (to support features on the rustfmt.toml):
rustup toolchain install nightly
rustup component add rustfmt --toolchain nightly
cargo +nightly fmtIn addition to the above, we used the following crates/libraries:
good_lp |
Github | Docs |
clap |
Derive Doc | Derive Tutorial |
pfh |
Documentation | |
rustfmt-check |
Github | Actions Marketplace |
rustfmt |
Github | Toml Docs |
argmin |
Github | Docs |
rayon |
Github | Docs |
First install poetry and if prompted add the directory to the path.
sudo apt install python3-tk python3-pip
pip install poetry
# add given path to bashrc
echo "export PATH='/home/<>/.local/bin:$PATH'" > .bashrc
source .bashrcThen in the project root
poetry install
poetry run gui <INPUT>Where input is in the form small/3
This saves the current solution (if it has one) to edited/small/003.out and further edits are saved there
NOTE: ADDING DOES NOT WORK DO NOT TRY IT UNLESS NOT ZOOMED
A Python skeleton is available in the python subdirectory. The Python
skeleton was developed using Python 3.9, but it should work with Python
versions 3.6+.
To generate instances, read through python/instance.py,
which contains a dataclass (struct) that holds the data for an instance, as
well as other relevant methods. Then modify the
python/generate.py file by filling in the
make_{small,medium,large}_instance functions.
After you have filled in those functions, you can run make generate in the
python directory to generate instances into the input directory.
To run unit tests, run make check.
We've created a solver skeleton at python/solve.py.
python3 solve.py case.in --solver=naive case.outWe've also created a skeleton that runs your solver on all cases and puts them
in the output directory. To use it, modify
python/solve_all.py to use your solver function(s).
Then run
python3 python/solve_all.py inputs outputs
in the root directory.
To merge multiple output folders, taking the best solutions, see
python/merge.py.
To visualize problem instances, run python3 visualize.py, passing in the
path to your .in file as the first argument (or - to read from standard
input). To visualize a solution as well, pass in a .out file to the option
--with-solution.
By default, the output visualization will be written as a SVG file to standard output. To redirect it to a file, use your shell's output redirection or pass in an output file as an additional argument.
For example, you could run
python3 visualize.py my_input.in out.svgto create an out.svg file visualizing the my_input.in problem instance.
To visualize a solution file for this instance as well, you could run
python3 visualize.py my_input.in --with-solution my_soln.out out.svg