2017-10-04 6 views
9

튜플의 내용을 반복하지 않고 튜플 목록의 모든 조합을 생성하는 방법 dictionary = {(p,q):n}을, 나는를 생성해야 p 또는 q가 새로운 사전 내에서 반복되지 않도록 모든 조합의 새 사전 목록. 그리고이 사전 목록을 생성하는 동안 또는 사전 값을 사용하는 계산을 기반으로 사전 중 하나를 원하는 것으로 선택하십시오. 내가 (하지만 훨씬 작은) 무슨 뜻인지의파이썬 :</p> <p>튜플와 사전 키 감안할 때 : 나는 수수께끼의 비트와 함께 일하고 있어요

예 :

dictionary = {(1,1): 1.0, (1,2): 2.0, (1,3): 2.5, (1,4): 5.0, (2,1): 3.5, (2,2): 6.0, (2,3): 4.0, (2,4): 1.0}

listofdictionaries = [{(1,1): 1.0, (2,2): 6.0}, {(1,1): 1.0, (2,3): 4.0}, (1,1): 1.0, (2,4): 1.0}, {(1,2): 2.0, (2,1): 3.5}, {(1,2): 2.0, (2,3): 4.0},이되는 등

같은 사전 : {(1,1): 1.0, (2,1): 3.5}는 q를 반복하기 때문에하지 허용됩니다.

내 sob 이야기 : 저는 코딩에 새로운 브랜드입니다. 그러나이 스크립트를 작성하여 일부 데이터를 분석하려고했습니다. 하지만 흥미로운 알고리즘 수수께끼라고 생각합니다. 아주 작은 사전으로 작동하는 무언가를 썼지 만 큰 것을 입력 할 때 너무 길어서 (아래 복사). 내 스크립트 시도에서 실제로 스크립트에서 나중에 내 마스터 사전을 참조하는 대신 튜플 조합의 목록을 생성했습니다. 나는 아래에 복사합니다 :

#first, I generate all the tuple combinations from my ExpDict dictionary 
combos =(itertools.combinations(ExpDict,min(len(ExpList1),len(ExpList2)))) 

#then I generate a list of only the combinations that don't repeat p or q 
uniquecombolist = [] 
for foo in combos: 
    counter = 0 
    listofp = [] 
    listofq = [] 
    for bar in foo: 
     if bar[0] in listofp or bar[1] in listofq: 
      counter=+1 
      break 
     else: 
      listofp.append(bar[0]) 
      listofq.append(bar[1]) 
    if counter == 0: 
     uniquecombolist.append(foo) 

이 목록을 생성 한 후, 나는 모두에 함수를 적용 "ExpList1"와 "ExpList2"

사전 튜플 키는이 목록을 사용하여 생성 된 사전 조합 (튜플 목록을 반복하고 마스터 사전에서 각각의 값을 호출)을 선택하고 해당 함수에서 결과 값이 가장 작은 조합을 선택하십시오.

또한 고유 한 p, q 개를 선택하여 결과 값이 이전 값보다 작은 지 여부를 확인하고 유지하는 경우 함수를 적용하려고했습니다 (이것은 해당 목록을 생성하는 대신 " uniquecombolist ", 나는 최종 튜플리스트를 생성한다.) - 여전히 너무 오래 걸린다.

필자는 솔루션이 p 세대, q-no-repeat 및 조합 생성 중에 최종 선택 기능을 포함시키는 데 있다고 생각합니다. 나는 이것을 실제로하는 방법에 대해 머리를 감싸는 데 어려움을 겪고있다.

읽어 주셔서 감사합니다. 사라

편집 :

내가 쌍의 세트에 최종 기능 (기본적으로 루트 평균 제곱)을 통합 내 코드에 대한 대안을 썼다 명확히하기. 내가 설정 한 세대 동안 RMS 계산을 통합 만 작은 일을 계속 할 수 있다면

`combos =(itertools.combinations(ExpDict,min(len(ExpList1),len(ExpList2)))) 


prevRMSD = float('inf') 
for foo in combos: 
    counter = 0 
    distanceSUM = 0 
    listofp = [] 
    listofq = [] 
    for bar in foo: 
     if bar[0] in listofp or bar[1] in listofq: 
      counter=+1 
      break 
     else: 
      listofp.append(bar[0]) 
      listofq.append(bar[1]) 
     distanceSUM = distanceSUM + RMSDdict[bar] 
    RMSD = math.sqrt (distanceSUM**2/len(foo)) 
    if counter == 0 and RMSD< prevRMSD: 
     chosencombo = foo 
     prevRMSD = RMSD` 

그래서, 나는 내 조합 문제를 해결할 것이라 생각합니다.

+0

기준에 맞는 모든 가능한 쌍을 생성하고 싶습니까? 또는 'n'이 작은 생성 목록의 길이 인 쌍의 가능한 크기 'n'집합? –

+0

@ JaredGoguen 각 쌍은 집합의 단일 항목입니다. p와 q는 반복 할 수 없으므로 세트에 n 개의 쌍이 있으므로 작은 생성 목록의 크기로 제한되어야합니다. 두 쌍의 튜플 쌍 (또는 튜플 키가있는 두 개의 사전)이 가능한 모든 가능한 집합을 생성하려고합니다. – Sara

+0

