can you answer the following question:
Question Title: Algorithm for ordering data so that neighbor elements are as identical as possible
Question Body:
I have a (potentially large) list `data` of 3-tuples of small non-negative integers, like
```python
data = [
 (1, 0, 5),
 (2, 4, 2),
 (3, 2, 1),
 (4, 3, 4),
 (3, 3, 1),
 (1, 2, 2),
 (4, 0, 3),
 (0, 3, 5),
 (1, 5, 1),
 (1, 5, 2),
]
```
I want to order the tuples within `data` so that neighboring tuples (`data[i]` and `data[i+1]`) are "as similar as possible".
[Define](https://en.wikipedia.org/wiki/Hamming\_distance) the \_dis\_similarity of two 3-tuples as the number of elements which are unequal between them. E.g.
- `(0, 1, 2)` vs. `(0, 1, 2)`: Dissimilarity `0`.
- `(0, 1, 2)` vs. `(0, 1, 3)`: Dissimilarity `1`.
- `(0, 1, 2)` vs. `(0, 2, 1)`: Dissimilarity `2`.
- `(0, 1, 2)` vs. `(3, 4, 5)`: Dissimilarity `3`.
- `(0, 1, 2)` vs. `(2, 0, 1)`: Dissimilarity `3`.

\*\*Question\*\*: What is a good algorithm for finding the ordering of `data` which minimizes the sum of dissimilarities between all neighboring 3-tuples?

### Some code
Here's a function which computes the dissimilarity between two 3-tuples:
```python
def dissimilar(t1, t2):
 return sum(int(a != b) for a, b in zip(t1, t2))
```
Here's a function which computes the summed total dissimilarity of `data`, i.e. the number which I seek to minimize:
```python
def score(data):
 return sum(dissimilar(t1, t2) for t1, t2 in zip(data, data[1:]))
```
The problem can be solved by simply running `score()` over every permutation of `data`:
```python
import itertools
n\_min = 3\*len(data) # some large number
for perm in itertools.permutations(data):
 n = score(perm)
 if n < n\_min:
 n\_min = n
 data\_sorted = list(perm)
print(data\_sorted, n\_min)
```
Though the above works, it's very slow as we explicitly check each and every permutation (resulting in O(N!) complexity). On my machine the above takes about 20 seconds when `data` has 10 elements.
For completeness, here's the result of running the above given the example `data`:
```python
data\_sorted = [
 (1, 0, 5),
 (4, 0, 3),
 (4, 3, 4),
 (0, 3, 5),
 (3, 3, 1),
 (3, 2, 1),
 (1, 5, 1),
 (1, 5, 2),
 (1, 2, 2),
 (2, 4, 2),
]
```

with `n\_min = 15`. Note that several other orderings (`10` in total) with a score of `15` exist. For my purposes these are all equivalent and I just want one of them.
### Final remarks
In practice the size of `data` may be as large as say `10000`.
The sought-after algorithm should beat O(N!), i.e. probably be polynomial in time (and space).
If no such algorithm exists, I would be interested in "near-solutions", i.e. a fast algorithm which gives an ordering of `data` with a small but not necessarily minimal total score. One such algorithm would be [lexicographic sorting](https://en.wikipedia.org/wiki/Lexicographic\_order), i.e.
```python
sorted(data) # score 18
```
though I hope to be able to do better than this.
### Edit (comments on accepted solution)
I have tried all of the below heuristic solutions given as code (I have not tried e.g. Google OR-tools). For large `len(data)`, I find that the solution of Andrej Kesely is both quick and gives the best results.
The idea behind this method is quite simple. The sorted list of data elements (3-tuples) is built up one by one. Given some data element, the next element is chosen to be the most similar one out of the remaining (not yet part of the sorted) data.
Essentially this solves a localized version of the problem where we only "look \_one\_ ahead", rather than optimizing globally over the entire data set. We can imagine a hierarchy of algorithms looking `n` ahead, each successively delivering better (or at least as good) results but at the cost of being much more expensive. The solution of Andrej Kesely then sits lowest in this hierarchy. The algorithm at the highest spot, looking `len(data)` ahead, solves the problem exactly.
Let's settle for "looking 1 ahead", i.e. the answer by Andrej Kesely. This leaves room for a) the choice of initial element, b) what to do when several elements are equally good candidates (same dissimilarity) for use as the next one. Choosing the first element in `data` as the initial element and the first occurrence of an element with minimal dissimilarity, both a) and b) are determined from the original order of elements within `data`. As Andrej Kesely points out, it then helps to (lex)sort `data` in advance.
In the end I went with this solution, but refined in a few ways:
- I try out the algorithm for 6 initial sortings of `data`; lex sort for columns `(0, 1, 2)`, `(2, 0, 1)`, `(1, 2, 0)`, all in ascending as well as descending order.
- For large `len(data)`, the algorithm becomes too slow for me. I suspect it scales like `O(n²)`. I thus process chunks of the data of size `n\_max` independently, with the final result being the different sorted chunks concatenated. Transitioning from one chunk to the next we expect a dissimilarity of 3, but this is unimportant if we keep `n\_max` large. I go with `n\_max = 1000`.
As an implementation note, the performance can be improved by not using `data.pop(idx)` as this itself is `O(n)`. Instead, either leave the original `data` as is and use another data structure for keeping track of which elements/indices have been used, or replace `data[idx]` with some marker value upon use.
다음 질문에 답변해 주세요:질문 제목: 이웃 요소가 가능한 한 동일하도록 데이터를 정렬하는 알고리즘질문 본문:나는 다음과 같은 작은 음수가 아닌 정수의 3 튜플의 (잠재적으로 큰) 목록 `데이터`를 가지고 있습니다.```pythondata = [ (1, 0, 5), (2, 4, 2), (3, 2, 1), (4, 3, 4), (3, 3, 1), (1, 2, 2), (4, 0, 3), (0, 3, 5), (1, 5, 1), (1, 5, 2),]```데이터` 내의 튜플을 인접한 튜플(`데이터[i]` 및 `데이터[i+1]`)이 "가능한 한 유사"하도록 정렬하고 싶습니다.[정의](https://en.wikipedia.org/wiki/Hamming\_distance)는 두 3튜플의 \_dis\_similarity를 그 사이에 같지 않은 요소의 수로 정의합니다. 예- (0, 1, 2)` 대 `(0, 1, 2)`: 유사도 `0`.- (0, 1, 2)` 대 `(0, 1, 3)`: 유사도 `1`.- (0, 1, 2)` 대 `(0, 2, 1)`: 유사도 `2`.- (0, 1, 2)` 대 `(3, 4, 5)`: 유사도 `3`.- (0, 1, 2)` 대 `(2, 0, 1)`: 유사도 `3`.\*\*질문\*\*\*: 인접한 모든 3 튜플 사이의 유사도 합을 최소화하는 `데이터`의 순서를 찾는 좋은 알고리즘은 무엇인가요?### 일부 코드다음은 두 3-튜플 사이의 유사도를 계산하는 함수입니다:```pythondef dissimilar(t1, t2): return sum(int(a != b) for a, b in zip(t1, t2))```다음은 `데이터`의 총 유사도 합계를 계산하는 함수, 즉 최소화하고자 하는 숫자를 계산하는 함수입니다:```pythondef score(data): RETURN SUM(DISSIMULAR(T1, T2) FOR T1, T2 IN ZIP(DATA, DATA[1:]))```이 문제는 `데이터`의 모든 순열에 대해 `score()`를 실행하면 간단히 해결할 수 있습니다:```pythonimport itertoolsn\_min = 3\*len(data) # 어떤 큰 숫자for perm in itertools.permutations(data): n = score(perm) 만약 n < n\_min: n\_min = n data\_sorted = list(perm)print(data\_sorted, n\_min)```위의 방법은 작동하지만 모든 순열을 명시적으로 검사하기 때문에 매우 느립니다(결과적으로 복잡성이 O(N!)). 제 컴퓨터에서는 `데이터`에 10개의 요소가 있을 때 위와 같은 작업을 수행하는 데 약 20초가 걸립니다.완성도를 높이기 위해 `data` 예제로 위 코드를 실행한 결과는 다음과 같습니다:```pythondata\_sorted = [ (1, 0, 5), (4, 0, 3), (4, 3, 4), (0, 3, 5), (3, 3, 1), (3, 2, 1), (1, 5, 1), (1, 5, 2), (1, 2, 2), (2, 4, 2),]```n\_min = 15`입니다. 점수가 `15`인 다른 여러 가지 순서(총 `10`)가 존재한다는 점에 유의하십시오. 제 목적상 이들은 모두 동일하며 저는 그 중 하나만 원합니다.### 최종 코멘트실제로 `데이터`의 크기는 `10000`만큼 클 수 있습니다.찾고자 하는 알고리즘은 O(N!), 즉 시간(및 공간)에서 다항식이어야 합니다.만약 그러한 알고리즘이 존재하지 않는다면, 저는 "근사 해법", 즉 작지만 반드시 최소 총점은 아닌 '데이터'의 순서를 제공하는 빠른 알고리즘에 관심이 있을 것입니다. 그러한 알고리즘 중 하나는 [사전 정렬](https://en.wikipedia.org/wiki/Lexicographic\_order), 즉```pythonsorted(data) # 점수 18```이보다 더 잘할 수 있기를 바라지만요.### 편집 (허용 된 솔루션에 대한 의견)코드로 주어진 아래의 모든 휴리스틱 솔루션을 시도해 보았습니다 (예 : Google OR 도구는 시도하지 않았습니다). 큰 `len(data)`의 경우 Andrej Kesely의 솔루션이 빠르고 최상의 결과를 제공한다는 것을 알았습니다.이 방법의 아이디어는 아주 간단합니다. 데이터 요소의 정렬된 목록(3-튜플)이 하나씩 쌓입니다. 어떤 데이터 요소가 주어지면, 다음 요소는 나머지(아직 정렬되지 않은) 데이터 중에서 가장 유사한 요소로 선택됩니다.기본적으로 이것은 전체 데이터 집합에 대해 전역적으로 최적화하는 것이 아니라 "\_하나\_ 앞만 보는" 로컬화된 버전의 문제를 해결합니다. 우리는 앞을 내다보는 알고리즘의 계층 구조를 상상할 수 있으며, 각 알고리즘은 연속적으로 더 나은(또는 적어도 동등한) 결과를 제공하지만 훨씬 더 비싼 대가를 치르게 됩니다. 그러면 안드레이 케슬리의 솔루션은 이 계층 구조에서 가장 아래에 위치합니다. 가장 높은 지점에 있는 알고리즘은 '렌(데이터)'을 앞을 바라보며 문제를 정확히 해결합니다."1 앞을 보는 것", 즉 안드레이 케슬리의 해답에 만족합시다. 이것은 a) 초기 요소의 선택, b) 여러 요소가 다음 요소로 사용하기에 똑같이 좋은 후보(동일한 비 유사성)일 때 어떻게 해야 하는지에 대한 여지를 남깁니다. '데이터'의 첫 번째 요소를 초기 요소로 선택하고 유사성이 최소인 요소가 처음 발생하는 경우, a)와 b)는 모두 '데이터' 내의 원래 요소 순서에서 결정됩니다. Andrej Kesely가 지적한 것처럼, 미리 `데이터`를 (렉)정렬하는 것이 도움이 됩니다.결국 저는 이 솔루션을 사용했지만 몇 가지 방법을 개선했습니다:- 데이터`의 6가지 초기 정렬, 즉 `(0, 1, 2)`, `(2, 0, 1)`, `(1, 2, 0)` 열에 대해 오름차순과 내림차순으로 모두 lex 정렬하는 알고리즘을 시도해 보았습니다.- 큰 `len(데이터)`의 경우 알고리즘이 너무 느려집니다. 저는 `O(n²)`처럼 확장된다고 생각합니다. 따라서 저는 `n\_max` 크기의 데이터 청크를 독립적으로 처리하고 최종 결과는 서로 다른 정렬된 청크가 연결된 것입니다. 한 청크에서 다음 청크로 전환할 때 3의 불일치가 예상되지만, 다음과 같은 경우 이는 중요하지 않습니다.