This is a Rust implementation that calculates subset sum problem using dynamic programming. It solves subset sum problem and returns a set of decomposed integers. It also can match corresponding numbers from two vectors and be used for Account reconciliation.
There are three ways to use this program. * CLI * Rust * Python
And it has three methods.
find_subset
Sequence Matcher (One-to-Many)
Sequence Matcher (Many-to-Many)
dpss
is short for dynamic programming subset sum
.
|Name|URL| |--|--| |github|https://github.com/europeanplaice/subsetsum| |crates.io|https://crates.io/crates/subsetsum| |docs.rs|https://docs.rs/subset_sum/latest/dpss/| |pypi|https://pypi.org/project/dpss/|
Binary files are provided on the Releases page. When you download one of these, please add it to your PATH manually.
First, you need to prepare a text file containing a set of integers like this
1
2
-3
4
5
and save it at any place.
Second, call subset_sum
with the path of the text file and the target sum.
Call subset_sum.exe num_set.txt 3
The executable's name subset_sum.exe
would be different from your choice. Change this example along with your environment.
In this example, the output is
[[2, 1], [4, -3, 2], [5, -3, 1]]
key.txt
3
5
7
targets.txt
1
5
-3
4
5
3
Call subset_sum.exe key.txt targets.txt
In this example, the output is
[(3, [3]), (5, [5]), (7, [5, 4, -3, 1])]
[(3, [3]), (5, [4, 1]), (7, [5, 5, -3])]
[(3, [5, -3, 1]), (5, [5]), (7, [3, 4])]
arr1.txt
1980
2980
3500
4000
1050
arr2.txt
1950
2900
30
80
3300
200
3980
1050
20
Call subset_sum.exe arr1.txt arr2.txt m2m 10 5
In this case, 10 is n_candidates
that is the number of candidates to be selected. A default value is 10.
5 is max_key_length
that is the maximum length of the keys as a group. A default value is 2.
In this example, the output is
[([1050], [1050]), ([1980], [30, 1950]), ([4000], [20, 3980]), ([2980], [80, 2900]), ([3500], [200, 3300])]
[([1980], [30, 1950]), ([2980], [80, 2900]), ([1050], [1050]), ([4000], [20, 3980]), ([3500], [200, 3300])]
[([1980], [30, 1950]), ([2980], [80, 2900]), ([3500], [200, 3300]), ([4000], [20, 3980]), ([1050], [1050])]
[([1980], [30, 1950]), ([2980], [80, 2900]), ([4000], [20, 3980]), ([3500], [200, 3300]), ([1050], [1050])]
[([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950]), ([4000], [20, 3980]), ([3500], [200, 3300])]
[([2980], [80, 2900]), ([4000], [20, 3980]), ([1050], [1050]), ([3500], [200, 3300]), ([1980], [30, 1950])]
[([3500], [200, 3300]), ([4000], [20, 30, 1050, 2900]), ([1050, 1980, 2980], [80, 1950, 3980])]
[([3500], [200, 3300]), ([4000], [20, 3980]), ([2980], [80, 2900]), ([1980], [30, 1950]), ([1050], [1050])]
[([4000], [20, 30, 1050, 2900]), ([3500], [200, 3300]), ([1050, 1980, 2980], [80, 1950, 3980])]
[([4000], [20, 3980]), ([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950]), ([3500], [200, 3300])]
[([4000], [20, 3980]), ([2980], [80, 2900]), ([1980], [30, 1950]), ([1050], [1050]), ([3500], [200, 3300])]
[([4000], [20, 3980]), ([3500], [200, 3300]), ([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950])]
There are a lot of combinations!
pip install dpss
```python import dpss print(dpss.find_subset([1, -2, 3, 4, 5], 2))
[[4, -2], [3, -2, 1]]
print(dpss.findsubsetfastonlypositive([1, 2, 3, 4, 5], 10))
[[4, 3, 2, 1], [5, 3, 2], [5, 4, 1]]
print(dpss.sequence_matcher([3, 5, 7], [1, 5, -3, 4, 5, 3]))
[[([3], 3), ([5], 5), ([5, 4, -3, 1], 7)], [([3], 3), ([4, 1], 5), ([5, 5, -3], 7)], [([5, -3, 1], 3), ([5], 5), ([3, 4], 7)]]
print(dpss.sequencematcherm2m([1980, 2980, 3500, 4000, 1050], [1950, 2900, 30, 80, 3300, 200, 3980, 1050, 20], 10, 5))
[[([1050], [1050]), ([1980], [30, 1950]), ([4000], [20, 3980]), ([2980], [80, 2900]), ([3500], [200, 3300])] [([1980], [30, 1950]), ([2980], [80, 2900]), ([1050], [1050]), ([4000], [20, 3980]), ([3500], [200, 3300])] [([1980], [30, 1950]), ([2980], [80, 2900]), ([3500], [200, 3300]), ([4000], [20, 3980]), ([1050], [1050])] [([1980], [30, 1950]), ([2980], [80, 2900]), ([4000], [20, 3980]), ([3500], [200, 3300]), ([1050], [1050])] [([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950]), ([4000], [20, 3980]), ([3500], [200, 3300])] [([2980], [80, 2900]), ([4000], [20, 3980]), ([1050], [1050]), ([3500], [200, 3300]), ([1980], [30, 1950])] [([3500], [200, 3300]), ([4000], [20, 30, 1050, 2900]), ([1050, 1980, 2980], [80, 1950, 3980])] [([3500], [200, 3300]), ([4000], [20, 3980]), ([2980], [80, 2900]), ([1980], [30, 1950]), ([1050], [1050])] [([4000], [20, 30, 1050, 2900]), ([3500], [200, 3300]), ([1050, 1980, 2980], [80, 1950, 3980])] [([4000], [20, 3980]), ([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950]), ([3500], [200, 3300])] [([4000], [20, 3980]), ([2980], [80, 2900]), ([1980], [30, 1950]), ([1050], [1050]), ([3500], [200, 3300])] [([4000], [20, 3980]), ([3500], [200, 3300]), ([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950])]] ```
Please check https://crates.io/crates/subset_sum.
Cargo.toml
[dependencies]
subset_sum = "(version)"
main.rs
```rust
use subsetsum::dp::findsubset;
fn main() {
let result = find_subset(&mut vec![1, 2, 3, 4, 5], 6);
println!("{:?}", result);
}
Output
[[3, 2, 1], [4, 2], [5, 1]]
```
main.rs
```rust
use subsetsum::dp::sequencematcher;
fn main() {
let result = sequence_matcher(&mut vec![3, 5, 7], &mut vec![1, 5, -3, 4, 5, 3]);
println!("{:?}", result);
}
Output
[
[(3, [3]), (5, [5]), (7, [5, 4, -3, 1])]
[(3, [3]), (5, [4, 1]), (7, [5, 5, -3])]
[(3, [5, -3, 1]), (5, [5]), (7, [3, 4])]
]
```
main.rs
```rust
use subsetsum::dp::sequencematcher_m2m;
fn main() {
let result = sequencematcherm2m(&mut vec![1980, 2980, 3500, 4000, 1050], &mut vec![1950, 2900, 30, 80, 3300, 200, 3980, 1050, 20], 10, 5);
println!("{:?}", result);
}
Output
[([1050], [1050]), ([1980], [30, 1950]), ([4000], [20, 3980]), ([2980], [80, 2900]), ([3500], [200, 3300])]
[([1980], [30, 1950]), ([2980], [80, 2900]), ([1050], [1050]), ([4000], [20, 3980]), ([3500], [200, 3300])]
[([1980], [30, 1950]), ([2980], [80, 2900]), ([3500], [200, 3300]), ([4000], [20, 3980]), ([1050], [1050])]
[([1980], [30, 1950]), ([2980], [80, 2900]), ([4000], [20, 3980]), ([3500], [200, 3300]), ([1050], [1050])]
[([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950]), ([4000], [20, 3980]), ([3500], [200, 3300])]
[([2980], [80, 2900]), ([4000], [20, 3980]), ([1050], [1050]), ([3500], [200, 3300]), ([1980], [30, 1950])]
[([3500], [200, 3300]), ([4000], [20, 30, 1050, 2900]), ([1050, 1980, 2980], [80, 1950, 3980])]
[([3500], [200, 3300]), ([4000], [20, 3980]), ([2980], [80, 2900]), ([1980], [30, 1950]), ([1050], [1050])]
[([4000], [20, 30, 1050, 2900]), ([3500], [200, 3300]), ([1050, 1980, 2980], [80, 1950, 3980])]
[([4000], [20, 3980]), ([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950]), ([3500], [200, 3300])]
[([4000], [20, 3980]), ([2980], [80, 2900]), ([1980], [30, 1950]), ([1050], [1050]), ([3500], [200, 3300])]
[([4000], [20, 3980]), ([3500], [200, 3300]), ([2980], [80, 2900]), ([1050], [1050]), ([1980], [30, 1950])]
```