Skip to content

Commit d7302d8

Browse files
committed
Initial commit
0 parents  commit d7302d8

33 files changed

Lines changed: 2456 additions & 0 deletions

.github/workflows/build.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Build
2+
3+
on: [push]
4+
5+
jobs:
6+
7+
build:
8+
9+
runs-on: ${{ matrix.os }}
10+
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
os: [ubuntu-latest, windows-latest, macos-latest]
15+
python-version: ["3.8"]
16+
17+
env:
18+
SUBSET_SUM_DATA: ${{ github.workspace }}/data
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
- name: Set up Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v4
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
- name: Download data
28+
run: |
29+
python3 -m pip install -r requirements.txt
30+
python3 -u scripts/download_data.py
31+
- name: Build
32+
run: |
33+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
34+
cmake --build build --config Release --parallel
35+
cmake --install build --config Release --prefix install
36+
- name: Run unit tests
37+
run: ctest --test-dir build/test --parallel
38+
- name: Run tests
39+
run: python3 -u scripts/run_tests.py test_results
40+
- name: Checkout main branch
41+
run: |
42+
git remote set-branches origin '*'
43+
git fetch --depth 1
44+
git checkout main
45+
- name: Build
46+
run: |
47+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
48+
cmake --build build --config Release --parallel
49+
cmake --install build --config Release --prefix install
50+
- name: Run tests
51+
run: python3 -u scripts/run_tests.py test_results_ref
52+
- name: Process tests
53+
run: python3 -u ./build/_deps/optimizationtools-src/scripts/process_tests.py --ref test_results_ref --new test_results

CMakeLists.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
cmake_minimum_required(VERSION 3.15.0)
2+
3+
project(SubsetSum LANGUAGES CXX)
4+
5+
# Build options.
6+
option(SUBSETSUMSOLVER_BUILD_MAIN "Build main" ON)
7+
option(SUBSETSUMSOLVER_BUILD_TEST "Build the unit tests" ON)
8+
9+
# Avoid FetchContent warning.
10+
cmake_policy(SET CMP0135 NEW)
11+
12+
# Require C++11.
13+
set(CMAKE_CXX_STANDARD 11)
14+
15+
# Enable output of compile commands during generation.
16+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
17+
18+
# Add sub-directories.
19+
add_subdirectory(extern)
20+
add_subdirectory(src)
21+
add_subdirectory(test)

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Florian Fontan
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# SubsetSumSolver
2+
3+
A solver for the subset sum problem
4+
5+
## Implemented algorithms
6+
7+
* Dynamic programming
8+
* Bellman
9+
* Array `-a dynamic-programming-bellman-array`
10+
* List (only optimal value) `-a dynamic-programming-bellman-list`
11+
* Word RAM (only optimal value) `-a dynamic-programming-bellman-word-ram`
12+
* Word RAM with recursive scheme `-a dynamic-programming-bellman-word-ram-rec`
13+
* Balancing
14+
* Array (only optimal value) `-a dynamic-programming-balancing-array`
15+
16+
## Usage
17+
18+
### Command line
19+
20+
Compile:
21+
```shell
22+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
23+
cmake --build build --config Release --parallel
24+
cmake --install build --config Release --prefix install
25+
```
26+
27+
Download data:
28+
```shell
29+
python3 scripts/download_data.py
30+
```
31+
32+
Solve:
33+
```shell
34+
./install/bin/subsetsumsolver --verbosity-level 1 --input data/pthree/pthree_1000_1 --algorithm dynamic-programming-bellman-word-ram-rec
35+
```
36+
```
37+
====================================
38+
KnapsackSolver
39+
====================================
40+
41+
Problem
42+
-------
43+
Subset sum problem
44+
45+
Instance
46+
--------
47+
Number of items: 1000
48+
Capacity: 250000
49+
50+
Algorithm
51+
---------
52+
Dynamic programming - Bellman - word RAM - recursive scheme
53+
54+
Parameters
55+
----------
56+
Time limit: inf
57+
Messages
58+
Verbosity level: 1
59+
Standard output: 1
60+
File path:
61+
# streams: 0
62+
Logger
63+
Has logger: 0
64+
Standard error: 0
65+
File path:
66+
67+
Time (s) Sol. Value Bound Gap Gap (%) Comment
68+
-------- ---- ----- ----- --- ------- -------
69+
0.000 1 0 250000 250000 100.00
70+
0.033 1 250000 250000 0 0.00 algorithm end (solution)
71+
72+
Final statistics
73+
----------------
74+
Value: 250000
75+
Has solution: 1
76+
Bound: 250000
77+
Absolute optimality gap: 0
78+
Relative optimality gap (%): 0
79+
Time (s): 0.0330949
80+
81+
Solution
82+
--------
83+
Number of items: 484 / 1000 (48.4%)
84+
Weight: 250000 / 250000 (100%)
85+
Feasible: 1
86+
```
87+
88+
Run tests:
89+
```
90+
export SUBSET_SUM_DATA=$(pwd)/data
91+
cd build/test
92+
ctest --parallel
93+
```

