Skip to content

Commit 8381988

Browse files
authored
Merge pull request #74 from cicirello/development
Minor bug fixes and improved test coverage
2 parents e3a86d8 + 0ef35af commit 8381988

35 files changed

+1193
-608
lines changed

CHANGELOG.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,40 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [Unreleased] - 2021-01-27
7+
## [Unreleased] - 2021-01-30
88

99
### Added
1010

1111
### Changed
12-
* Modified API documentation website (https://jpt.cicirello.org/) to improve browsing on mobile devices.
1312

1413
### Deprecated
1514

15+
### Removed
16+
17+
### Fixed
18+
19+
### CI/CD
20+
21+
22+
## [2.3.0] - 2021-01-30
23+
24+
### Added
25+
* Test cases added to improve test coverage.
26+
27+
### Changed
28+
* Modified API documentation website (https://jpt.cicirello.org/) to improve browsing on mobile devices.
29+
* Minor optimizations in Permutation class.
30+
1631
### Removed
1732
* Moved the example programs to a new repository. They were previously found in directories examples and replication, both of which have been removed. All of the examples are now located in the repository: https://github.com/cicirello/jpt-examples.
1833
* Removed jars of the library from the repo. These have been available from Maven Central, GitHub Packages, and GitHub Releases, for quite some time. No need to store in repo, and it is inefficient to do so.
1934
* Removed the zip files generated by javadoc of the indexes for the api website. These are not needed for search functionality, as javadoc also stores and uses the js files contained in these zips. Later versions of javadoc no longer generate these. Also gitignored these to prevent future storage.
2035

2136
### Fixed
37+
* Bug in Permutation.toString which was inserting an extra space at end.
38+
* Added validation checking for all permutation distance measures validating same length permutations (except for EditDistance which can handle that case).
39+
* Bug in ReversalDistance.max in case when permutation length is 2, and also added missing parameter validation.
40+
* Minor bug fix in KendallTauSequenceDistance in the case of distance between arrays of floats.
2241

2342
### CI/CD
2443
* Migrated build process from Ant to Maven, including GitHub workflows.

src/org/cicirello/permutations/Permutation.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2005, 2010, 2014-2019 Vincent A. Cicirello, <https://www.cicirello.org/>.
2+
* Copyright 2005, 2010, 2014-2021 Vincent A. Cicirello, <https://www.cicirello.org/>.
33
*
44
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
55
*
@@ -38,8 +38,7 @@
3838
* manipulate permutations in a variety of ways.
3939
*
4040
* @author <a href=https://www.cicirello.org/ target=_top>Vincent A. Cicirello</a>, <a href=https://www.cicirello.org/ target=_top>https://www.cicirello.org/</a>
41-
* @version 9.23.2019
42-
* @since 1.0
41+
* @version 1.28.2021
4342
*/
4443
public final class Permutation implements Serializable, Iterable<Permutation>, Copyable<Permutation> {
4544

@@ -777,7 +776,7 @@ public void removeAndInsert(int i, int size, int j) {
777776
System.arraycopy(permutation, j, temp, 0, i-j);
778777
System.arraycopy(permutation, i, permutation, j, size);
779778
System.arraycopy(temp, 0, permutation, j+size, i-j);
780-
} else if (i < j) {
779+
} else { // Condition is implied by above: if (i < j)
781780
int[] temp = new int[size];
782781
System.arraycopy(permutation, i, temp, 0, size);
783782
System.arraycopy(permutation, i+size, permutation, i, j-i);
@@ -828,8 +827,11 @@ public Iterator<Permutation> iterator() {
828827
@Override
829828
public String toString() {
830829
String permS = "";
831-
for (int i : permutation) {
832-
permS += (i + " ");
830+
if (permutation.length > 0) {
831+
permS += permutation[0];
832+
for (int i = 1; i < permutation.length; i++) {
833+
permS += " " + permutation[i];
834+
}
833835
}
834836
return permS;
835837
}

src/org/cicirello/permutations/distance/AbstractPermutationDistanceMeasurer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010, 2015, 2017-2019 Vincent A. Cicirello, <https://www.cicirello.org/>.
2+
* Copyright 2010, 2015, 2017-2021 Vincent A. Cicirello, <https://www.cicirello.org/>.
33
*
44
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
55
*
@@ -27,30 +27,30 @@
2727
* where distance is an integer value.
2828
*
2929
* @author <a href=https://www.cicirello.org/ target=_top>Vincent A. Cicirello</a>, <a href=https://www.cicirello.org/ target=_top>https://www.cicirello.org/</a>
30-
* @version 1.19.6.12
31-
* @since 1.0
30+
* @version 1.28.2021
3231
*
3332
*/
3433
abstract class AbstractPermutationDistanceMeasurer implements PermutationDistanceMeasurer, NormalizedPermutationDistanceMeasurer {
3534

3635
/**
3736
* {@inheritDoc}
37+
*
38+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
3839
*/
3940
@Override
4041
public final double distancef(Permutation p1, Permutation p2) {
4142
return distance(p1,p2);
4243
}
4344

44-
/**
45-
* {@inheritDoc}
46-
*/
4745
@Override
4846
public final double maxf(int length) {
4947
return max(length);
5048
}
5149

5250
/**
5351
* {@inheritDoc}
52+
*
53+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
5454
*/
5555
@Override
5656
public final double normalizedDistance(Permutation p1, Permutation p2) {

src/org/cicirello/permutations/distance/AcyclicEdgeDistance.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2019 Vincent A. Cicirello, <https://www.cicirello.org/>.
2+
* Copyright 2014-2021 Vincent A. Cicirello, <https://www.cicirello.org/>.
33
*
44
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
55
*
@@ -42,8 +42,7 @@
4242
* S. Ronald, "Distance functions for order-based encodings," in Proc. IEEE CEC. IEEE Press, 1997, pp. 49–54.</p>
4343
*
4444
* @author <a href=https://www.cicirello.org/ target=_top>Vincent A. Cicirello</a>, <a href=https://www.cicirello.org/ target=_top>https://www.cicirello.org/</a>
45-
* @version 1.19.6.12
46-
* @since 1.0
45+
* @version 1.28.2021
4746
*/
4847
public final class AcyclicEdgeDistance extends AbstractPermutationDistanceMeasurer {
4948

@@ -54,28 +53,28 @@ public AcyclicEdgeDistance() {}
5453

5554
/**
5655
* {@inheritDoc}
56+
*
57+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
5758
*/
5859
@Override
5960
public int distance(Permutation p1, Permutation p2) {
61+
if (p1.length() != p2.length()) {
62+
throw new IllegalArgumentException("Permutations must be the same length");
63+
}
6064
int countNonSharedEdges = 0;
61-
int L1 = p1.length();
62-
int L2 = p2.length();
63-
if (L1==L2 && L1==0) return 0;
64-
int[] successors2 = new int[L2];
65-
for (int i = 0; i < L2 - 1; i++) {
65+
if (p1.length()==0) return 0;
66+
int[] successors2 = new int[p2.length()];
67+
for (int i = 0; i < p2.length() - 1; i++) {
6668
successors2[p2.get(i)] = p2.get(i+1);
6769
}
68-
successors2[p2.get(L2-1)] = -1;
70+
successors2[p2.get(p2.length()-1)] = -1;
6971

70-
for (int i = 0; i < L1 - 1; i++) {
72+
for (int i = 0; i < p1.length() - 1; i++) {
7173
if (p1.get(i+1) != successors2[p1.get(i)] && p1.get(i) != successors2[p1.get(i+1)]) countNonSharedEdges++;
7274
}
7375
return countNonSharedEdges;
7476
}
7577

76-
/**
77-
* {@inheritDoc}
78-
*/
7978
@Override
8079
public int max(int length) {
8180
if (length <= 2) return 0;

src/org/cicirello/permutations/distance/BlockInterchangeDistance.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 Vincent A. Cicirello, <https://www.cicirello.org/>.
2+
* Copyright 2019, 2021 Vincent A. Cicirello, <https://www.cicirello.org/>.
33
*
44
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
55
*
@@ -40,8 +40,7 @@
4040
* <p>Runtime: O(n), where n is the permutation length.</p>
4141
*
4242
* @author <a href=https://www.cicirello.org/ target=_top>Vincent A. Cicirello</a>, <a href=https://www.cicirello.org/ target=_top>https://www.cicirello.org/</a>
43-
* @version 7.26.19
44-
* @since 2.0
43+
* @version 1.28.2021
4544
*/
4645
public class BlockInterchangeDistance extends AbstractPermutationDistanceMeasurer {
4746

@@ -52,9 +51,14 @@ public BlockInterchangeDistance() {}
5251

5352
/**
5453
* {@inheritDoc}
54+
*
55+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
5556
*/
5657
@Override
5758
public int distance(Permutation p1, Permutation p2) {
59+
if (p1.length() != p2.length()) {
60+
throw new IllegalArgumentException("Permutations must be the same length");
61+
}
5862
int[] inv2 = p2.getInverse();
5963
int[] p = new int[inv2.length+2];
6064
int[] inv = new int[p.length];
@@ -81,9 +85,6 @@ public int distance(Permutation p1, Permutation p2) {
8185
return (p1.length()+1-cycles)/2;
8286
}
8387

84-
/**
85-
* {@inheritDoc}
86-
*/
8788
@Override
8889
public int max(int length) {
8990
return length >> 1;

src/org/cicirello/permutations/distance/CyclicEdgeDistance.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2019 Vincent A. Cicirello, <https://www.cicirello.org/>.
2+
* Copyright 2014-2021 Vincent A. Cicirello, <https://www.cicirello.org/>.
33
*
44
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
55
*
@@ -42,8 +42,7 @@
4242
* S. Ronald, "Distance functions for order-based encodings," in Proc. IEEE CEC. IEEE Press, 1997, pp. 49–54.</p>
4343
*
4444
* @author <a href=https://www.cicirello.org/ target=_top>Vincent A. Cicirello</a>, <a href=https://www.cicirello.org/ target=_top>https://www.cicirello.org/</a>
45-
* @version 1.19.6.12
46-
* @since 1.0
45+
* @version 1.28.2021
4746
*/
4847
public final class CyclicEdgeDistance extends AbstractPermutationDistanceMeasurer {
4948

@@ -54,28 +53,27 @@ public CyclicEdgeDistance() {}
5453

5554
/**
5655
* {@inheritDoc}
56+
*
57+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
5758
*/
5859
@Override
5960
public int distance(Permutation p1, Permutation p2) {
61+
if (p1.length() != p2.length()) {
62+
throw new IllegalArgumentException("Permutations must be the same length");
63+
}
6064
int countNonSharedEdges = 0;
61-
int L1 = p1.length();
62-
int L2 = p2.length();
63-
64-
int[] successors2 = new int[L2];
65-
for (int i = 0; i < L2; i++) {
66-
successors2[p2.get(i)] = p2.get((i+1) % L2);
65+
int[] successors2 = new int[p2.length()];
66+
for (int i = 0; i < successors2.length; i++) {
67+
successors2[p2.get(i)] = p2.get((i+1) % successors2.length);
6768
}
6869

69-
for (int i = 0; i < L1; i++) {
70-
if (p1.get((i+1) % L1) != successors2[p1.get(i)] && p1.get(i) != successors2[p1.get((i+1) % L1)]) countNonSharedEdges++;
70+
for (int i = 0; i < successors2.length; i++) {
71+
if (p1.get((i+1) % successors2.length) != successors2[p1.get(i)] && p1.get(i) != successors2[p1.get((i+1) % successors2.length)]) countNonSharedEdges++;
7172
}
7273

7374
return countNonSharedEdges;
7475
}
7576

76-
/**
77-
* {@inheritDoc}
78-
*/
7977
@Override
8078
public int max(int length) {
8179
if (length <= 3) return 0;

src/org/cicirello/permutations/distance/CyclicIndependentDistance.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018-2019 Vincent A. Cicirello, <https://www.cicirello.org/>.
2+
* Copyright 2018-2021 Vincent A. Cicirello, <https://www.cicirello.org/>.
33
*
44
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
55
*
@@ -32,8 +32,7 @@
3232
* the constructor.</p>
3333
*
3434
* @author <a href=https://www.cicirello.org/ target=_top>Vincent A. Cicirello</a>, <a href=https://www.cicirello.org/ target=_top>https://www.cicirello.org/</a>
35-
* @version 1.19.6.12
36-
* @since 1.0
35+
* @version 1.28.2021
3736
*
3837
*/
3938
public final class CyclicIndependentDistance implements PermutationDistanceMeasurer {
@@ -56,6 +55,7 @@ public CyclicIndependentDistance(PermutationDistanceMeasurer d) {
5655
* @param p1 first permutation
5756
* @param p2 second permutation
5857
* @return distance between p1 and p2
58+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
5959
*/
6060
@Override
6161
public int distance(Permutation p1, Permutation p2) {
@@ -70,7 +70,13 @@ public int distance(Permutation p1, Permutation p2) {
7070
}
7171

7272
/**
73-
* {@inheritDoc}
73+
* Measures the distance between two permutations, with cyclic independence:
74+
* distance = min_{i in [0,N)} distance(p1,rotate(p2,i))
75+
*
76+
* @param p1 first permutation
77+
* @param p2 second permutation
78+
* @return distance between p1 and p2
79+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
7480
*/
7581
@Override
7682
public final double distancef(Permutation p1, Permutation p2) {

src/org/cicirello/permutations/distance/CyclicIndependentDistanceDouble.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018-2019 Vincent A. Cicirello, <https://www.cicirello.org/>.
2+
* Copyright 2018-2021 Vincent A. Cicirello, <https://www.cicirello.org/>.
33
*
44
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
55
*
@@ -32,8 +32,7 @@
3232
* the constructor.</p>
3333
*
3434
* @author <a href=https://www.cicirello.org/ target=_top>Vincent A. Cicirello</a>, <a href=https://www.cicirello.org/ target=_top>https://www.cicirello.org/</a>
35-
* @version 1.19.5.10
36-
* @since 1.0
35+
* @version 1.28.2021
3736
*
3837
*/
3938
public final class CyclicIndependentDistanceDouble implements PermutationDistanceMeasurerDouble {
@@ -56,6 +55,7 @@ public CyclicIndependentDistanceDouble(PermutationDistanceMeasurerDouble d) {
5655
* @param p1 first permutation
5756
* @param p2 second permutation
5857
* @return distance between p1 and p2
58+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
5959
*/
6060
@Override
6161
public double distancef(Permutation p1, Permutation p2) {

src/org/cicirello/permutations/distance/CyclicRTypeDistance.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010, 2014-2015, 2017-2019 Vincent A. Cicirello, <https://www.cicirello.org/>.
2+
* Copyright 2010, 2014-2015, 2017-2021 Vincent A. Cicirello, <https://www.cicirello.org/>.
33
*
44
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
55
*
@@ -44,8 +44,7 @@
4444
* IEEE Transactions on Evolutionary Computation, 20(3):434-446, June 2016.</p>
4545
*
4646
* @author <a href=https://www.cicirello.org/ target=_top>Vincent A. Cicirello</a>, <a href=https://www.cicirello.org/ target=_top>https://www.cicirello.org/</a>
47-
* @version 1.19.6.12
48-
* @since 1.0
47+
* @version 1.28.2021
4948
*/
5049
public final class CyclicRTypeDistance extends AbstractPermutationDistanceMeasurer {
5150

@@ -56,27 +55,26 @@ public CyclicRTypeDistance() {}
5655

5756
/**
5857
* {@inheritDoc}
58+
*
59+
* @throws IllegalArgumentException if p1.length() is not equal to p2.length().
5960
*/
6061
@Override
6162
public int distance(Permutation p1, Permutation p2) {
63+
if (p1.length() != p2.length()) {
64+
throw new IllegalArgumentException("Permutations must be the same length");
65+
}
6266
int countNonSharedEdges = 0;
63-
int L1 = p1.length();
64-
int L2 = p2.length();
65-
66-
int[] successors2 = new int[L2];
67-
for (int i = 0; i < L2; i++) {
68-
successors2[p2.get(i)] = p2.get((i+1) % L2);
67+
int[] successors2 = new int[p2.length()];
68+
for (int i = 0; i < successors2.length; i++) {
69+
successors2[p2.get(i)] = p2.get((i+1) % successors2.length);
6970
}
7071

71-
for (int i = 0; i < L1; i++) {
72-
if (p1.get((i+1) % L1) != successors2[p1.get(i)]) countNonSharedEdges++;
72+
for (int i = 0; i < successors2.length; i++) {
73+
if (p1.get((i+1) % successors2.length) != successors2[p1.get(i)]) countNonSharedEdges++;
7374
}
7475
return countNonSharedEdges;
7576
}
7677

77-
/**
78-
* {@inheritDoc}
79-
*/
8078
@Override
8179
public int max(int length) {
8280
if (length <= 2) return 0;

0 commit comments

Comments
 (0)