문제

가 비용을 최적화하는 요청을 하지 않는 방법을 알고 있는 경우 문학.그것은 약간의 설명하기 어려운,그래서 내가 미리 사과 길이에 대해 질문입니다.

가 서버 내에 액세스하는 작동하는 이 방법:

  • 요청에 만들어 레코드(r1,...rn)와 필드(f1,...fp)
  • 요청할 수 있습 데카르트 제품(r1,...,rp)x(f1,...fp)
  • 비용(시간과 돈)과 관련된 이러한 요청은 아핀에서의 크기는 요청은:

T((r1, ..., rn)x(f1, ..., fp) = a + b * n * p

의 손실 없이 일반(당해 정상화),가정할 수 있습니다 b=1 그래서 비용:

T((r1, ...,rn)x(f1,...fp)) = a + n * p

  • 나만을 요청하는 하위 집합의 쌍 (r1, f(r1)), ... (rk, f(rk)), 요청에서 오는 사용자.내 프로그램 행위를 중개인으로 사는 사용자와 서버(외부).나는 많이 요청이 오는(수만 하루에).

그래픽으로,우리는 생각할 수 있습으로 그것 n x p sparse matrix,한 커버하고 싶은 이 아닌 값으로 사각형 부분행렬:

   r1 r2 r3 ... rp
   ------      ___
f1 |x  x|      |x|
f2 |x   |      ---
   ------
f3
..    ______
fn    |x  x|
      ------

하:

  • 숫자의해 부분행렬되고 유지 합리적인 지속적으로 있기 때문에 비용
  • 모든'x'거짓말을 내 부분행렬
  • 총 지역을 커버해 너무 크지 않기 때문에 선 비용

내가 이름을 것입니다 g 분포도 계수의 제 문제(숫자의 필요한 쌍을 통해 가능한 총 쌍, g = k / (n * p).나는 알고 계수 a.

거기에 몇 가지 명백한 관찰:

  • 는 경우가 작고,최고의 솔루션을 요청하는 각(레코드 필드)쌍 독립적으로,총 비용은: k * (a + 1) = g * n * p * (a + 1)
  • 는 경우에는 큰,최고의 솔루션을 요청하는 전체적인 데카르트 제품,그리고 총 비용은: a + n * p
  • 두 번째 솔루션은 더 나은 즉시 g > g_min = 1/ (a+1) * (1 + 1 / (n * p))
  • 코스의 주문에 데카르트 제품은 중요하지 않은,그래서 나는 트랜스 수 행과 열의 행렬은 더 쉽게 회복시킬 수 있는,예를 들어:
   f1 f2 f3
r1  x    x
r2     x 
r3  x    x

으로 다시 주문하실 수 있습니다

   f1 f3 f2
r1  x  x
r3  x  x
r2       x

고 있는 최적의 솔루션을 요청 (f1,f3) x (r1,r3) + (f2) x (r2)

  • 고 모든 솔루션을 찾고에 대한 낮은 비용,옵션을 선택하지 않기 때문에 조합론 폭발:
for each permutation on rows: (n!)
   for each permutation on columns: (p!)
       for each possible covering of the n x p matrix: (time unknown, but large...)
           compute cost of the covering

그래서 내가 찾는 것에 대한 대략적인 솔루션입니다.이미 어떤 종류의 욕심하는 알고리즘을 찾을 덮어 매트릭스(로 시작 단일세포,다음을 병합하는 경우의 비율에서 빈 셀 병합은 아래턱).

일부를 넣어 번호에서 마음,내 n 은 어딘가에 1~1000,내 p 이 어딘가에 1~200.보험 패턴은 정말로 괴상이기 때문에,이 기록에서 클래스에 대한 필드 요청은 비슷합니다.불행하게도 내에 액세스 할 수 없습니스 클래스의 기록을...

질문 1:는 사람이 아이디어,영리 단순화하거나,참조에 대한 종이로는 도움이 될 수 있을까?로 많이 요청하는 알고리즘을 잘 작동 평균 내가 무엇을 찾고 있다(하지만 나는 그것을 감당할 수 없을 작동하는 매우 저조한 일부 극단적인 경우,예를 들어는 요청의 전체 매트릭스 때 n 및 p 하고 요청은 실제로 매우 sparse).

질문 2:사실,문제는 더욱 복잡:비용은 사실상태: a + n * (p^b) + c * n' * p', 는 곳,b 정 < 1(일단 기록 요구하는 분야,그것은 너무 비용이 많이 드는 요청하는 다른 분야)및 n' * p' = n * p * (1 - g) 은 세포의 수를 나는 원하지 않을 요청하는(있기 때문에 잘못된,그리고 거기에 추가 비용을 요청하는 잘못된 것).수도 꿈의 신속한 솔루션이 문제이지만,여전히...는 생각을 누구나?

도움이 되었습니까?

해결책

선택해 부분행렬을 커버가 요청한 값은 형태의 트 문제를 덮고 따라서 NP 완료합니다.귀하가 문제를 추가 이미 어려운 문제는 비용의 설정이 다릅니다.

당신이 허용하는 순열의 행과 열의하지 않은 큰 문제가 할 수 있기 때문에,단지 고려 연결해 부분행렬.행나,열 칠 및 행 다섯,열 두 네 일곱은 유효한 설정할 수 있기 때문에만 교환 행을 두고 행 다섯과를 얻을 연결된 부분행렬 행나,열 네 명을 행 두 열니다.물론 이것은 일부 제약 조건이 추가하지 모든 집합은 유효한 아래에서 모든 순열을-하지만 나는 생각하지 않는 이것은 큰 문제입니다.

위키백과 문서를 제공합 inapproximability 결과는 것을 문제를 해결할 수 없습니다 다항식 시간은 더 나은 다음 요소 0.5 * log2(n)n 은 번호를 설정합니다.귀하의 경우에는 2^(n * p) 입니다(매우 비관적)상에 대한 세트의 수를 산출할 수 있는 단지 해결책을 찾기 위해 요소의 0.5 * n * p 다항식 시간(외 N=NP 및을 무시하고 다양한 비용).

는 낙관적 하의 수에 대한 설정을 무시하고 순열의 행과 열가 0.5 * n^2 * p^2 항복이 훨씬 더 나은 인자의 log2(n) + log2(p) - 0.5.에 결과를 기대할 수 있습니다 해결책을 찾아에서 최악의 경우 n = 1000p = 200 까지의 요인에 대한 17 에서 낙관적 인 경우 최대의 요소에 대해 100.000 에서 비관적인 경우(여전히 무시하고 다양한 비용).

그래서 당신이 할 수있는 최선을 사용하는 것이 경험적 알고리즘은(위키 문서에서 언급하는 거의 최적의 욕심이 알고리즘)고 받아들이 있는 경우 알고리즘 수행(매우)나쁘다.또 다른 방법으로 사용 최적화 알고리즘을 찾으려고 좋은 해결책이 있을 사용하여 많은 시간입니다.이 경우에는 것이 좋을 사용하려고 *검색.

다른 팁

나는 확실히 여기에는 정말 좋은 위한 알고리즘을 이 밖이 어딘가에,하지만 여기에 내의 자신의 직관적인 아이디어:

  1. 을 던져 어떤 사각형 접근 방식:

    • 결정하"대략적"직사각형 크기에 따라 a.
    • 이러한 사각형은(아마도 무작위)이 필요한 지점까지 모든 포인트가 적용됩니다.
    • 지금 가지고 각 사각형과 축소 가능한 한 많지 않고"잃고"모든 데이터 포인트입니다.
    • 을 찾아 사각형이 서로 가까이 다른지 여부를 결정을 결합하는 것보다 저렴 유지하는 그들을 분리합니다.
  2. 성장

    • 시작과 함께 각 지점에서 그것의 자신의 1x1 사각형입니다.
    • 를 찾는 모든 사각형 내에 있는 행/열(n 기반 할 수 있습에 a);당신이 결합 할 수 있습니다 그들 중 하나로 사각형에 대한 비용(또는 부정적인 비용:D).
    • 반복합니다.
  3. 축소

    • 시작이 하나의 큰 사각형을 덮는 더 많은 시간이 필요합니다.
    • 보면 하위 사각형 공유하는 한 쌍의 양쪽으로 큰 중 하나,하지만 포함됩니다.
    • 그것을 잘라의 큰 중 하나는 생산,두 개의 작은 사각형입니다.
    • 반복합니다.
  4. 쿼드

    • 를 나누기로 4 사각형입니다.이들 각각에 대해,당신은 더 나은 비용에 의해 recursing 또한,또는 단지 포함하여 전체 사각형입니다.
    • 지금 당신의 사각형하고 보는 경우에 병합할 수 있습니다 그들의 약간/비용이 없습니다.\

도: 마음에 유지 는 때때로 그것이 더 좋을 것을 두 중복 사각형의 하나 이상의 큰 사각형의 상위 집합니다.E.g.는 경우 두 사각형을 그냥에 겹치는 한 구석에 자리 잡고 있습니다.

Ok,내의 이해를 질문가 변경되었습니다.새로운 아이디:

  • 점으로 각 행 롱 비트 문자열입니다.과 쌍의 비트 문자열을 찾기 위해 노력하고,쌍을 극대화하는 1 비트입니다.이러한 성장은 쌍으로 더 큰 그룹(정렬과 일치하려고 정말 큰 것 서로 다른).다음 건설 요청에 타격을 줄 것으로 예상된다 가장 큰 그룹은 다음을 잊지에 대한 모든 비트입니다.될 때까지 반복합니다.어쩌면 스위치에서 행하는 열 때로는.

  • 모든 행/열과 함께,또는,몇 가지 포인트에 있다."삭제"일시적으로 그들을.지금 당신이 보고 있는 것이 무엇에 의해 덮여 요청을 하는 그들을 떠난다.지금은 아마도 중 하나를 적용하는 다른 기술,그리고 거래를 무시 rows/cols 습니다.또 다른 방법에 대해 생각하는 것입니다:다루는 밀도가 높은 지점 첫째,그리고 다음에 움직이 더 부족하다.

때문에 당신의 값이 스파 스,그것은 많은 사용자 요구하고 있는 비슷한 가치입니까?캐싱 응용 프로그램 내에서 옵션이 될 수 있습니까?요청이 될 수 있을 인덱싱하는 해시된 기능의(x,y)위치,그래서 당신은 쉽게 식별할 수 있 캐시 설정에 속하는 올바른 지역의 자리를 차지하고 있습니다.저장 캐시 설정에서,예를 들어,을 찾을 수 있습니다 최소 캐시 하위 집합을 커버하는 요청의 범위는 매우 빠르게 합니다.당신은 할 수 있습니 선형 조회 하위 집합에있는 작습니다.

나는 고려 n 기록(행)및 p 필드(cols)에 언급된 요청 시 사용자 설정하는 n 으로 포인트에서 p-차원 공간({0,1}^p)ith 좌표되는 1iff 고 있 X 를 식별하는 계층의 클러스터, 으로,가장 대략적인 클러스터에는 루트를 포함하여 모든 X각 노드 클러스터링 계층 구조,고려한 제품을 커버하는 모든 필요한 열(이 행을(모든 하위 노드)x cols(모든 하위 노드)).그런 다음을 결정 아래에서 여부를 병합 아이 깔개(지불하는 전체를 위한 취재)또는 유지 별도로 요청합니다.(덮음의 연속된 열이지만,정확하게 필요한;즉생각의 비트를 벡터)

동의함으로 Artelius 는 겹치는 제품-요청할 수 있는 저렴;내 계층적 접근 방식 개선이 필요한을 통합합니다.

나는 일에 그것은,그리고 여기에 명백한,O(n^3)greedy,대칭을 깨는 알고리즘(기록 및 필드하는 대우는 별도로)파이썬에서 같은 의사 코드입니다.

아이디어가 사소:우리가 시작 중 하나를 시도하여 요청을 기록,그리고 우리는 가장 가치가 병합이 있을 때까지 아무것도 남아 가치를 병합합니다.이 algo 는 명백한 불이익 허용하지 않는다는 것이 겹치는 요구지만,나는 그것을 기대를 확실히 잘 작동에 실제 케이스(a+ n * (p^b) + c * n * p * (1 - g) 비용능):

# given are
# a function cost request -> positive real
# a merge function that takes two pairs of sets (f1, r1) and (f2, r2) 
# and returns ((f1 U f2), (r1 U r2))

# initialize with a request per record

requests = [({record},{field if (record, field) is needed}) for all needed records]
costs = [cost(request) for request in requests]

finished = False

while not finished: # there might be something to gain
    maximum_gain = 0
    finished = True
    this_step_merge = empty

    # loop onto all pairs of request
    for all (request1, request2) in (requests x request) such as request1 != request2:
        merged_request = merge(request1, request2)
        gain = cost(request1) + cost(request2) - cost(merged_request)

        if gain > maximum_gain:
            maximum_gain = gain
            this_step_merge = (request1, request2, merged_request)

    # if we found at least something to merge, we should continue
    if maximum_gain > 0:
        # so update the list of requests...
        request1, request2, merged_request = this_step_merge
        delete request1 from requests
        delete request2 from requests
        # ... and we are not done yet
        insert merged_request into requests
        finished = False

output requests

이 O(n3*p)기:

  • 초기화 이후에는 우리가 시작 n 요청
  • while 루프를 제거 정확히 한 요청에서 수영장에서 각각의 iteration.
  • for 루프 반복하에(ni^2 - ni)/2 뚜렷한 쌍의 요청 ni 가에서 하나 최악의 경우에는 때(우리 병합으로 모든 것을 하나의 큰 요청 시).

    1. 누군가의 도움을 받을 수 있는 저를 가리키는 아주 나쁜 사례의 알고리즘이 있습니다.그것은 소리 reasonnable 이것을 사용하나요?
    2. 그것은 오(n^3)이는 너무 비용이 많이 드는 대형 입력이 있습니다.어떤 아이디어를 최적화하는지?

사전에 감사합니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top