Kích thước tối thiểu của việc ký hợp đồng DAG thành DAG mới


15

Chúng tôi có một DAG. Chúng tôi có một chức năng trên các nút (nói một cách lỏng lẻo, chúng tôi đánh số các nút). Chúng tôi muốn tạo một biểu đồ có hướng mới với các quy tắc sau:F:VN

  1. Chỉ các nút có cùng số có thể được ký hợp đồng vào cùng một nút mới. . (Tuy nhiên, .)F(x)F(y)xyxyF(x)F(y)
  2. Chúng tôi thêm tất cả các cạnh cũ giữa các nút mới: .(x,y)Exy(x,y)E
  3. Biểu đồ mới này vẫn là một DAG.

Tối thiểu là gì? Một thuật toán tạo ra một đồ thị mới tối thiểu là gì?|V|


1
Vì vậy, vấn đề quyết định dường như là: đưa ra một DAG có màu đỉnh và một số nguyên , quyết định xem có một DAG nào với hầu hết các đỉnh được hình thành bằng cách tạo các đỉnh có cùng màu hay không. kkk
András Salamon

1
Nếu bạn ký hợp đồng với hai nút được kết nối, bạn có nhận được một vòng lặp tự cấm không?
Yuval Filmus

1
Không. Đọc 2. một lần nữa: chúng ta chỉ thêm cạnh nếu hai nút sau khi co vẫn khác nhau. Nếu hai nút được ký hợp đồng thành một, chúng ta không thêm cạnh.
chx

1
@chx Bạn đang yêu cầu "tối thiểu" hay "tối thiểu"?
Realz Slaw

1
bạn có thể cho một số động lực / bkg?
vzn

Câu trả lời:


5

Một cách tiếp cận để giải quyết vấn đề này là sử dụng lập trình tuyến tính số nguyên (ILP). Chúng ta hãy giải quyết phiên bản quyết định của vấn đề: cho , có cách nào để hợp đồng các đỉnh cùng màu để có DAG có kích thước không?kkk

Điều này có thể được thể hiện như là một ví dụ ILP bằng cách sử dụng các kỹ thuật tiêu chuẩn. Chúng tôi đã đưa ra màu sắc của từng đỉnh trong biểu đồ ban đầu. Tôi đề nghị chúng ta nên gắn nhãn cho mỗi đỉnh bằng một nhãn trong ; tất cả các đỉnh có cùng nhãn và cùng màu sẽ được ký hợp đồng. Vì vậy, vấn đề quyết định trở thành: có tồn tại một nhãn, sao cho việc ký kết tất cả các đỉnh cùng nhãn có cùng màu tạo ra một DAG không?{1,2,,k}

Để biểu thị điều này dưới dạng một chương trình tuyến tính số nguyên, hãy giới thiệu một biến số nguyên cho mỗi đỉnh , để thể hiện nhãn trên đỉnh . Thêm bất đẳng thức . v v 1 vkvvv1vk

Bước tiếp theo là thể hiện yêu cầu rằng đồ thị được ký hợp đồng phải là DAG. Lưu ý rằng nếu có một nhãn của biểu mẫu được liệt kê ở trên, mà không mất tính tổng quát thì sẽ tồn tại một nhãn như vậy trong đó các nhãn tạo ra một loại cấu trúc liên kết trên biểu đồ được ký hợp đồng (nghĩa là, nếu đứng trước trong biểu đồ được ký hợp đồng, thì nhãn của nhỏ hơn nhãn của ). Vì vậy, đối với mỗi cạnh trong biểu đồ ban đầu, chúng ta sẽ thêm ràng buộc rằng và có cùng nhãn và cùng màu, hoặc nhãn khác của nhỏ hơn nhãn của . Cụ thể, với mỗi cạnhw v w v w v w v w v w v , w vw v w v , w v < wvwvwvwvwvwvwtrong biểu đồ ban đầu trong đó có cùng màu, hãy thêm bất đẳng thức . Đối với mỗi cạnh trong đó có các màu khác nhau, hãy thêm bất đẳng thức .v,wvwvwv,wv<w

Bây giờ hãy xem nếu có bất kỳ giải pháp khả thi cho chương trình tuyến tính số nguyên này. Sẽ có một giải pháp khả thi nếu và chỉ khi việc ghi nhãn có dạng mong muốn (nghĩa là ký hợp đồng với tất cả các đỉnh cùng nhãn có cùng màu mang lại DAG). Nói cách khác, sẽ có một giải pháp khả thi nếu và chỉ khi có cách hợp đồng biểu đồ gốc với DAG có kích thước . Chúng ta có thể sử dụng bất kỳ bộ giải lập trình tuyến tính số nguyên; nếu người giải ILP cho chúng tôi câu trả lời, chúng tôi có câu trả lời cho vấn đề quyết định ban đầu.k

