Note: I am searching for an algorithm that can do what I need or something similar to it, so that I can try to adapt it to my needs. My idea here was to ask for a reference (e.g. “This can be solved using an algorithm called xyz”) but obviously I would also appreciate it if someone took the time to create one on-the-fly. The latter is not my expectation though. I am mostly looking for some keywords to continue my research on.

### Algorithm description

I am searching for an algorithm that can bring a given set of elements as close to a different set of the same length as possible. However the tricky part is that only specific elements may be exchanged.

The elements in the set can be assumed to have an intrinsic order. That is we can define a series `a < b < c < d < ...`

for all elements across the sets.

The allowed changes are not known beforehand but are generally in the form of “replace the i-th element in the set with the j-th one” or “Replace the i-th and the j-th element and at the same time the k-th with l-th” or any extension of that. Thus: Pairwise exchanges of one or more pairs of elements where not the element itself but its position within the set is important.

As an example consider the set `{abcd}`

and we want to check whether we can turn this into `{dabc}`

. The allowed modifications are:

- Switch 0-th with 1-st
- Switch 2nd with 3rd

Using these rules it is impossible to convert the starting set into the target set and thus something that comes as close as possible to it, is enough.

The exact measure of “closeness” is not relevant for me, as long as the end-result is always the same, no matter from which permutation of the set I start (provided it is possible to arrive at the solution using only the given modifications). So in this example it should not matter whether I start from `{abcd}`

or e.g. `{badc}`

.

The other characteristic of the searched for algorithm is that if it is possible to reach the given target set with the allowed modifications, the algorithm should always transform my start set into the target set.

### The underlying application

The context to where I intend to use an algorithm as described above is to determine whether two Tensor specifications (for our intents and purposes a “Tensor” is a multidimensional array) are really referring to one and the same element, taking the Tensor’s symmetry into account.

So for instance a Tensor could be $G^{ij}_{ab}$ and its symmetries allow exchange index $i$ with $j$. Therefore $G^{ji}_{ab}$ must have the exact same value because there exists a symmetry-relation that tells us that these two must be equal. $G^{ij}_{ba}$ on the other hand would be a different element.

My idea was to establish something of a “canonical” order of indices such that Tensor elements that are really the same, end up being written in the exact same way and therefore can be compared for equality by a simple `==`

check.

In order to do that I would map the indices into a set of indices (e.g. `{ijab}`

) which I can sort, since my indices are comparable. Therefore I can create a target set of indices that is independent of the starting set and thus I can use that as a common reference point for all Tensors that contain the same indices (but maybe in different order).