-
-
Notifications
You must be signed in to change notification settings - Fork 482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Steinhaus-Johnson-Trotter algorithm for permutations #38064
Steinhaus-Johnson-Trotter algorithm for permutations #38064
Conversation
Documentation preview for this PR (built with commit f9d76cf; changes) is ready! 🎉 |
Linter is failing. I think a few of the other CI fails are fixed in some PRs, so maybe a rebase to trigger CI will resolve them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are also missing examples/doctests in docstrings everywhere - see developer guide, in particular the EXAMPLES
block.
fe085c6
to
80ca849
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I think I messed up the styling for input docstring before
Also can you resolve the comments that are fixed, so i can see what to look |
Many thanks again @grhkm21 for reviewing the code. I've made |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final style changes, hopefully non controversial ones. should be ok afterwards. thanks in advance
Ah thank you for catching these small style issues. Commit 1052244 meets the changes. |
Some doctring formatting has also been done.
1052244
to
6ed2a79
Compare
Last linting error has been fixed. If everybody agrees with the changes and the overall code suggestion, this PR is ready for merging on my side. |
Sorry for the delay |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! Feel free to open an issue for the TODOs e.g. implement .previous()
or something
else: | ||
self._directions = directions | ||
|
||
def __idx_largest_element_non_zero_direction(self, perm, directions): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually internal methods are single underscores, but this is okay too
if self._algorithm != "lex" and self._algorithm != "sjt": | ||
raise ValueError("unsupported algorithm %s; expected 'lex' or 'sjt'" | ||
% self._algorithm) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, please fix this (CI lint is failing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good
<!-- ^ Please provide a concise and informative title. --> <!-- ^ Don't put issue numbers in the title, do this in the PR description below. --> <!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method to calculate 1 + 2". --> <!-- v Describe your changes below in detail. --> <!-- v Why is this change required? What problem does it solve? --> <!-- v If this PR resolves an open issue, please link to it here. For example, "Fixes sagemath#12345". --> I suggest this diff against develop to implement the Steinhaus-Johnson- Trotter algorithm that generates the permutations of a list using only transpositions of two elements of the list. The algorithm can be selected upon initialization with the parameter of the same name, defaults to "lex" which is the current algorithm. Since the `Permutation` class is a bit weird and creates a new list and a new object on every iteration, I had to tweak a bit the parameters in input to the class `__init__` method adding - `algorithm`: this one is fine, it allows to choose which algorithm to use to generate the permutations - `directions`: this one is meant to keep track of the internal state specific to the SJT algorithm. To find the two elements to transpose for the next permutation, we need to find elements according to some conditions regarding each of their direction. Since the `Permutation` class creates a new object at each iteration, I tried to find the best way to pass on the internal state to the new object. Maybe the internal state can be directly computed from the list, I haven't checked. Because of this dependency on the internal state, only the identity permutation can be used when initializing a `Permutation` object with `algorithm='sjt'` (see examples from doc). I am aware that adding an extra optional parameter to the object construction might not be the best option thus I will gladly take your feedback and opinions. I haven't implemented the `prev()` method. I think it should be done if this is accepted. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on. For example, --> <!-- - sagemath#12345: short description why this is a dependency --> <!-- - sagemath#34567: ... --> URL: sagemath#38064 Reported by: grnx Reviewer(s): grhkm21, grnx
<!-- ^ Please provide a concise and informative title. --> <!-- ^ Don't put issue numbers in the title, do this in the PR description below. --> <!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method to calculate 1 + 2". --> <!-- v Describe your changes below in detail. --> <!-- v Why is this change required? What problem does it solve? --> <!-- v If this PR resolves an open issue, please link to it here. For example, "Fixes sagemath#12345". --> I suggest this diff against develop to implement the Steinhaus-Johnson- Trotter algorithm that generates the permutations of a list using only transpositions of two elements of the list. The algorithm can be selected upon initialization with the parameter of the same name, defaults to "lex" which is the current algorithm. Since the `Permutation` class is a bit weird and creates a new list and a new object on every iteration, I had to tweak a bit the parameters in input to the class `__init__` method adding - `algorithm`: this one is fine, it allows to choose which algorithm to use to generate the permutations - `directions`: this one is meant to keep track of the internal state specific to the SJT algorithm. To find the two elements to transpose for the next permutation, we need to find elements according to some conditions regarding each of their direction. Since the `Permutation` class creates a new object at each iteration, I tried to find the best way to pass on the internal state to the new object. Maybe the internal state can be directly computed from the list, I haven't checked. Because of this dependency on the internal state, only the identity permutation can be used when initializing a `Permutation` object with `algorithm='sjt'` (see examples from doc). I am aware that adding an extra optional parameter to the object construction might not be the best option thus I will gladly take your feedback and opinions. I haven't implemented the `prev()` method. I think it should be done if this is accepted. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on. For example, --> <!-- - sagemath#12345: short description why this is a dependency --> <!-- - sagemath#34567: ... --> URL: sagemath#38064 Reported by: grnx Reviewer(s): grhkm21, grnx
<!-- ^ Please provide a concise and informative title. --> <!-- ^ Don't put issue numbers in the title, do this in the PR description below. --> <!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method to calculate 1 + 2". --> <!-- v Describe your changes below in detail. --> <!-- v Why is this change required? What problem does it solve? --> <!-- v If this PR resolves an open issue, please link to it here. For example, "Fixes sagemath#12345". --> I suggest this diff against develop to implement the Steinhaus-Johnson- Trotter algorithm that generates the permutations of a list using only transpositions of two elements of the list. The algorithm can be selected upon initialization with the parameter of the same name, defaults to "lex" which is the current algorithm. Since the `Permutation` class is a bit weird and creates a new list and a new object on every iteration, I had to tweak a bit the parameters in input to the class `__init__` method adding - `algorithm`: this one is fine, it allows to choose which algorithm to use to generate the permutations - `directions`: this one is meant to keep track of the internal state specific to the SJT algorithm. To find the two elements to transpose for the next permutation, we need to find elements according to some conditions regarding each of their direction. Since the `Permutation` class creates a new object at each iteration, I tried to find the best way to pass on the internal state to the new object. Maybe the internal state can be directly computed from the list, I haven't checked. Because of this dependency on the internal state, only the identity permutation can be used when initializing a `Permutation` object with `algorithm='sjt'` (see examples from doc). I am aware that adding an extra optional parameter to the object construction might not be the best option thus I will gladly take your feedback and opinions. I haven't implemented the `prev()` method. I think it should be done if this is accepted. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on. For example, --> <!-- - sagemath#12345: short description why this is a dependency --> <!-- - sagemath#34567: ... --> URL: sagemath#38064 Reported by: grnx Reviewer(s): grhkm21, grnx
I suggest this diff against develop to implement the Steinhaus-Johnson-Trotter algorithm that generates the permutations of a list using only transpositions of two elements of the list. The algorithm can be selected upon initialization with the parameter of the same name, defaults to "lex" which is the current algorithm.
Since the
Permutation
class is a bit weird and creates a new list and a new object on every iteration, I had to tweak a bit the parameters in input to the class__init__
method addingalgorithm
: this one is fine, it allows to choose which algorithm to use to generate the permutationsdirections
: this one is meant to keep track of the internal state specific to the SJT algorithm. To find the two elements to transpose for the next permutation, we need to find elements according to some conditions regarding each of their direction. Since thePermutation
class creates a new object at each iteration, I tried to find the best way to pass on the internal state to the new object. Maybe the internal state can be directly computed from the list, I haven't checked. Because of this dependency on the internal state, only the identity permutation can be used when initializing aPermutation
object withalgorithm='sjt'
(see examples from doc). I am aware that adding an extra optional parameter to the object construction might not be the best option thus I will gladly take your feedback and opinions.I haven't implemented the
prev()
method. I think it should be done if this is accepted.📝 Checklist
⌛ Dependencies