0

특정 제약 조건에 따라 최적의 미디어 선택을 찾아야합니다. 나는 4 중첩 된 for 루프에서 그것을하고 있으며, 약 O (n^4) 회 반복이 걸릴 것이므로 느리다. 나는 그것을 더 빨리 만들려고했지만 아직도 느리다. 내 변수는 2 ~ 3 만개 정도 될 수 있습니다.Python : 느린 중첩 for 루프

max_disks = 5 
    max_ssds = 5 
    max_tapes = 1 
    max_BR = 1 
    allocations = [] 
    for i in range(max_disks): 
    for j in range(max_ssds): 
     for k in range(max_tapes): 
      for l in range(max_BR): 
       allocations.append((i,j,k,l)) # this is just for example. In actual program, I do processing here, like checking for bandwidth and cost constraints, and choosing the allocation based on that. 

그것은 최대 각 미디어 유형의 수백 둔화되지하지만 수천 느려질 것 :

여기에 내가 뭘하려고 오전의 작은 예입니다. 내가 시도

다른 방법은 : 그것은 심지어 작은 숫자 느린

max_disks = 5 
    max_ssds = 5 
    max_tapes = 1 
    max_BR = 1 

    allocations = [(i,j,k,l) for i in range(max_disks) for j in range(max_ssds) for k in range(max_tapes) for l in range(max_BR)] 

이 방법.

두 질문 : 두 번째는 적은 수의 느린 이유

  1. ?
  2. 큰 숫자 (수천)에 대해 내 프로그램을 작동 시키려면 어떻게해야합니까? 여기

그것은이 숫자로 마무리 19.8 초 밖에 걸리지 itertools.product

  max_disks = 500 
      max_ssds = 100 
      max_tapes = 100 
      max_BR = 100 
      # allocations = [] 
      for i, j, k,l in itertools.product(range(max_disks),range(max_ssds),range(max_tapes),range(max_BR)): 
       pass 

와 버전입니다.

+5

목록 이해가있는 첫 번째 예는 두 번째 예보다 * 빠름 *입니다. 그것들은 다른 점은 같지만'allocations.append' 속성 룩업과 후속 메서드 호출은 중첩 된 루프를 느리게 만듭니다. 대신에 여기에서'itertools.product()'를보고 대신 모든 가능한 조합으로 거대한리스트 객체를 생성하는 것을 피하고 싶다. –

+0

itertools.product()도 시도했습니다. 그러나 그것도 수천 번은 효과가 없었습니다. – Pretty

+1

할당 목록 작성을 고집합니까? 작성중인 목록의 일반 구조를 이미 알고 있으므로 개별적으로 할당을 처리 할 수 ​​없습니까? –

답변

3

댓글을 통해 나는 ILP으로 다시 쓸 수있는 문제에 대해 작업하고 있다는 것을 알게되었습니다. 몇 가지 제약 조건이 있으며 (거의) 최적의 솔루션을 찾아야합니다.

이제 ILP는 해결하기가 매우 어려우며, 짐마차를 강요하는 것은 (당신이 이미 목격했듯이) 어렵게됩니다. 이것이 진정한 마술을 만들어내는 업계에서 사용되는 몇 가지 정말로 영리한 알고리즘이있는 이유입니다.

파이썬의 경우 현대 솔버에 연결되는 인터페이스가 상당히 있습니다. 자세한 내용은 을 참조하십시오. this SO post. SciPy optimize과 같은 옵티 마이저를 사용할 수도 있지만 일반적으로 정수 프로그래밍은 수행하지 않습니다.

0

파이썬에서 어떤 작업을 수행하면 1 조 시간이 느려질 것입니다. 그러나 그것이 당신이하는 전부는 아닙니다. 1 조의 항목을 모두 하나의 목록에 저장하려고하면 많은 양의 데이터를 메모리에 저장하고 RAM에서 더 이상 적합하지 않게 메모리를 스왑 할 수있는 많은 작업을 생성하는 방식으로 조작합니다.

파이썬이 작동하는 방식은 목록에 항목을 저장하기 위해 어느 정도의 메모리를 할당한다는 것입니다. 목록을 채우고 더 많은 것을 할당해야 할 때, 파이썬은 두 배의 메모리를 할당하고 모든 이전 항목을 새로운 저장 공간에 복사합니다. 기억 장치를 확장 할 때마다 목록의 모든 내용을 복사해야하지만 크기가 두 배로 유지되므로 빈도를 줄여야합니다. 문제는 메모리가 부족하여 사용되지 않는 메모리를 디스크로 교체해야 할 때 발생합니다. 다음에 디스크 크기를 조정하려고하면 디스크에서 스왑 된 모든 항목을 디스크에서 다시로드 한 다음 다시 모든 항목을 스왑하여 다시 새 항목을 쓸 수있는 공간을 확보해야합니다. 따라서 작업 속도가 느려지고 느려질 수있는 느린 디스크 작업이 많이 생성됩니다.

정말 모든 항목을 목록에 저장해야합니까? 당신이 끝나면 그들과 무엇을 할거 니? 거대한 목록에 누적하지 않고 디스크에 기록 할 수는 있지만 그 중 수조가 많으면 여전히 많은 양의 데이터입니다. 아니면 당신은 그 중 대부분을 필터링하고 있습니까? 도움이 될 것입니다.

실제 프로그램을 보지 않고 철저한 검색을 통해이 작업을 완료 할 수 있는지 여부를 알기가 어렵습니다. 한 번에 모든 변수를 수천 단위로 늘릴 수 있습니까? 이 변수들의 모든 조합을 고려해야합니까? max_disks == 2000 일 때, i = 1731과 i = 1732의 결과를 구별 할 필요가 있습니까? 예를 들어, 아마도 1,2,3,4,5,102030405010020030050010002000의 값을 고려할 수 있습니까? 아니면 수학적 해결책이 있을까요? 너는 그냥 아이템을 세고 있니?