Tất nhiên, điều này không được đảm bảo để hoàn thành trong thời gian đa thức. Không có gì đảm bảo. Tuy nhiên, người giải quyết ILP đã nhận được khá tốt. Tôi hy vọng rằng, đối với một biểu đồ có kích thước hợp lý, bạn đã có cơ hội tốt rằng người giải ILP có thể giải quyết vấn đề này trong một khoảng thời gian hợp lý.

Cũng có thể mã hóa đây là một ví dụ SAT và sử dụng bộ giải SAT. Tôi không biết liệu điều đó sẽ hiệu quả hơn. Phiên bản ILP có lẽ dễ nghĩ hơn, mặc dù.

(Tôi hy vọng điều này đúng. Tôi đã không kiểm tra từng chi tiết một cách cẩn thận, vì vậy vui lòng kiểm tra lại lý do của tôi! Tôi hy vọng tôi đã không đi đâu đó.)


Cập nhật (21/10): Dường như ILP của hình thức này có thể được giải quyết theo thời gian tuyến tính, bằng cách xử lý DAG theo thứ tự sắp xếp theo cấu trúc liên kết và theo dõi giới hạn dưới trên nhãn cho mỗi đỉnh. Điều này khiến tôi nghi ngờ về giải pháp của mình: tôi đã phạm sai lầm ở đâu đó chưa?


Cảm ơn các câu trả lời chi tiết! Tôi nhận được những hạn chế và họ trông hợp lý. Tuy nhiên, trong khi tôi không rành về ILP, tôi nghĩ lập trình tuyến tính số nguyên cần một hàm bạn muốn tối đa hóa (hoặc tối thiểu hóa) và tôi không thấy điều đó ở bất cứ đâu. Tôi chỉ kiểm tra trong Wikipedia vì vậy tôi có thể sai.
chx

@chx, tôi đang sử dụng ILP để kiểm tra tính khả thi của các ràng buộc. Điều này có thể được thực hiện bằng cách yêu cầu người giải ILP tối đa hóa bất kỳ hàm mục tiêu nào bạn thích (ví dụ: tối đa hóa 0), sau đó bỏ qua giá trị của hàm mục tiêu và chỉ xem liệu ILP có khả thi hay không. Bộ giải ILP trả lời "Không khả thi" (có nghĩa là không có DAG có kích thước ) hoặc nó đáp ứng "Khả thi" và cung cấp giá trị tốt nhất của hàm mục tiêu mà nó có thể tìm thấy; trong trường hợp đó, bạn bỏ qua giá trị của hàm mục tiêu (và bạn biết rằng có tồn tại một DAG có kích thước k ). kk
DW

