새로운 DAG로 DAG 계약의 최소 크기


15

DAG가 있습니다. 우리는 노드 에프:V (느슨하게 말해서 노드에 번호를 매 깁니다). 다음 규칙을 사용하여 새로운 방향 그래프를 작성하려고합니다.

  1. 동일한 번호의 노드 만 동일한 새 노드로 계약 할 수 있습니다. F(x)F(y)xy . (그러나 xyF(x)F(y) )
  2. 우리는 새로운 노드 사이에 모든 오래된 가장자리를 추가합니다 : (x,y)Exy(x,y)E .
  3. 이 새로운 그래프는 여전히 DAG입니다.

최소는 무엇입니까 ? 최소한의 새로운 그래프를 생성하는 알고리즘은 무엇입니까?|V|


1
따라서 결정 문제는 다음과 같습니다. 꼭짓점 색의 DAG와 정수 주어지면 , 같은 색으로 꼭짓점을 만들어서 최대 k 개의 꼭짓점 이있는 DAG가 있는지 여부를 결정 하십시오. 케이케이
András Salamon

1
두 개의 연결된 노드를 계약 한 경우 금지 된 자체 루프를 얻습니까?
Yuval Filmus

1
아니. 다시 2를 읽으십시오. 수축 후 두 노드가 여전히 다른 경우에만 가장자리를 추가합니다. 두 개의 노드가 하나로 축소되면 에지를 추가하지 않습니다.
chx

1
@chx "최소"또는 "최소"를 요구하고 있습니까?
Realz Slaw

1
동기 부여 / bkg를 줄 수 있습니까?
vzn

답변:


5

이 문제를 해결하는 한 가지 방법은 정수 선형 프로그래밍 (ILP)을 사용하는 것입니다. 문제의 의사 결정 버전을 해결해 봅시다. 가 주어지면 k 크기의 DAG를 얻기 위해 같은 색의 정점을 계약하는 방법이 있습니까?kk

이는 표준 기술을 사용하여 ILP 인스턴스로 표현 될 수 있습니다. 원래 그래프에서 각 정점의 색상이 주어집니다. 각 정점에 의 레이블로 레이블을 지정하는 것이 좋습니다 . 라벨과 색상이 같은 정점이 모두 계약됩니다. 따라서 의사 결정 문제는 다음과 같습니다. 모든 동일한 색상의 동일한 레이블 정점을 수축하면 DAG가 생성되도록 레이블이 있습니까?{1,2,,k}

정수 선형 프로그램으로이를 표현하기 위해 정수 변수 소개 각 꼭지점에 대한 V 정점에 라벨을 표현하기 위해, . 부등식 1 vk를 더 합니다.vvv1vk

다음 단계는 계약 그래프가 DAG 여야한다는 요구 사항을 표현하는 것입니다. 공지 사항이 라벨은 계약 그래프의 위상 정렬 (유도 같은 라벨이 존재 일반성의 손실없이 위에 나열된 형태의 라벨,있는 경우 즉, 만약 선행 w 계약 그래프에서, 다음 V 의 라벨 w 의 레이블 보다 작습니다 ). 따라서 원래 그래프의 각 가장자리 v w 에 대해 vw 의 레이블과 색상이 동일하거나 v 의 레이블이 w 의 레이블 보다 작다 는 제약 조건을 추가합니다 . 구체적으로, 각 모서리 v 에 대해vwvwvwvwvw 초기 그래프 여기서 V , w는 동일한 색상을 가지고, 부등식 추가 ℓ의 Vℓ를 . 각 모서리 v w 에 대해 v , w의 색상이 다른 경우 부등식v < w를 추가하십시오.vwv,wvwvwv,wv<w

