2013-02-08 4 views
2

버킷으로 그룹화 된 항목의 중첩되지 않는 조합을 모두 찾아야합니다. 여러 개의 버킷이있을 수 있으며 각 버킷에는 여러 개의 항목이 포함될 수 있습니다. 올바른 조합에는 각 버킷의 정확히 1 개의 항목이 포함됩니다.겹치지 않는 모든 조합은 어떻게 찾습니까?

bucket item start end 
======================== 

     |-- I1  1 5 
B1----|-- I2  6 9 
     |-- I3 15 20 


     |-- I4 6  9 
B2----|-- I5 10 14 
     |-- I6 14 25 


     |-- I7 1  14 
B3----|-- I8 26 40 
     |-- I9 1  20 
     |-- In ... 

Bn ... 

예를 들어, 1,4,8; 1,5,8; 1,6,8; 2,5,8; 2,6,8; 3,4,8; 및 3,5,8.

항목 9는 버킷 1의 모든 항목과 겹치기 때문에 조합으로 나타나지 않으며 옵션이없는 것을 볼 수 있습니다.

이 문제를 어떻게 효율적으로 가장 잘 해결할 수 있습니까? JavaScript JavaScript에서 이것을 구현하고 있습니다.

+0

버킷이 채워지는시기와 방법을 설명해야합니다. – Popnoodles

+0

각 버킷 (및 해결 중 부분 솔루션)을 고정하려면 간격 트리를 사용해야합니다. 그것 이외의, 이것은 NP 완전한 문제처럼 보입니다. – ElKamina

+0

@popnoodles : 간단한 개체 배열로 시작합니다. '[{버킷 : Bn, id : In, 시작 : x, 끝 : y}, ...]' – josh3736

답변

1

무차별 방식은 버킷의 데카르트 곱을 생성하고 유효하지 않은 것을 필터링하는 것입니다.

var cp = _.flatten(_.flatten(_.map(B1, function(item1) { 
    return _.map(B2, function(item2) { 
     return _.map(B3, function(item3) { 
      return [item1, item2, item3]; 
     }); 
    }); 
}), true), true); 

당신에게 3 양동이의 직교 제품을 제공합니다 : 그래서, 가정 당신의 버킷은 단순히 항목의 목록의 라인을 따라 뭔가입니다.

_.filter(cp, function(tuple) { 
    return !overlaps(item1, item2) && !overlaps(item1, item3) && !(overlaps(item2, item3); 
}); 

은 원하지 않는 필터를 걸러 낼 것입니다 (적절한 중첩 정의가 있음).

function overlaps(a, b) { 
    return a.lower > b.upper || b.lower > a.upper; 
} 

넌 _.rest (인수)의 직교 제품 위로 _.first (인수)의 평탄화 팽창 산출 재귀 호출 직교 변환하여 제품 간격 임의의 수의 필터를 일반화 할 수있다.

모든 가능한 쌍을 생성하고 !_.any(pairs, function(pair) { return overlaps.prototype.apply(undefined, pair); });을 호출하여 원하는 간격으로 필터를 일반화 할 수 있습니다.

+0

원래 질문에 명확하지 않은 경우 죄송합니다. 미리 계산할 버킷 수를 미리 알지 못합니다. (버킷 수는 데이터 집합 및 사용자 선택에 따라 다릅니다.) – josh3736

+0

이 경우 진행하기 전에 이것이 숙제인지 알아야합니다. 나는 이것이 당신에게 문제를 해결하는데 도움이 될만한 충분한 것을 주었다. 그렇지 않다면, 나중에 더 많은 시간과 육체가있을 때 이것을 되돌릴 수있다. – Recurse

+0

아니요, 현실 세계 문제입니다. (아마도 나는 교과서를 쓸 미래가 있습니까?) – josh3736

관련 문제