ขนาดที่เล็กที่สุดของการทำสัญญา DAG เป็น DAG ใหม่


15

เรามี DAG เรามีฟังก์ชั่นบนโหนด (พูดอย่างอิสระเรานับจำนวนโหนด) เราต้องการสร้างกราฟกำกับใหม่ด้วยกฎเหล่านี้:F:Vยังไม่มีข้อความ

  1. เฉพาะโหนดที่มีหมายเลขเท่ากันเท่านั้นที่สามารถทำการต่อสัญญาในโหนดใหม่เดียวกันได้ Y' (อย่างไรก็ตาม, .)F(x)F(Y)x'Y'x'Y'F(x)F(Y)
  2. เราได้เพิ่มทุกขอบเก่าระหว่างโหนดใหม่: (x,Y)Ex'Y'(x',Y')E'E'
  3. กราฟใหม่นี้ยังคงเป็น DAG

อะไรคือสิ่งที่น้อยที่สุด|V'|? อัลกอริทึมคืออะไรสร้างกราฟใหม่ที่น้อยที่สุด


1
ดังนั้นปัญหาการตัดสินใจน่าจะเป็น: กำหนด DAG สีจุดยอดและจำนวนเต็มkตัดสินใจว่ามี DAG ที่จุดสูงสุดkส่วนใหญ่ที่kเกิดขึ้นจากการทำสัญญาจุดที่มีสีเดียวกันหรือไม่
András Salamon

1
หากคุณติดตั้งโหนดที่เชื่อมต่อสองโหนดคุณจะต้องทำการวนซ้ำตัวเองแบบต้องห้ามหรือไม่?
Yuval Filmus

1
Nope อ่าน 2 อีกครั้ง: เราเพิ่มขอบเท่านั้นหากทั้งสองโหนดหลังจากการหดตัวยังคงแตกต่างกัน หากสองโหนดรับสัญญาเป็นหนึ่งเราจะไม่เพิ่ม edge
chx

1
@chx คุณกำลังขอ "ขั้นต่ำ" หรือ "ขั้นต่ำ" หรือไม่?
Realz Slaw

1
คุณสามารถให้แรงจูงใจ / bkg
vzn

คำตอบ:


5

วิธีหนึ่งในการแก้ปัญหานี้คือใช้การเขียนโปรแกรมเชิงเส้นจำนวนเต็ม (ILP) มาจัดการปัญหาของเวอร์ชันการตัดสินใจ: ให้มีวิธีทำสัญญาจุดยอดสีเดียวกันเพื่อให้ได้ DAG ที่มีขนาดหรือไม่?kkk

ซึ่งสามารถแสดงเป็นอินสแตนซ์ของ ILP ได้โดยใช้เทคนิคมาตรฐาน เราได้สีของแต่ละจุดยอดในกราฟต้นฉบับ ฉันขอแนะนำให้เราติดป้ายจุดสุดยอดแต่ละจุดด้วยป้ายกำกับใน ; จุดยอดทั้งหมดที่มีป้ายชื่อเดียวกันและสีเดียวกันจะถูกทำสัญญา ดังนั้นปัญหาการตัดสินใจกลายเป็น: มีการติดฉลากหรือไม่เช่นนั้นการทำสัญญาจุดยอดเดียวกัน - สีเดียวกันทั้งหมดให้ DAG หรือไม่{1,2,,k}

ในการแสดงนี้เป็นจำนวนเต็มเชิงเส้นโปรแกรมแนะนำจำนวนเต็มตัวแปรสำหรับแต่ละจุดสุดยอดเพื่อเป็นตัวแทนของฉลากบนจุดสุดยอดวีเพิ่มความไม่สมดุลกันkวีวี1 วีkvvv1vk