이제이 정수 선형 프로그램에 적합한 솔루션이 있는지 확인하십시오. 라벨링이 원하는 형태 인 경우에만 가능한 해결책이있을 것입니다 (즉, 모든 동일한 색상의 동일한 라벨 정점을 계약하면 DAG가 생성됨). 다시 말해, 원래 그래프를 크기의 DAG로 계약하는 방법이있는 경우에만 가능한 해결책이있을 것 입니다. 정수 선형 프로그래밍 솔버를 사용할 수 있습니다. 만약 ILP 솔버가 우리에게 답을한다면, 우리는 원래의 결정 문제에 대한 답을 얻게됩니다.k

물론 이것은 다항식 시간으로 완료한다고 보장 할 수 없습니다. 보장은 없습니다. 그러나 ILP 솔버는 꽤 좋아졌습니다. 합리적인 크기의 그래프의 경우 ILP 솔버가 적절한 시간 내에이 문제를 해결할 수있을 가능성이 높습니다.

이것을 SAT 인스턴스로 인코딩하고 SAT 솔버를 사용할 수도 있습니다. 그것이 더 효과적인지 모르겠습니다. 그래도 ILP 버전은 생각하기가 더 쉽습니다.

(이것이 옳기를 바랍니다. 모든 세부 사항을주의 깊게 확인하지 않았으므로 내 추론을 다시 확인하십시오!


업데이트 (10/21) :이 형식의 ILP는 DAG를 위상 적으로 정렬 된 순서로 처리하고 각 정점의 레이블에서 하한을 추적함으로써 선형 시간으로 해결할 수있는 것처럼 보입니다. 이것은 내 해결책을 의심합니다. 어딘가에서 실수를 했습니까?


자세한 답변 감사합니다! 나는 제한을 받고 합리적으로 보입니다. 그러나 ILP에 정통하지는 않지만 정수 선형 프로그래밍에는 최대화 (또는 최소화)하려는 함수가 필요하다고 생각했지만 어디서나 볼 수 없습니다. 나는 Wikipedia에서만 반격하여 틀렸다.
chx

@chx, 나는 제약 조건의 타당성을 테스트하기 위해 ILP를 사용하고 있습니다. ILP 솔버에 원하는 목적 함수를 최대화 (예 : 0을 최대화)하도록 요청한 다음 목표 함수의 값을 무시하고 ILP가 실현 가능한지 여부 만 확인하면됩니다. ILP 솔버가 "불가능한"(크기가 계약 DAG가 없음을 의미 )이거나 "가능한"라고 응답하고 찾을 수있는 목적 함수의 최상의 가치를 제공합니다. 이 경우 목적 함수의 값을 무시합니다 (크기가 k 인 DAG가 있음을 알고 있음 ). 케이케이
DW

예를 들면, 참조 engineering.purdue.edu/~engelb/abe565/... ( "난 그냥 가능한 솔루션이 있는지 여부를 알고 싶은 존재합니다 .")
DW

선형 시간 솔루션과 관련하여; 나는 당신의 ILP 공식을 소화하지 않았으므로 그것을 판단 할 수는 없지만 문제가 NP-hard임을 증명할 수 있다고 확신합니다. 선형 시간 솔루션이 매우 편리합니다 : P. 곧 게시하겠습니다.
Realz Slaw

@RealzSlaw, 감사합니다! 이 경우 어딘가에 실수가 있었을 것입니다. (아직도 아직 확실하지는 않습니다.)
DW

5

참고 : AFAICT, DW 는이 축소에서 구멍을 발견했으며 잘못되었습니다 (주석 참조). 역사적인 이유로 여기에 보관하십시오.

소개 : 먼저 Monotone 3SAT 문제를 우리 문제로 줄입니다. 하지만 모노톤 3SAT의 문제가 하찮게 만족할 수있다, 우리의 문제는 더를 해결할 수 최소 진정한 모노톤 3SAT의 NP-어려운 문제; 따라서이 문제는 NP-hard입니다.

에서 감소 Monotone 3SAT 에서 문제로

변수의 시퀀스와 절의 시퀀스로 표현되는 모노톤 부울 공식이 있습니다. CNF는 Φ=(V,) 입니다.

(나는) 나는=(엑스제이엑스케이엑스)||(엑스제이,엑스케이,엑스V)

나는=1나는|나는,=||.

변환

그래프 합니다. G '의 각 정점'=V',이자형'' 에는 레이블이 있습니다. 라벨이 같은 정점이 수축 될 수 있습니다.

다음 우선 그래프를 구성 : 각 , 우리는 두 개의 노드을 각각 표시된 x를 I , 다른 하나에서 유향 에지 (고해상도보기 이미지를 클릭).엑스나는V엑스나는

여기에 이미지 설명을 입력하십시오

이 노드들은 물론 동일한 레이블을 가지고 있기 때문에 수축 될 수 있습니다. 우리는 계약 된 변수 / 노드를 거짓으로 간주하고 계약되지 않은 변수 / 노드를 참으로 간주합니다 :

여기에 이미지 설명을 입력하십시오

이 단계 후에 2 | V | 노드. 다음으로 절 제약 조건을 소개합니다. 각 절에 대해, c iC , c i = ( x jx kx l ) | x j , x k , x lV , 우리는 하나의 노드 c i 와 다음 모서리를 소개합니다.V'2|V|나는, 나는=(엑스제이엑스케이엑스)|엑스제이,엑스케이,엑스V나는

여기에 이미지 설명을 입력하십시오

나는1나는 . (전체 이미지를 보려면 이미지를 클릭하십시오)

2|V|+||노드.

엑스나는엑스제이 엑스케이나는나는 로 사이클이 발생합니다.

절 제약 조건을 풀면서 또 다른 시각화가 있습니다.

여기에 이미지 설명을 입력하십시오

따라서 각 절 제약 조건에는 포함 된 변수 중 하나 이상이 계약되지 않은 상태로 유지되어야합니다. 계약되지 않은 노드는 true로 평가되므로 변수 중 하나가 true 여야합니다. Monotone SAT가 절에 요구하는 것.

최소 True Monotone 3SAT에서 감소

모노톤 3SAT는 아주 만족 스럽습니다. 모든 변수를 true로 설정하면됩니다.

그러나 DAG 최소화 문제는 가장 많은 수축을 찾는 것이기 때문에 CNF에서 가장 잘못된 변수를 생성하는 만족스러운 할당을 찾는 것으로 해석됩니다. 최소 실제 변수를 찾는 것과 같습니다. 문제는 때때로 Minimum True Monotone 3SAT 또는 여기 (최적화 문제 또는 결정 문제) 또는 k-True Monotone 2SAT (약한 의사 결정 문제)라고합니다. NP- 하드 문제. 따라서 우리의 문제는 NP-hard입니다.


참고 문헌 :

그래프 소스 :


1
와. DW의 솔루션이 잘못 되었어야합니다 (또는 우리는 NP = P로 적어도 의심합니다 : P).
chx

(엑스1엑스2엑스6)(엑스1엑스4엑스5)(엑스엑스4엑스6)엑스1=엑스4=엑스6=그릇된 엑스2=엑스=엑스5=진실1엑스1엑스4엑스61

@DW 또한 여러분과 다시 대화하게되어 반갑습니다 : D, 행운을 빕니다. 우리 둘 다 맞다면 답에 P = NP가있을 것입니다! / jk
Realz Slaw 2016

(엑스1,엑스)

@RealzSlaw, 아직 팔로우하지 않는 것이 두렵습니다 ... 수식을 변환 해야하는 이유는 없습니다. 나는 이미 생각 입니다 최소 진정한 모노톤 3SAT의 인스턴스. 하지만 레벨을 올리겠습니다. 더 광범위하게, 제안 된 축소를 보았지만 축소가 정확하다는 주장은 보이지 않습니다. 축소가 정확하려면 YES 인스턴스를 YES 인스턴스로, NO 인스턴스를 NO 인스턴스로 맵핑해야합니다. 감축에 대한 정확성 증명을 작성하려고하면 내가 준 공식을 고려할 때 문제가 발생할 것으로 의심됩니다.
DW

1

각 대체 (직 부모-자식 교체를 제외하고)와 함께 새로운 조상-하위 관계를 추가하여 장기적으로 실제로 어느 것이 가치가 있는지 결정하는 것은 사소하지 않습니다. 따라서 간단한 탐욕 알고리즘은 일반적인 경우 실패합니다. 그러나 무차별 대입 방식을 사용하는 경우 가장 작은 그래프를 결정할 수 있습니다.

Python-ish (테스트되지 않음) :

def play((V,E),F,sequence=[]):
  """
  (V,E) -- a dag.
  V     -- a set of vertices.
  E     -- a set of directed-edge-tuples.
  F     -- a function that takes a vertex, returns an integer.
  sequence -- the sequence of moved taken so far; starts with/defaults to
              an empty list, will contain tuples of the form (x,y)
              where x is removed and replaced with y.

  Returns the best recursively found solution.
  """

  #find all the integer values in the graph, remember which
  # values correspond to what vertices. Of the form {integer => {vertices}}.
  n2v = {}
  for x in V:
    n = F(x)

    #for each integer, make sure you have a set to put the vertices in.
    if n not in n2v:
      n2v[n] = set()

    #for each integer, add the vertex to the equivalent set.
    n2v[n].add(v)

  #record the best sequence/solution. You start with the current sequence,
  # and see if you can obtain anything better.
  best_solution = list(sequence)

  #Now you will try to combine a single pair of vertices, obtain a new
  # graph and then recursively play the game again from that graph. 

  #for each integer and equivalent set of vertices,
  for n,vset in n2v.iteritems():

    #pick a pair of vertices
    for x in vset:
      for y in vset:

        #no point if they are the same.
        if x == y:
          continue

        #If there is a path from x => y or y => x, then you will be
        # introducing a cycle, breaking a rule. So in that case, disregard
        # this pair.
        #However, the exception is when one is a direct child of the other;
        # in that case you can safely combine the vertices.
        if pathtest((V,E),x,y) and (x,y) not in E and (x,y) not in E:
          continue

        #combine the vertices (function is defined below), discard x,
        # replace it with y, obtain the new graph, (V',E').
        Vp,Ep = combine_vertex((V,E),x,y))

        #record the sequence for this move.
        sequencep = list(sequence) + [(x,y)]

        #recurse and play the game from this new graph.
        solution = play(Vp,Ep,F,sequencep)

        #if the returned solution is better than the current best,
        if len(solution) > len(best_solution):
          #record the new best solution
          best_solution = solution
  #return the best recorded solution
  return best_solution


