Skip to content

Commit b00b854

Browse files
authored
Merge pull request #8 from Benezivas/develop
Develop
2 parents 1a485a4 + a27f718 commit b00b854

File tree

46 files changed

+453
-369
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+453
-369
lines changed

.github/workflows/python-app.yml

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
# This workflow will install Python dependencies, run tests and lint with a single version of Python
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3-
4-
name: Algorithmic Battle - Problem Files
1+
name: Algorithmic Battle
52

63
on:
74
push:
@@ -10,31 +7,61 @@ on:
107
branches: [ main, develop ]
118

129
jobs:
13-
build:
14-
10+
lint:
1511
runs-on: ubuntu-latest
16-
1712
steps:
1813
- uses: actions/checkout@v2
19-
- name: Set up Python 3.9
14+
- name: Set up Python 3.6
2015
uses: actions/setup-python@v2
2116
with:
22-
python-version: 3.9
17+
python-version: 3.6
2318
- name: Install dependencies
2419
run: |
2520
python -m pip install --upgrade pip
2621
pip install flake8 flake8-docstrings
27-
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
28-
git clone https://github.com/Benezivas/algobattle.git
29-
cd algobattle && pip install . --user && cd ..
3022
- name: Lint with flake8
3123
run: |
32-
# stop the build if there are Python syntax errors or undefined names
33-
flake8 . --count --exit-zero --select=E9,F63,F7,F82 --show-source --statistics --exclude algobattle
34-
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
35-
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics \
36-
--per-file-ignores="__init__.py:F401,D104 */solver/main.py:D100 */generator/main.py:D100" \
37-
--docstring-convention numpy --ignore=D100,D105,D102,W503 --exclude algobattle
38-
- name: Test with unittest
24+
flake8 . --count --max-complexity=10 --max-line-length=127 \
25+
--per-file-ignores="__init__.py:F401,D104 */solver_execution_error/main.py:E999 \
26+
*/generator_execution_error/main.py:E999 match.py:E221 setup.py:D102,D100 \
27+
*/verifier.py:D102 */parser.py:D102 tests/*:D102 tests/__init__.py:D104 \
28+
scripts/battle:E501,C901" \
29+
--docstring-convention numpy --show-source --statistics --ignore=D105,D401,W503
30+
31+
test:
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@v2
35+
- name: Set up Python 3.6
36+
uses: actions/setup-python@v2
37+
with:
38+
python-version: 3.6
39+
- name: Test using unittests
3940
run: |
41+
git clone https://github.com/Benezivas/algobattle.git
42+
cd algobattle && pip install . --user && cd ..
4043
python -m unittest
44+
45+
execute:
46+
runs-on: ubuntu-latest
47+
steps:
48+
- uses: actions/checkout@v2
49+
- name: Set up Python 3.6
50+
uses: actions/setup-python@v2
51+
with:
52+
python-version: 3.6
53+
- name: Install dependencies
54+
run: |
55+
git clone https://github.com/Benezivas/algobattle.git
56+
cd algobattle && pip install . --user && cd ..
57+
- name: Run short battles with different options as a sanity check
58+
run: |
59+
$HOME/.local/bin/battle problems/biclique --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation
60+
$HOME/.local/bin/battle problems/c4subgraphiso --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation
61+
$HOME/.local/bin/battle problems/clusterediting --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation
62+
$HOME/.local/bin/battle problems/domset --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation
63+
$HOME/.local/bin/battle problems/hikers --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation
64+
$HOME/.local/bin/battle problems/oscm3 --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation
65+
$HOME/.local/bin/battle problems/pairsum --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation
66+
$HOME/.local/bin/battle problems/pathpacking --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation
67+
$HOME/.local/bin/battle problems/scheduling --verbose --iter_cap=10 --rounds=2 --no_overhead_calculation

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
**/__pycache__
2+
.vscode/*

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
# Algorithmic Battle: Problems
22
Collection of problems to be used in the [algobattle](https://github.com/Benezivas/algobattle) project.
33

4+
This repository contains several problem tasks that you may use for your
5+
students. Each problem directory contains a `README.md` describing the problem
6+
and the I/O that the generator and solver use. The `generator` and `solver`
7+
directories contain dummy solvers that output instances which are technically
8+
legal, but rather unexiting.
9+
10+
The simplest problem is currently the `pairsum` problem, which is well suited
11+
as a primer task at the start of the lab. For this task, a simple randomized generator and solver are
12+
implemented which you may use to see how the program behaves when the
13+
solver runs into a timeout at some instance size.
14+
415
# Setup and Usage
516
Clone the [algobattle](https://github.com/Benezivas/algobattle) repository:
617
```

problems/biclique/generator/main.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
fin = open("input")
2-
fout = open("output", "w")
3-
n = int(fin.readline())
4-
5-
fout.write("e 1 2\n")
6-
fout.write("e 1 3\n")
7-
fout.write("e 1 4\n")
8-
fout.write("s set1 1\n")
9-
fout.write("s set2 2\n")
10-
fout.write("s set2 3\n")
11-
fout.write("s set2 4\n")
12-
fout.close()
1+
"""Simple dummy generator for the BiClique problem, outputting a static instance."""
2+
with open("output", "w") as output:
3+
output.write("e 1 2\n")
4+
output.write("e 1 3\n")
5+
output.write("e 1 4\n")
6+
output.write("s set1 1\n")
7+
output.write("s set2 2\n")
8+
output.write("s set2 3\n")
9+
output.write("s set2 4\n")

problems/biclique/problem.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""The Biclique problem class."""
12
import logging
23

34
from algobattle.problem import Problem

problems/biclique/solver/main.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
fin = open("input")
2-
line = fin.readline()
3-
4-
fout = open("output", "w")
5-
fout.write("s set1 1\n")
6-
fout.write("s set2 2\n")
7-
fout.write("s set2 3\n")
8-
fout.write("s set2 4\n")
9-
fout.close()
1+
"""Simple dummy solver for the BiClique problem, outputting a static solution."""
2+
with open("output", "w") as output:
3+
output.write("s set1 1\n")
4+
output.write("s set2 2\n")
5+
output.write("s set2 3\n")
6+
output.write("s set2 4\n")
Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
fin = open("input")
2-
fout = open("output", "w")
3-
n = int(fin.readline())
4-
5-
fout.write("s 1 2 3 4\n")
6-
fout.write("e 4 1\n")
7-
fout.write("e 1 2\n")
8-
fout.write("e 2 3\n")
9-
fout.write("e 3 4\n")
10-
fout.close()
1+
"""Simple dummy generator for the C4SubGraphIso problem, outputting a static instance."""
2+
with open("output", "w") as output:
3+
output.write("s 1 2 3 4\n")
4+
output.write("e 4 1\n")
5+
output.write("e 1 2\n")
6+
output.write("e 2 3\n")
7+
output.write("e 3 4\n")

problems/c4subgraphiso/problem.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""The C4subgraphiso problem class."""
12
import logging
23

34
from algobattle.problem import Problem

problems/c4subgraphiso/solver/main.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
fin = open("input")
2-
line = fin.readline()
3-
4-
fout = open("output", "w")
5-
fout.write("s 1 2 3 4\n")
6-
fout.close()
1+
"""Simple dummy solver for the C4SubGraphIso problem, outputting a static solution."""
2+
with open("output", "w") as output:
3+
output.write("s 1 2 3 4\n")

problems/c4subgraphiso/verifier.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ def verify_semantics_of_solution(self, solution, instance_size: int, solution_ty
2424
return True
2525

2626
def square_in_instance(self, square, instance):
27+
"""Check if a given square is part of the given instance.
28+
29+
Parameters
30+
----------
31+
square : tuple
32+
A tuple of the form (i,j,k,l) which are sequentially connected to form a square.
33+
instance : list
34+
A list of tuples of edges, each edge {i, j} is given as ('e', 'i', 'j').
35+
36+
Returns
37+
-------
38+
bool
39+
True if the square is part of the instance, False otherwise.
40+
"""
2741
if (not (('e', square[0], square[1]) in instance or ('e', square[1], square[0]) in instance)
2842
or not (('e', square[1], square[2]) in instance or ('e', square[2], square[1]) in instance)
2943
or not (('e', square[2], square[3]) in instance or ('e', square[3], square[2]) in instance)
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
fin = open("input")
2-
fout = open("output", "w")
3-
n = int(fin.readline())
4-
5-
fout.write("e 1 2\ne 3 2\ne 1 4\ns del 1 4\ns add 1 3")
6-
fout.close()
1+
"""Simple dummy generator for the ClusterEditing problem, outputting a static instance."""
2+
with open("output", "w") as output:
3+
output.write("e 1 2\ne 3 2\ne 1 4\ns del 1 4\ns add 1 3")

problems/clusterediting/problem.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""The Clusterediting problem class."""
12
import logging
23

34
from algobattle.problem import Problem
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
fin = open("input")
2-
line = fin.readline()
3-
4-
fout = open("output", "w")
5-
fout.write("s add 1 3\ns del 1 4")
6-
fout.close()
1+
"""Simple dummy solver for the ClusterEditing problem, outputting a static solution."""
2+
with open("output", "w") as output:
3+
output.write("s add 1 3\ns del 1 4")

problems/domset/generator/main.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
fin = open("input")
2-
fout = open("output", "w")
3-
n = int(fin.readline())
4-
5-
fout.write("s 1\ns 4\ne 1 2\ne 2 3\ne 3 4\ne 4 5\ne 5 6\ne 6 1\ne 2 6\ne 3 5")
6-
fout.close()
1+
"""Simple dummy generator for the DomSet problem, outputting a static instance."""
2+
with open("output", "w") as output:
3+
output.write("s 1\ns 4\ne 1 2\ne 2 3\ne 3 4\ne 4 5\ne 5 6\ne 6 1\ne 2 6\ne 3 5")

problems/domset/problem.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""The DomSet problem class."""
12
import logging
23

34
from algobattle.problem import Problem

problems/domset/solver/main.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
fin = open("input")
2-
line = fin.readline()
3-
4-
fout = open("output", "w")
5-
fout.write("s 1\ns 4")
6-
fout.close()
1+
"""Simple dummy solver for the DomSet problem, outputting a static solution."""
2+
with open("output", "w") as output:
3+
output.write("s 1\ns 4")

problems/hikers/generator/main.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
fin = open("input")
2-
fout = open("output", "w")
3-
n = int(fin.readline())
4-
5-
fout.write("s 1 1\ns 4 1\ns 5 1\ns 3 2\nh 1 1 3\nh 2 10 12\nh 3 1 1\nh 4 2 5\nh 5 3 3")
6-
fout.close()
1+
"""Simple dummy generator for the Hikers problem, outputting a static instance."""
2+
with open("output", "w") as output:
3+
output.write("s 1 1\ns 4 1\ns 5 1\ns 3 2\nh 1 1 3\nh 2 10 12\nh 3 1 1\nh 4 2 5\nh 5 3 3")

problems/hikers/problem.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""The Hikers problem class."""
12
import logging
23

34
from algobattle.problem import Problem

problems/hikers/solver/main.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
fin = open("input")
2-
line = fin.readline()
3-
4-
fout = open("output", "w")
5-
fout.write("s 3 1\ns 1 2\ns 4 2\ns 5 2")
6-
fout.close()
1+
"""Simple dummy solver for the Hikers problem, outputting a static solution."""
2+
with open("output", "w") as output:
3+
output.write("s 3 1\ns 1 2\ns 4 2\ns 5 2")

problems/oscm3/generator/main.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
fin = open("input")
2-
fout = open("output", "w")
3-
n = int(fin.readline())
4-
5-
for i in range(n):
6-
fout.write("n {}\n".format(i))
7-
fout.write("s ")
8-
for i in range(n):
9-
fout.write("{} ".format(i))
10-
fout.close()
1+
"""Simple dummy generator for the OSCM3 problem, outputting a trivial instance."""
2+
n = 0
3+
with open("input", "r") as input:
4+
n = int(input.readline())
5+
with open("output", "w") as output:
6+
for i in range(n):
7+
output.write("n {}\n".format(i))
8+
output.write("s ")
9+
for i in range(n):
10+
output.write("{} ".format(i))

problems/oscm3/parser.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ def split_into_instance_and_solution(self, raw_input):
2222
return raw_instance, raw_solution
2323

2424
def is_instance_line_clean(self, line, instance_size):
25+
"""Checks whether a given line of the instance is of the required form.
26+
27+
Parameters
28+
----------
29+
line : tuple
30+
The line to be checked. Expected to be of the form ('n', 'i', 'j', 'k', 'l')
31+
where the last three entries are optional. Consult the README for more information.
32+
instance_size : int
33+
The size of the instance.
34+
35+
Returns
36+
-------
37+
bool
38+
True if the line is well-formatted, False otherwise.
39+
"""
2540
clean = True
2641
included_nodes = set()
2742
for entry in line[2:]:

problems/oscm3/problem.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""The OSCM3 problem class."""
12
import logging
23

34
from algobattle.problem import Problem

problems/oscm3/solver/main.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
with open("input") as fin:
2-
lines = []
3-
for line in fin:
1+
"""Simple dummy solver for the OSCM3 problem, outputting a trivial solution."""
2+
lines = []
3+
with open("input", "r") as input:
4+
for line in input:
45
lines.append(line)
56
n = len(lines)
67

7-
fout = open("output", "w")
8-
fout.write("s ")
9-
for i in range(n):
10-
fout.write("{} ".format(i))
11-
fout.close()
8+
with open("output", "w") as output:
9+
output.write("s ")
10+
for i in range(n):
11+
output.write("{} ".format(i))

0 commit comments

Comments
 (0)