itertools.combinations에 대한 코드를 살펴 보았습니다. 솔직히 말해서 조합에 대한 내 자신의 조건에서 적용 할 수있는 충분한 감각을 갖지 못하고 적용 할 필요가있는 최종 기능까지도 이해할 수 없습니다. 나는 https://stackoverflow.com/questions/24907913/explain-combination-function-of-python-module-itertools를 보았지만 여전히 불행하게도 실제로 어떻게 작동하는지 이해하지 못한다. 내가 내 글에서 말했듯이, 나는 이것 (나는 다른 하나의 대본을 썼고 컴퓨터 과학에서는 어떤 과목도 택한 적이 없다)에 대해 매우 익숙하다. 그래서 나는 아마도 내가 씹을 수있는 것보다 더 많이 물어 뜯고있다. – Sara

답변

1

이 대답은 | S |를 사용하여 세트를 생성하려고한다고 가정합니다. 여기서 S는 튜플 좌표의 작은 풀입니다. 큰 풀은 L로 표시됩니다.

집합에는 | S | 반복 요소가없는 쌍으로, S의 각 요소는 정확히 한 번 발생해야합니다. 여기에서 순열 (L | S | 요소는 S의 정렬 된 요소로 선택됩니다. 이렇게하면 모든 요청 집합 이 철저히 반복되며이 생성됩니다.

P (| L |, | S |)는 | L |!/(| L | - | S |)와 같습니다.

튜플 좌표 풀의 크기에 따라 열거 할 순열이 너무 많을 수 있습니다.

처럼 보일 수 있습니다 열거를 복제하는 일부 코드 : 총에서

from itertools import permutations 

S, L = range(2), range(4) # or ExpList1, ExpList2 
for p in permutations(L, len(S)): 
    print(zip(S, p)) 

, 같은 보일 수 있습니다 최종 코드 :

S, L = ExpList1, ExpList2 
pairset_maker = lambda p: zip(S, p) 

if len(S) > len(L): 
    S, L = L, S 
    pairset_maker = lambda p: zip(p, S) 

n = len(S) 
get_perm_value = lambda p: math.sqrt(sum(RMSDdict[t] for t in pairset_maker(p))**2/n) 

min_pairset = min(itertools.permutations(L, n), key=get_perm_value) 

이 주문에서 당신을하지 않는 경우 또는 원하는 런타임의 크기 또는 두 가지가 있다면 최적의 솔루션을 생성하지 못하는 알고리즘을 고려해야합니다.

+0

예,이 사실을 깨닫게되었습니다. 그래서 조합을 생성하는 동안 제 기능을 적용하는 것이 이상적입니다 ...마지막으로 함수를 사용하여 가장 작은 값을 계산하는 튜플 집합을 찾습니다. 따라서이 함수를 고유 한 코드를 생성하는 코드에 통합하여 각 새 조합을 검사하여 이전 것보다 작은 지 확인한 다음 두 가지 중 작은 것을 유지, 나는 그것이 효과가있을 것 같아요? 어떻게 생각해? – Sara

+0

또한 순열보다는 조합을 찾고 있습니다. – Sara

+0

쌍의 조합과 위의 답에서 설명한 L의 순열을 일대일로 매핑하는 방식이 있습니다. –

1

내가 당신의 문제를 이해한다면, 당신은 p와 q에 대해 주어진 가능한 값의 집합을 존중하는 고유 한 p와 q를 갖는 모든 쌍 (p, q)의 조합에 관심이 있습니다. 내 대답에 나는 그 가능한 값은 list_plist_q에 각각있는 가정 (나는 이것이 당신이 ExpList1이 무엇인지 생각하고 ExpList2 잘 나는 오전?)이 당신이있어 어떤 경우

min_size = min(len(list_p), len(list_q)) 

combos_p = itertools.combinations(list_p, min_size) 
combos_q = itertools.permutations(list_q, min_size) 
prod = itertools.product(combos_p, combos_q) 
uniquecombolist = [tuple(zip(i[0], i[1])) for i in prod] 

을 알려주세요 찾고. 그런데 오신 것을 환영합니다, 큰 질문입니다!


편집 :

당신이 당신의 목록이 엄청난 될 수 있음을 우려하는 경우

, 당신은 항상, 발전기 식을 사용하고 예를 들어, 그것을 원하는 어떤 기능을 적용 할 수 있습니다

min_size = min(len(list_p), len(list_q)) 

combos_p = itertools.combinations(list_p, min_size) 
combos_q = itertools.permutations(list_q, min_size) 
prod = itertools.product(combos_p, combos_q) 
uniquecombo = (tuple(zip(y[0], y[1])) for y in prod) # this is now a generator expression, not a list -- observe the parentheses 

def your_function(x): 
    # do whatever you want with the values, here I'm just printing and returning 
    print(x) 
    return x 

# now prints the minimum value 
print(min(itertools.imap(your_function, uniquecombo))) 

목록 대신 생성자를 사용하면 값이 필요에 따라 계산됩니다. 여기서 우리는 최소값에 관심이 있기 때문에 각 값은 계산되고 즉시 최소값이 아니라면 무시됩니다.

+0

필자는 목록의 크기가 너무 커서 어떤 집합 쌍이 함수에 각 집합을 입력 한 후에 가장 작은 최종 값을 생성하는지 결정할 수 없다는 문제가 발생할 것이라고 생각합니다. 위의 게시물을 수정하여 내 기능을 포함시킵니다. 나는이 게시물을 좀 더 일반적으로 유지하기 위해 그것을 버렸지 만 독자들이 내가하려고하는 것을 이해하는 데 도움이 될 것이라고 생각한다. – Sara

+0

Ir 이것이 실제로 당신이 원하는 것입니다. 제가 한 일을 조금 더 설명하려고합니다. –

+0

그것은 세트 선택의 첫 번째 라운드를 우아하게 해결합니다! 감사합니다 :) 내 편집 위의 생각을 알려 주시기 바랍니다 – Sara