출력 공간을 가로 지르는 그래프 측면에서 출력을 생각하면 원하는 순서대로 결과를 얻을 수 있다고 생각합니다. 가장 가까운 우선 탐색을 원하지만 itertools.product
함수는 깊이 우선 탐색입니다. 이 같은
시도 뭔가 :
import heapq
def nearest_first_product(*sequences):
start = (0,)*len(sequences)
queue = [(0, start)]
seen = set([start])
while queue:
priority, indexes = heapq.heappop(queue)
yield tuple(seq[index] for seq, index in zip(sequences, indexes))
for i in range(len(sequences)):
if indexes[i] < len(sequences[i]) - 1:
lst = list(indexes)
lst[i] += 1
new_indexes = tuple(lst)
if new_indexes not in seen:
new_priority = sum(index * index for index in new_indexes)
heapq.heappush(queue, (new_priority, new_indexes))
seen.add(new_indexes)
예 출력 :
for tup in nearest_first_product(range(1, 5), range(1, 4), range(1, 5)):
print(tup)
(1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(2, 1, 1)
(1, 2, 2)
(2, 1, 2)
(2, 2, 1)
(2, 2, 2)
(1, 1, 3)
(1, 3, 1)
(3, 1, 1)
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
(2, 2, 3)
(2, 3, 2)
(3, 2, 2)
(1, 3, 3)
(3, 1, 3)
(3, 3, 1)
(1, 1, 4)
(2, 3, 3)
(3, 2, 3)
(3, 3, 2)
(4, 1, 1)
(1, 2, 4)
(2, 1, 4)
(4, 1, 2)
(4, 2, 1)
(2, 2, 4)
(4, 2, 2)
(3, 3, 3)
(1, 3, 4)
(3, 1, 4)
(4, 1, 3)
(4, 3, 1)
(2, 3, 4)
(3, 2, 4)
(4, 2, 3)
(4, 3, 2)
(3, 3, 4)
(4, 3, 3)
(4, 1, 4)
(4, 2, 4)
(4, 3, 4)
당신은 코드에서 new_priority
의 계산을 변경하여 약간 다른 주문의 무리를 얻을 수 있습니다. 현재 버전에서는 제곱 데카르트 거리를 우선 순위로 사용하지만 원할 경우 다른 값을 사용할 수도 있습니다 (예 : 인덱스뿐만 아니라 시퀀스의 값도 포함).
(둘 다 (1, 1, 2)
, (1, 2, 1)
및 (2, 1, 1)
후에 와서 너무 오래) 당신이 (1, 1, 3)
이 (1, 2, 2)
앞에 오는 여부에 대해 너무 많이 걱정하지 않는 경우, 당신은 아마 폭 우선 탐색을 할 수있는 대신에 가까운 최초. 우선 순위 대기열이 아닌 일반 대기열 (예 : collections.deque
)을 사용할 수 있기 때문에 조금 더 간단합니다.
이러한 종류의 그래프 통과에 사용되는 큐는이 코드가 일정량의 메모리를 사용한다는 것을 의미합니다. 그러나 결과를 순서대로 정리하기 전에 결과를 모두 만들어야하는 경우보다 메모리 양이 훨씬 적습니다. 사용 된 최대 메모리는 볼륨이 아닌 결과 공간의 표면적에 비례합니다.
정확히 여기에서 원하는 것은 무엇입니까? 그게 아니면 다른 명령일까요? – miradulo
그 특별한 순서는 괜찮을 것이지만 나는 "다음 순열"선택 순서를 바꾸는 기술에 관심이있다. 나는 초기 결과가 목록 앞에서 대부분의 항목을 가지고 생성하지만, 솔루션이 113 또는 122 먼저 생성하는지 여부 또는 211 또는 112 먼저 온다 상관하지 않는 것이 좋습니다. – dbn