Xem, ví dụ, Engineering.purdue.edu/~engelb/abe565/ ((Tôi chỉ muốn biết liệu có tồn tại một giải pháp khả thi hay không . ")
DW

Về giải pháp thời gian tuyến tính của bạn; Tôi chưa tiêu hóa công thức ILP của bạn, vì vậy tôi không thể đánh giá nó, nhưng tôi khá chắc chắn rằng tôi có thể chứng minh vấn đề là NP-hard, điều này sẽ tạo ra một giải pháp thời gian tuyến tính khá tiện dụng: P. Tôi sẽ đăng nó sớm.
Realz Slaw

@RealzSlaw, cảm ơn bạn! Trong trường hợp đó, tôi cực kỳ nghi ngờ mình có thể đã sai ở đâu đó (mặc dù tôi không chắc là mình đã ở đâu).
DW

5

LƯU Ý: AFAICT, DW đã tìm thấy một lỗ hổng trong việc giảm này và nó đã sai (xem bình luận). Giữ nó ở đây vì lý do lịch sử.

Giới thiệu : đầu tiên tôi sẽ giảm vấn đề Monotone 3SAT cho vấn đề của chúng tôi. Mặc dù vấn đề Monotone 3SAT là thỏa đáng tầm thường, nhưng vấn đề của chúng tôi có thể giải quyết thêm vấn đề tối thiểu 3SAT True Monotone tối thiểu , đó là NP-hard; do đó, vấn đề này là NP-hard.

Giảm từ Monotone 3SAT cho vấn đề của chúng tôi

Chúng ta có một công thức boolean đơn điệu được biểu thị dưới dạng một chuỗi các biến và một chuỗi các mệnh đề. CNF có dạng sao cho:Φ=(V,C)

(ciC) ci=(xjxkxl)||(xj,xk,xlV)

i=1nci|ciC,n=|C|.

Chuyển đổi

Chúng ta xây dựng đồ thị, . Mỗi đỉnh trong G ' có nhãn; các đỉnh có cùng nhãn đủ điều kiện để co.G=V,EG

Trước tiên, chúng tôi xây dựng biểu đồ như sau: với mỗi , chúng tôi tạo hai nút, mỗi nút có nhãn x i và cạnh được định hướng từ điểm này sang điểm khác (nhấp vào hình ảnh để xem độ phân giải cao).xiVxi

nhập mô tả hình ảnh ở đây

Các nút này tất nhiên có thể được ký hợp đồng, bởi vì chúng có cùng nhãn. Chúng tôi sẽ xem xét các biến / nút được ký hợp đồng là có giá trị là sai và các nút không bị thu hút được định giá là đúng :

nhập mô tả hình ảnh ở đây

V2|V|ciC, ci=(xjxkxl)|xj,xk,xlVci

nhập mô tả hình ảnh ở đây

ci1ci

2|V|+|C|

xixj xkcici

Đây là một hình dung khác, bỏ kiểm soát ràng buộc mệnh đề:

nhập mô tả hình ảnh ở đây

Do đó, mỗi ràng buộc mệnh đề yêu cầu ít nhất một trong số các biến mà nó chứa vẫn không bị thu hút; vì các nút không bị thu hút có giá trị là true, điều này đòi hỏi một trong các biến là đúng; chính xác những gì Monotone SAT yêu cầu cho các mệnh đề của nó.

Giảm từ tối thiểu 3 đơn vị thật

Monotone 3SAT là thỏa đáng tầm thường; bạn chỉ có thể đặt tất cả các biến thành đúng.

Tuy nhiên, vì vấn đề tối thiểu hóa DAG của chúng tôi là tìm ra nhiều cơn co thắt nhất, điều này có nghĩa là tìm ra sự phân công thỏa mãn tạo ra các biến sai nhất trong CNF của chúng tôi; đó là giống như tìm các biến thực tối thiểu. Đây vấn đề đôi khi được gọi là tối thiểu Đúng đơn điệu 3SAT hoặc ở đây (như là một vấn đề tối ưu hóa, hay vấn đề quyết định), hoặc k-Đúng đơn điệu 2SAT (như là một vấn đề quyết định yếu); cả vấn đề NP-hard. Do đó, vấn đề của chúng tôi là NP-hard.


Người giới thiệu:

Nguồn đồ thị:


1
ồ thì giải pháp của DW phải sai (hoặc chúng tôi đã chứng minh NP = P mà tôi ít nhất nghi ngờ: P) - nhưng ở đâu?
chx

(x1x2x6)(x1x4x5)(x3x4x6)x1=x4=x6=False x2=x3=x5=Truec1x1x4x6c1

@DW Cũng rất vui được nói chuyện lại với bạn: D, và chúc may mắn, nếu cả hai chúng tôi đều đúng, chúng tôi có thể có P = NP trong câu trả lời của bạn! / jk
Realz Slaw

(x1,x3)

@RealzSlaw, tôi e rằng tôi chưa theo dõi ... Tôi không thấy bất kỳ lý do nào khiến công thức của tôi phải được chuyển đổi. Tôi tin rằng nó đã một phiên bản tối thiểu 3SAT True True Monotone. Nhưng hãy để tôi đưa nó lên một cấp độ. Nhìn rộng hơn, tôi thấy mức giảm được đề xuất, nhưng tôi không thấy bất kỳ lập luận nào cho thấy mức giảm đó là chính xác - điều đó còn thiếu. Để giảm chính xác, nó phải ánh xạ các trường hợp CÓ thành các trường hợp CÓ và các trường hợp KHÔNG, thành các trường hợp KHÔNG. Tôi nghi ngờ rằng nếu bạn cố gắng viết ra một bằng chứng chính xác cho việc giảm bớt của mình, bạn sẽ gặp phải một vấn đề khi bạn xem xét công thức tôi đưa ra.
DW

1

Với mỗi lần thay thế (ngoại trừ thay thế cha mẹ trực tiếp - con), bạn thêm các mối quan hệ hậu duệ tổ tiên mới khiến việc này không quan trọng để xác định xem cái nào thực sự có giá trị trong dài hạn. Do đó, một thuật toán tham lam đơn giản sẽ thất bại trong trường hợp chung. Tuy nhiên, nếu bạn thực hiện một cách tiếp cận mạnh mẽ, bạn có thể xác định biểu đồ nhỏ nhất:

Python-ish (chưa được kiểm tra):

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)

Tôi không chắc chắn nếu nó thực sự là một vấn đề khó khăn, nhưng chơi với một số biểu đồ bằng tay, nó có vẻ rất kết hợp. Tôi tò mò liệu một cái gì đó khó khăn có thể được giảm bớt cho vấn đề này, hoặc nếu có một thuật toán với thời gian chạy tốt hơn.


1
Tôi cũng tò mò :)
chx
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.