def combine_vertex((V0,E0),x,y):
  """
  (V0,E0)   -- an initial digraph.
  V0        -- a set of vertices.
  E0        -- a set of directed-edge-tuples.
  x         -- vertex to discard.
  y         -- vertex to replace it with.

  returns a new digraph replacing all relationships to and from x to relate
   to y instead, and removing x from the graph entirely.
  """

  #the final vertex set will have everything except x
  V = set(V0)
  V.discard(x)

  #now you construct the edge set.
  E = set()

  #for every edge,
  for (u0,v0) in E0:
    #recreate the edge in the new graph, but replace any occurence
    # of x.  
    u,v = u0,v0
    #if x is in the edge: replace it
    if u == x:
      u = y
    if v == x:
      v == y

    #sometimes u=v=y and can now be pointing to itself, don't add that
    # edge
    if u == v:
      continue

    #add the new/replaced edge into the edge-set.
    E.add( (u,v) )
  return (V,E)

정말 어려운 문제인지 확실하지 않지만 일부 그래프를 수동으로 재생하면 매우 조합적인 것처럼 보입니다. 어려운 문제 가이 문제로 축소 될 수 있는지 또는 실행 시간이 더 좋은 알고리즘이 있는지 궁금합니다.


1
나도 궁금하다 :)
chx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.