Skip to content

Commit a3f1089

Browse files
committed
Test that M(subsequence(X)) <= M(X) for most probes
1 parent 45f01fe commit a3f1089

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

docs/Measures-of-disorder.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ Computes the minimum number of exchanges required to sort $X$, which corresponds
217217

218218
`max_for_size`: $|X| - 1$ when every element in $X$ is one element away from its sorted position.
219219

220+
**Note:** *Exc* does not respect Mannila's criterion 3 (a subsequence contains no more disorder than the whole sequence): $Exc(\langle 3, 1, 2, 0 \rangle) = 1$, but $Exc(\langle 3, 1, 2 \rangle) = 2$.
221+
220222
*Warning: this algorithm might be noticeably slower when the passed range is not random-access.*
221223

222224
### *Ham*
@@ -233,7 +235,9 @@ Computes the number of elements in $X$ that are not in their sorted position, wh
233235

234236
`max_for_size`: $|X|$ when every element in $X$ is one element away from its sorted position.
235237

236-
**Note:** *Ham* does not respect Mannila's criterion 5: $Ham(\langle 4, 1, 2, 3 \rangle) \not \le |\langle 1, 2, 3 \rangle| + Ham(\langle 1, 2, 3 \rangle)$.
238+
**Note:** *Ham* does not respect Mannila's criterion 3 (a subsequence contains no more disorder than the whole sequence): $Ham(\langle 3, 1, 2, 0 \rangle) = 2$, but $Ham(\langle 3, 1, 2 \rangle) = 3$.
239+
240+
**Note²:** *Ham* does not respect Mannila's criterion 5: $Ham(\langle 4, 1, 2, 3 \rangle) \not \le |\langle 1, 2, 3 \rangle| + Ham(\langle 1, 2, 3 \rangle)$.
237241

238242
### *Inv*
239243

tests/probes/every_probe_common.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,45 @@ TEMPLATE_TEST_CASE( "test order isomorphism for every probe", "[probe]",
140140
});
141141
}
142142

143+
TEMPLATE_TEST_CASE( "test M(subsequence(X)) <= M(X) for most probes M", "[probe]",
144+
decltype(cppsort::probe::block),
145+
decltype(cppsort::probe::dis),
146+
decltype(cppsort::probe::enc),
147+
decltype(cppsort::probe::inv),
148+
decltype(cppsort::probe::max),
149+
decltype(cppsort::probe::mono),
150+
decltype(cppsort::probe::osc),
151+
decltype(cppsort::probe::rem),
152+
decltype(cppsort::probe::runs),
153+
decltype(cppsort::probe::spear),
154+
decltype(cppsort::probe::sus) )
155+
{
156+
// Third property formalized by Mannila
157+
// Ensure that the disorder that exists in a subsequence is no
158+
// greater than the disorder that exists in the whole sequence
159+
160+
rc::prop("M(subsequence(X)) ≤ M(X)", [](std::vector<int> sequence) {
161+
std::decay_t<TestType> measure;
162+
auto disorder_x = measure(sequence);
163+
164+
std::uniform_int_distribution<int> uni(0, sequence.size());
165+
166+
using diff_t = std::vector<int>::difference_type;
167+
using param_t = std::uniform_int_distribution<diff_t>::param_type;
168+
std::uniform_int_distribution<diff_t> dist;
169+
170+
diff_t size = sequence.size();
171+
auto number_of_elements_to_remove = dist(hasard::engine(), param_t{0, size});
172+
for (; number_of_elements_to_remove > 0; --number_of_elements_to_remove) {
173+
auto idx = dist(hasard::engine(), param_t{0, size - 1});
174+
sequence.erase(sequence.begin() + idx);
175+
--size;
176+
}
177+
178+
return measure(sequence) <= disorder_x;
179+
});
180+
}
181+
143182
TEMPLATE_TEST_CASE( "test M(aX) <= |X| + M(X) for most probes M", "[probe]",
144183
decltype(cppsort::probe::block),
145184
decltype(cppsort::probe::dis),

tests/probes/exc.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,12 @@ TEST_CASE( "measure of disorder: exc", "[probe][exc]" )
5656
const std::vector<int> collection = { 0, 0, -1 };
5757
CHECK( exc(collection) == 1 );
5858
}
59+
60+
SECTION( "Example of Exc(subsequence(X)) > Exc(X)" )
61+
{
62+
const std::forward_list<int> seq = { 3, 1, 2, 0 };
63+
const std::forward_list<int> subseq = { 3, 1, 2 };
64+
CHECK( exc(seq) == 1 );
65+
CHECK( exc(subseq) == 2 );
66+
}
5967
}

tests/probes/ham.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ TEST_CASE( "measure of disorder: ham", "[probe][ham]" )
4949
CHECK( ham(collection) == 0 );
5050
}
5151

52+
SECTION( "Example of Ham(subsequence(X)) > Ham(X)" )
53+
{
54+
const std::forward_list<int> seq = { 3, 1, 2, 0 };
55+
const std::forward_list<int> subseq = { 3, 1, 2 };
56+
CHECK( ham(seq) == 2 );
57+
CHECK( ham(subseq) == 3 );
58+
}
59+
5260
rc::prop("Ham(X) ≠ 1", [](const std::vector<int>& sequence) {
5361
return cppsort::probe::ham(sequence) != 1;
5462
});

0 commit comments

Comments
 (0)