ขั้นตอนต่อไปคือการแสดงความต้องการที่กราฟสัญญาจะต้องเป็น DAG ขอให้สังเกตว่าถ้ามีการติดฉลากในรูปแบบดังกล่าวข้างต้นโดยไม่สูญเสียของทั่วไปมีอยู่การติดฉลากดังกล่าวที่ฉลากเหนี่ยวนำให้เกิดการจัดเรียงทอพอโลยีในรูปแบบของกราฟหดตัว (เป็นเช่นถ้าแจ๋วในกราฟหดแล้ว 's ฉลาก เล็กกว่าป้ายกำกับของ ) ดังนั้นสำหรับแต่ละขอบในกราฟต้นฉบับเราจะเพิ่มข้อ จำกัด ที่และมีป้ายกำกับและสีเดียวกันหรือมิฉะนั้นป้ายกำกับของจะเล็กกว่าป้ายกำกับของโดยเฉพาะสำหรับแต่ละขอบW V W วีW V W V W วีW V , W วีWวีW V , W วี < Wvwโวลต์Wโวลต์Wโวลต์Wโวลต์Wโวลต์Wในรูปแบบของกราฟเริ่มต้นที่มีสีเดียวกันให้เพิ่มความไม่สมดุลกัน\ สำหรับแต่ละขอบที่มีสีที่แตกต่างกันเพิ่มความไม่เท่าเทียมกัน<\โวลต์,Wโวลต์Wโวลต์Wโวลต์,Wโวลต์<W

ตอนนี้ดูว่ามีวิธีแก้ปัญหาที่เป็นไปได้สำหรับโปรแกรมเชิงเส้นจำนวนเต็มนี้ จะมีวิธีแก้ปัญหาที่เป็นไปได้ถ้าหากว่าการติดฉลากนั้นอยู่ในรูปแบบที่ต้องการ (เช่นการทำสัญญาจุดยอดเดียวกันสีเดียวกันทั้งหมดให้ DAG) ในคำอื่น ๆ จะมีวิธีการแก้ปัญหาที่เป็นไปได้และถ้าหากมีวิธีการหดตัวของกราฟเดิม DAG ขนาดที่k เราสามารถใช้แก้การเขียนโปรแกรมเชิงเส้นจำนวนเต็มใด ๆ หากนักแก้ปัญหา ILP ให้คำตอบกับเราเรามีคำตอบสำหรับปัญหาการตัดสินใจเดิมk

แน่นอนว่านี่ไม่รับประกันว่าจะเสร็จสมบูรณ์ในเวลาพหุนาม ไม่มีการรับประกัน อย่างไรก็ตามนักแก้ปัญหา ILP ได้ค่อนข้างดี ฉันคาดหวังว่าสำหรับกราฟขนาดที่เหมาะสมคุณมีโอกาสดีที่ตัวแก้ไข ILP อาจสามารถแก้ปัญหานี้ได้ในเวลาที่เหมาะสม

เป็นไปได้ที่จะเข้ารหัสสิ่งนี้เป็นอินสแตนซ์ SAT และใช้ตัวแก้ SAT ฉันไม่รู้ว่ามันจะมีประสิทธิภาพมากกว่านี้หรือไม่ แม้ว่ารุ่น ILP น่าจะง่ายกว่าที่คิด

(ฉันหวังว่านี่ถูกต้องฉันไม่ได้ตรวจสอบทุกรายละเอียดอย่างถี่ถ้วนดังนั้นโปรดตรวจสอบเหตุผลของฉันอีกครั้ง!


อัปเดต (10/21): ดูเหมือนว่า ILP ของแบบฟอร์มนี้สามารถแก้ไขได้ในเวลาเชิงเส้นโดยการประมวลผล DAG ตามลำดับทอพอโลยีเรียงลำดับและติดตามขอบเขตล่างบนฉลากสำหรับแต่ละจุดสุดยอด สิ่งนี้ทำให้ฉันสงสัยวิธีแก้ปัญหาของฉัน: ฉันทำผิดพลาดที่ไหนสักแห่งหรือไม่?


ขอบคุณสำหรับคำตอบอย่างละเอียด! ฉันได้รับข้อ จำกัด และพวกเขาดูสมเหตุสมผล อย่างไรก็ตามในขณะที่ฉันไม่ชำนาญใน ILP ฉันคิดว่าการเขียนโปรแกรมเชิงเส้นจำนวนเต็มจำเป็นต้องใช้ฟังก์ชั่นที่คุณต้องการเพิ่ม (หรือย่อให้เล็กสุด) และฉันไม่เห็นว่าทุกที่ ฉันตอบโต้ใน Wikipedia เท่านั้นดังนั้นฉันอาจผิด
chx

@chx ฉันใช้ ILP เพื่อทดสอบความเป็นไปได้ของข้อ จำกัด สิ่งนี้สามารถทำได้โดยขอให้ ILP แก้เพื่อเพิ่มฟังก์ชั่นวัตถุประสงค์ใด ๆ ที่คุณต้องการ (เช่นเพิ่มสูงสุด 0) แล้วมองข้ามคุณค่าของฟังก์ชั่นวัตถุประสงค์และมองเพียงเพื่อดูว่า ILP เป็นไปได้หรือไม่ ตัวแปล ILP ตอบสนอง "Infeasible" (ซึ่งหมายความว่าไม่มี DAG ขนาดหดตัว ) หรือตอบสนอง "Feasible" และให้คุณค่าที่ดีที่สุดของฟังก์ชันวัตถุประสงค์ที่สามารถหาได้ ในกรณีนั้นคุณจะไม่สนใจค่าของฟังก์ชันวัตถุประสงค์ (และคุณรู้ว่ามี DAG ที่มีขนาดk ) kk
DW

ดูเช่นengineering.purdue.edu/~engelb/abe565/... ( "ฉันแค่อยากจะรู้หรือไม่ว่าวิธีการแก้ปัญหาที่เป็นไปได้ที่มีอยู่ .")
DW

เกี่ยวกับการแก้ปัญหาเวลาเชิงเส้นของคุณ ฉันยังไม่ย่อยสูตร ILP ของคุณดังนั้นฉันจึงไม่สามารถตัดสินได้ แต่ฉันค่อนข้างมั่นใจว่าฉันสามารถพิสูจน์ได้ว่าปัญหาคือ NP-hard ซึ่งจะทำให้การแก้ปัญหาเชิงเส้นเวลามีประโยชน์มาก: P ฉันจะโพสต์มันในไม่ช้า
Realz Slaw

@ RealzSlaw ขอบคุณ! ในกรณีนี้ฉันสงสัยอย่างมากว่าฉันอาจผิดพลาดบางแห่ง (แม้ว่าฉันยังไม่แน่ใจว่าอยู่ที่ไหน)
DW

5

หมายเหตุ: AFAICT, DWพบช่องโหว่ในการลดลงนี้และมันผิด (ดูความคิดเห็น) เก็บไว้ที่นี่ด้วยเหตุผลทางประวัติศาสตร์

คำแนะนำ : ก่อนอื่นฉันจะลดปัญหาMonotone 3SAT เป็นปัญหาของเรา ถึงแม้ว่าปัญหาMonotone 3SATนั้นน่าพึงพอใจเล็กน้อย แต่ปัญหาของเราสามารถแก้ไขปัญหาขั้นต่ำ True Monotone 3SATซึ่งเป็น NP-hard; ดังนั้นปัญหานี้คือปัญหา NP-hard

ลดจากMonotone 3SATเป็นปัญหาของเรา

เรามีสูตรบูลีน monotone ที่แสดงเป็นลำดับของตัวแปรและลำดับของข้อ CNF อยู่ในรูปแบบเช่นนั้น:Φ=(V,C)

และ

(ผม) ผม=(xJxkxล.)||(xJ,xk,xล.V)

ผม=1nผม|ผม,n=||.

การแปลง

เราสร้างกราฟ ' แต่ละจุดสุดยอดในG มีฉลาก จุดยอดที่มีป้ายกำกับเดียวกันมีสิทธิ์ได้รับการหดG'=V',E'G'

ก่อนอื่นเราสร้างกราฟดังนี้: สำหรับแต่ละเราสร้างสองโหนดแต่ละอันที่มีเลเบลx iและขอบกำกับจากที่หนึ่งไปอีกที่หนึ่ง (คลิกที่ภาพเพื่อดูความละเอียดสูง)xผมVxผม

ป้อนคำอธิบายรูปภาพที่นี่

แน่นอนว่าโหนดเหล่านี้สามารถต่อสัญญาได้เนื่องจากมีป้ายกำกับเหมือนกัน เราจะพิจารณาตัวแปร / โหนดที่ทำสัญญาว่ามีมูลค่าเป็นเท็จและผู้ที่ไม่ได้รับการว่าจ้างให้ถือว่ามีมูลค่าเป็นจริง :

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากขั้นตอนนี้ควรมี2 | V | โหนด ต่อไปเราจะแนะนำข้อ จำกัด ของข้อ สำหรับแต่ละส่วนคำสั่งc iC , c i = ( x jx kx l ) | x j , x k , x lVเราแนะนำหนึ่งโหนดc iและขอบต่อไปนี้:V'2|V|ผม, ผม=(xJxkxล.)|xJ,xk,xล.Vผม

ป้อนคำอธิบายรูปภาพที่นี่

ผม1ผม

2|V|+||

xผมxJ xkผมผม

นี่คือการสร้างภาพข้อมูลอีกครั้งโดยการคลี่ข้อ จำกัด ของข้อ:

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นข้อ จำกัด แต่ละข้อต้องการว่าอย่างน้อยหนึ่งในตัวแปรที่มีอยู่ยังคงไม่มีการทำสัญญา เนื่องจากโหนดที่ไม่มีการติดต่อมีค่าเป็นจริงจึงต้องมีหนึ่งในตัวแปรที่เป็นจริง สิ่งที่ Monotone SAT ต้องการสำหรับคำสั่ง

ลดจากขั้นต่ำ True Monotone 3SAT

Monotone 3SAT นั้นน่าพึงพอใจเล็กน้อย คุณสามารถตั้งค่าตัวแปรทั้งหมดให้เป็นจริงได้

อย่างไรก็ตามเนื่องจากปัญหาการย่อขนาด DAG ของเราคือการค้นหาการหดตัวมากที่สุดซึ่งแปลว่าการค้นหาการมอบหมายที่น่าพอใจซึ่งสร้างตัวแปรที่ผิดพลาดมากที่สุดใน CNF ของเรา ซึ่งเหมือนกับการค้นหาตัวแปรจริงขั้นต่ำ นี้ปัญหาบางครั้งเรียกว่าขั้นต่ำที่ทรู Monotone 3SATหรือนี่ (เป็นปัญหาการเพิ่มประสิทธิภาพหรือปัญหาการตัดสินใจ) หรือK-True Monotone 2SAT (เป็นปัญหาการตัดสินใจที่อ่อนแอ); ทั้งปัญหา NP-hard ดังนั้นปัญหาของเราคือ NP-hard


อ้างอิง:

แหล่งกราฟ:


1
ว้าว. ดังนั้นทางออกของ DW ต้องผิด (หรือเราได้พิสูจน์ NP = P ซึ่งฉันค่อนข้างสงสัยอย่างน้อย: P) - แต่ที่ไหน?
chx

(x1x2x6)(x1x4x5)(x3x4x6)x1=x4=x6=เท็จ x2=x3=x5=จริง1x1x4x61

@DW ยินดีที่ได้คุยกับคุณอีกครั้ง: D และขอให้โชคดีถ้าเราทั้งคู่ถูกต้องเราอาจมี P = NP ในคำตอบของคุณ! / jk
Realz Slaw

(x1,x3)

@ RealzSlaw ฉันเกรงว่าฉันยังไม่ทำตาม ... ฉันไม่เห็นเหตุผลที่จะต้องแปลงสูตรของฉัน ฉันเชื่อว่ามันเป็นตัวอย่างของ Minimum True Monotone 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)

ฉันไม่แน่ใจว่ามันเป็นปัญหาจริงหรือไม่ แต่การเล่นด้วยกราฟบางอย่างด้วยตนเองดูเหมือนว่าจะเป็น combinatorial มาก ฉันอยากรู้ว่าสิ่งที่ยากสามารถลดปัญหานี้ได้หรือถ้ามีอัลกอริทึมที่มีเวลาทำงานที่ดีขึ้น


1
ผมอยากรู้มากเกินไป :)
CHX
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.