extern/CMakeLists.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Enable FetchContent.
2+
include(FetchContent)
3+
4+
# Fetch boost.
5+
if(SUBSETSUMSOLVER_BUILD_MAIN OR SUBSETSUMSOLVER_BUILD_TEST)
6+
set(BOOST_INCLUDE_LIBRARIES thread filesystem system program_options)
7+
set(BOOST_ENABLE_CMAKE ON)
8+
FetchContent_Declare(
9+
Boost
10+
URL https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.xz
11+
EXCLUDE_FROM_ALL)
12+
FetchContent_MakeAvailable(Boost)
13+
endif()
14+
15+
# Fetch googletest.
16+
if(SUBSETSUMSOLVER_BUILD_TEST)
17+
FetchContent_Declare(
18+
googletest
19+
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip)
20+
# For Windows: Prevent overriding the parent project's compiler/linker settings
21+
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
22+
set(INSTALL_GTEST OFF)
23+
FetchContent_MakeAvailable(googletest)
24+
endif()
25+
26+
# Fetch fontanf/optimizationtools.
27+
set(OPTIMIZATIONTOOLS_BUILD_TEST OFF)
28+
FetchContent_Declare(
29+
optimizationtools
30+
GIT_REPOSITORY https://github.com/fontanf/optimizationtools.git
31+
GIT_TAG 4037a1a03f97ea0c388baa4f3f74c3ba55baec08
32+
#SOURCE_DIR "${PROJECT_SOURCE_DIR}/../optimizationtools/"
33+
EXCLUDE_FROM_ALL)
34+
FetchContent_MakeAvailable(optimizationtools)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#pragma once
2+
3+
#include "subsetsumsolver/solution.hpp"
4+
5+
namespace subsetsumsolver
6+
{
7+
8+
class AlgorithmFormatter
9+
{
10+
11+
public:
12+
13+
/** Constructor. */
14+
AlgorithmFormatter(
15+
const Parameters& parameters,
16+
Output& output):
17+
parameters_(parameters),
18+
output_(output),
19+
os_(parameters.create_os()) { }
20+
21+
/** Print the header. */
22+
void start(
23+
const std::string& algorithm_name);
24+
25+
/** Print the header. */
26+
void print_header();
27+
28+
/** Print current state. */
29+
void print(
30+
const std::string& s);
31+
32+
/** Update the solution. */
33+
void update_solution(
34+
const Solution& solution_new,
35+
const std::string& s);
36+
37+
/** Update the solution value. */
38+
void update_value(
39+
Weight value,
40+
const std::string& s);
41+
42+
/** Update the bound. */
43+
void update_bound(
44+
Weight bound_new,
45+
const std::string& s);
46+
47+
/** Method to call at the end of the algorithm. */
48+
void end();
49+
50+
private:
51+
52+
/** Parameters. */
53+
const Parameters& parameters_;
54+
55+
/** Output. */
56+
Output& output_;
57+
58+
/** Output stream. */
59+
std::unique_ptr<optimizationtools::ComposeStream> os_;
60+
61+
};
62+
63+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include "subsetsumsolver/solution.hpp"
4+
5+
namespace subsetsumsolver
6+
{
7+
8+
Output dynamic_programming_balancing_array(
9+
const Instance& instance,
10+
const Parameters& parameters = {});
11+
12+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#pragma once
2+
3+
#include "subsetsumsolver/solution.hpp"
4+
5+
namespace subsetsumsolver
6+
{
7+
8+
struct DynamicProgrammingBellmanArrayOutput: public Output
9+
{
10+
/** Constructor. */
11+
DynamicProgrammingBellmanArrayOutput(const Instance& instance):
12+
Output(instance)
13+
{ }
14+
15+
std::vector<ItemId> values;
16+
17+
bool is_reachable(Weight weight) const
18+
{
19+
return values[weight] != -1;
20+
}
21+
};
22+
23+
DynamicProgrammingBellmanArrayOutput dynamic_programming_bellman_array(
24+
const Instance& instance,
25+
const Parameters& parameters = {});
26+
27+
Output dynamic_programming_bellman_list(
28+
const Instance& instance,
29+
const Parameters& parameters = {});
30+
31+
struct DynamicProgrammingBellmanWordRamOutput: public Output
32+
{
33+
/** Constructor. */
34+
DynamicProgrammingBellmanWordRamOutput(const Instance& instance):
35+
Output(instance)
36+
{ }
37+
38+
std::vector<uint64_t> values;
39+
40+
bool is_reachable(Weight weight) const
41+
{
42+
Weight word = weight / 64;
43+
int bit = weight % 64;
44+
return (values[word] >> bit);
45+
}
46+
};
47+
48+
DynamicProgrammingBellmanWordRamOutput dynamic_programming_bellman_word_ram(
49+
const Instance& instance,
50+
const Parameters& parameters = {});
51+
52+
Output dynamic_programming_bellman_word_ram_rec(
53+
const Instance& instance,
54+
const Parameters& parameters = {});
55+
56+
}

include/subsetsumsolver/algorithms/dynamic_programming_primal_dual.hpp

Whitespace-only changes.

0 commit comments

Comments
 (0)