ได้อย่างมีประสิทธิภาพการสุ่มตัวอย่างที่สั้นที่สุด


14

ให้เป็นกราฟและให้sและเสื้อมีสองจุดของG เราสามารถได้อย่างมีประสิทธิภาพตัวอย่างที่สั้นที่สุดs - เสื้อเส้นทางสม่ำเสมอและเป็นอิสระโดยการสุ่มจากชุดของเส้นทางที่สั้นที่สุดทั้งหมดระหว่างsและเสื้อ ? เพื่อความง่ายเราสามารถสรุปได้ว่าGนั้นง่ายไม่ได้บอกทิศทางและไม่มีน้ำหนักGstGststG

แม้ในกราฟที่ จำกัด จำนวนมากจำนวนเส้นทางที่สั้นที่สุดระหว่างและtสามารถเป็นเลขชี้กำลังเป็นขนาดGได้ ดังนั้นเราจึงจะเป็นธรรมชาติเหมือนจริงหลีกเลี่ยงการคำนวณทั้งหมดที่สั้นที่สุดs - เสื้อเส้นทาง ฉันไม่รู้เกี่ยวกับกรณีทั่วไป แต่สำหรับฉันแล้วเราสามารถทำสิ่งนี้เพื่อเรียนกราฟพิเศษได้stGst

รู้สึกเหมือนมีบางสิ่งที่บางคนต้องพิจารณาก่อน มีการวิจัยที่มีอยู่ในเรื่องนี้หรืออันที่จริงแล้วมันง่ายที่จะทำแม้กระทั่งกราฟทั่วไป?


คำถามที่ดี Juho ในขณะที่พิจารณาคำตอบคุณจะเข้าใจอะไรอย่างแม่นยำโดย "สุ่มตัวอย่างเส้นทางที่สุ่มอย่างสม่ำเสมอ" ถ้ามันพอเพียงสำหรับ s และ t ที่จะหยิบขึ้นมาแบบสุ่มคำถามนั้นเป็นเรื่องไร้สาระดังนั้นฉันเดาว่าคุณหมายถึงว่าโหนดทั้งหมดในเส้นทางที่สั้นที่สุดปรากฏขึ้นพร้อมกับความถี่ (เช่น. ความน่าจะเป็น) ซึ่งเป็นไปตามการแจกแจงแบบเดียวกัน หรือมีคำจำกัดความอื่น ๆ ? โดยเฉพาะอย่างยิ่งสำหรับกราฟสองฝ่ายคำถามของคุณดูเหมือนจะง่ายมากใช่ไหม
Carlos Linares López

1
@ CarlosLinaresLópezพิจารณาพูดว่ากราฟเพชรและพูดว่าอยู่ทางด้านขวาของ "แนวตั้งขอบ" และtอยู่ทางด้านซ้าย ขณะนี้มี 2 เส้นทางที่สั้นที่สุดระหว่างsและเสื้อ อัลกอริทึมควรกลับมาพร้อมความน่าจะเป็นที่เท่ากันไม่ว่าจะเป็นหนึ่งในสองเส้นทางนี้ ดังนั้นsและtไม่ใช่ "หยิบขึ้นมาแบบสุ่ม" แต่จะได้รับเป็นอินพุต นั่นทำให้ชัดเจนหรือไม่? ในแง่นี้ฉันไม่แน่ใจว่าปัญหานั้นง่ายสำหรับกราฟสองฝ่ายหรือไม่ ststst
Juho

1
@ CarlosLinaresLópezในคำอื่น ๆ เราจะได้รับกราฟและสองจุดs , เสื้อV ( G ) ให้Sเป็นชุดของเส้นทางที่สั้นที่สุดทั้งหมดระหว่างsและเสื้อ เอาท์พุทองค์ประกอบของSอย่างสม่ำเสมอ Gs,tV(G)SstS
Juho

คำตอบ:


6

ฉันไม่แน่ใจ 100% คำตอบนี้ถูกต้อง แต่ที่นี่จะไป:

ฉันคิดว่าคุณสามารถลดสิ่งนี้เป็นสุ่มเส้นทางใด ๆ อย่างสม่ำเสมอจากใน DAG ที่มีแหล่งเดียวและอ่างเดียวst

รับกราฟG

  1. HH
  2. แม่: เรียกใช้เป็นส่วนหนึ่งของ BFS ของ Dijkstra สั้นที่สุดเส้นทางเริ่มต้นจากเครื่องหมายโหนดทั้งหมดที่มีที่สั้นที่สุดระยะทางของพวกเขา from- sss
  3. ให้เป็นระยะทางต่ำสุดจากs - v ; ซึ่งเรารู้จากขั้นตอน BFS ของอัลกอริธึมทางลัดที่สั้นที่สุดของ Dijkstrad(s,v)sv
  4. จากนั้นทำขั้นตอนต่อไปของอัลกอริธึมทางลัดที่สั้นที่สุดของ Dijkstra รับเส้นทางที่สั้นที่สุดเก็บไว้ใน (โดยย้อนกลับจากtไปยังs )pts
  5. ตอนนี้เริ่มวนซ้ำต่อไปนี้ เปิดเผยในความคิดเห็นและด้านล่าง:
    • q0={t}
    • ในขณะที่q0
      • q1=
      • สำหรับuq0
        • ดังนั้นเราต้องการค้นหาโหนดถัดไปที่เป็นไปได้ทั้งหมดสำหรับพา ธ ย่อยสั้นที่สุดนี้จากtu
        • สำหรับเช่นนั้นd ( s , v ) < d ( s , u )edge(u,v)Gd(s,v)<d(s,u)
          • คือโหนดที่อยู่ใกล้เคียงโดยมีค่าน้อยลง d ( s , ) (มันจะน้อยกว่า 1 )vd(s,)1
          • ดังนั้นเป็น subpath ที่เป็นไปได้ในเส้นทางที่สั้นที่สุดtuv
          • ใส่vH,di-edge(u,v)H
          • ตอนนี้เราต้องตรวจสอบเพื่อนบ้านที่น้อยกว่าของในรอบถัดไปv
          • ใส่vq1
      • ตั้งค่าเป็นq 1 : q0q1
        • q0q1

โดยพื้นฐานแล้วฉันกำลังเก็บรวบรวมโหนดเป็นไปได้ทั้งหมดที่สามารถใช้ในที่สั้นเส้นทางและวางไว้ในHH

เพิ่มเติมเกี่ยวกับวิธีการทำงาน:

ของ Dijkstra สั้นที่สุดเส้นทางขั้นตอนวิธีการทำงานโดยครั้งแรกที่ทำงาน BFS และทำเครื่องหมายทุกโหนดมีเส้นทางที่สั้นที่สุดของพวกเขาจากs -วี ขั้นตอนต่อไปคือการย้อนกลับจากt - sและติดตามโหนดที่อยู่ติดกันน้อยที่สุดvGsvts

สิ่งที่เป็นที่นี่คุณสามารถเลือกใด ๆของโหนดข้างเคียงน้อย สิ่งที่ผมทำนี่คือการเก็บรวบรวมทั้งหมดโหนดน้อยเพื่อนบ้านแต่ละขั้นตอนซึ่งหมายความว่าฉันบัญชีสำหรับทุกที่สั้นที่สุดเส้นทาง

ตอนนี้คุณคิดอย่างรวดเร็ว แต่เดี๋ยวก่อนทำไมถึงแจกแจงเลขชี้กำลัง แต่วิธีของฉันไม่ได้

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

ตอนนี้เรามี DAG ที่เราสามารถสำรวจในทางใด ๆ จาก , และได้รับที่สั้นที่สุดย้อนกลับเส้นทางจากs -เสื้อ กราฟควรมีtเป็นแหล่งข้อมูลเท่านั้นและsเป็นอ่างล้างจานเท่านั้นtsstts


หากข้างต้นถูกต้องฉันคิดว่าเราสามารถทำขั้นตอนต่อไปและแก้ไขปัญหาได้ดังนี้

ให้แต่ละโหนดใน DAG เป็น node-weight โหนดน้ำหนักจะมีจำนวนของเส้นทางจากจากโหนดที่sขอให้เราเรียกสิ่งนี้ว่าW ( วี )sw(v)

คุณสามารถคำนวณเหล่านี้อย่างรวดเร็วดูขั้นตอนวิธีการที่พบจำนวนเส้นทางที่เรียบง่ายจาก s ไปทีจี

เมื่อเรามีน้ำหนักโหนดเราสามารถเลือกเส้นทางโดย:

  • จัดวาง DAG เป็นโครงสร้างระดับ (สำหรับการสร้างภาพข้อมูล)
  • ในแต่ละระดับเลือกลำดับโดยพลการระหว่างโหนดเช่น แนวคิดของ "จากซ้ายไปขวา"
  • การข้าม DAG: ในแต่ละขั้นตอน , i [ 1 , | p | ] (โดยที่||หมายถึงขนาดของในกรณีนี้ความยาวของเส้นทางที่สั้นที่สุด): ii[1,|p|]||
    • Let เป็นโหนดปัจจุบัน (เริ่มต้นที่T )uit
    • เพิ่มน้ำหนักทั้งหมดของลูกของและใช้ RNG เลือกโหนดย่อยหนึ่งโหนด, v i , ระหว่างเด็กที่ถ่วงน้ำหนักอย่างสม่ำเสมอuivi
    • ตั้งและไปที่ขั้นตอนถัดไปui+1=vi

โครงสร้างระดับและความคิดของจากซ้ายไปขวาเป็นส่วนหนึ่งของความพยายามเริ่มต้นของฉันเพียงแค่สร้างและเลือกเส้นทางด้วยวิธีนั้น แต่ฉันไม่ได้คิดอย่างนั้น คุณสามารถเพิกเฉยได้อย่างปลอดภัย r[0,w(t))
Realz Slaw

1
คำตอบนี้ดูดีมาก! ฉันชอบความคิด! ฉันพยายามเขียนออกมาในลักษณะที่แตกต่างออกไปเล็กน้อย (ในคำตอบของฉัน) เพื่อทดสอบความเข้าใจของฉัน ไม่ว่าในกรณีใดฉันแค่อยากจะแบ่งปันคำชื่นชมของฉันสำหรับคำตอบที่น่ารักนี้!
DW

5

นี่คือวิธีการแก้ปัญหาตามความคิดในคำตอบของ Realz Slaw โดยพื้นฐานแล้วเป็นการแสดงออกถึงความคิดของเขาอีกครั้งซึ่งอาจชัดเจนหรือง่ายต่อการติดตาม แผนคือเราจะดำเนินการในสองขั้นตอน:

  1. อันดับแรกเราจะสร้างกราฟมีคุณสมบัติต่อไปนี้: เส้นทางใด ๆ จากsถึงtในSคือเส้นทางที่สั้นที่สุดจากsถึงtในGและเส้นทางที่สั้นที่สุดจากsถึงtในGก็มีอยู่ในSด้วย ดังนั้นSประกอบด้วยเส้นทางที่สั้นที่สุดในG : เส้นทางที่สั้นที่สุดทั้งหมดและไม่มีอะไรเพิ่มเติม เมื่อมันเกิดขึ้นSจะเป็น DAGSstSstGstGSSGS

  2. ต่อไปเราจะได้ลิ้มลองอย่างสม่ำเสมอโดยการสุ่มจากทุกเส้นทางจากไปทีในSstS

วิธีนี้ generalizes ไปโดยพลการกำกับกราฟตราบเท่าที่ขอบทั้งหมดมีน้ำหนักในเชิงบวกดังนั้นฉันจะอธิบายขั้นตอนวิธีของฉันในคำเหล่านั้น Let W ( U , V )หมายถึงน้ำหนักในขอบยูวี (generalizes คำสั่งนี้ปัญหาที่คุณให้. ถ้าคุณมีกราฟไม่ได้ชั่งเพียงสมมติขอบทุกคนมีน้ำหนัก 1. ถ้าคุณมี undirected กราฟ, การรักษาขอบแต่ละไม่มีทิศทาง( U , V )ขณะที่ทั้งสองขอบกำกับยูV และV คุณ )Gw(u,v)uv(u,v)uvvu


ขั้นตอนที่ 1: สารสกัดจากSS เรียกใช้แหล่งเดียวอัลกอริทึมที่สั้นที่สุดเส้นทาง (เช่นอัลกอริทึมของ Dijkstra) บนเริ่มต้นจากแหล่งที่มาของ สำหรับแต่ละจุดสุดยอดวีในGให้d ( s , V )หมายถึงระยะทางจากsไปวีGsvGd(s,v)sv

ตอนนี้กำหนดกราฟดังนี้ มันประกอบด้วยขอบทุกU วีดังกล่าวว่า (1) U วีเป็นขอบในG , และ (2) d ( s , V ) = d ( s , U ) + W ( U , V )SuvuvGd(s,v)=d(s,u)+w(u,v)

กราฟมีคุณสมบัติที่สะดวก:S

  • เส้นทางที่สั้นที่สุดจากถึงtในGมีอยู่เป็นเส้นทางในS : เส้นทางที่สั้นที่สุดs = v 0 , v 1 , v 2 , , v k = tในGมีคุณสมบัติที่d ( s , v i + 1 ) = d ( s , v i ) + w ( v i , v istGSs=v0,v1,v2,,vk=tGเพื่อให้ขอบวีฉันวีฉัน+ 1อยู่ในSd(s,vi+1)=d(s,vi)+w(vi,vi+1)vivi+1S

  • ทุกเส้นทางในจากsไปทีเป็นเส้นทางที่สั้นที่สุดในG โดยเฉพาะอย่างยิ่งพิจารณาเส้นทางใด ๆ ในSจากsไปทีพูดs = v 0 , V 1 , V 2 , ... , วีk = T ความยาวของมันถูกกำหนดโดยผลรวมของน้ำหนักของขอบคือk i = 1 w ( v i - 1 , v i )SstGSsts=v0,v1,v2,,vk=ti=1kw(vi1,vi)แต่ตามนิยามของผลรวมนี้คือk i = 1 ( d ( s , v i ) - d ( s , v i - 1 ) , ซึ่งกล้องโทรทรรศน์ไปยังd ( s , t ) - d ( s , s ) = d ( s , t )ดังนั้นเส้นทางนี้เป็นเส้นทางที่สั้นที่สุดจากs ถึงtในGSi=1k(d(s,vi)d(s,vi1)d(s,t)d(s,s)=d(s,t)stG.

  • ในที่สุดการไม่มีขอบน้ำหนักศูนย์ในบอกเป็นนัยว่าSคือเดกGS

ขั้นตอนที่ 2: ตัวอย่างเส้นทางสุ่ม ตอนนี้เราสามารถทิ้งน้ำหนักบนขอบในที่และตัวอย่างเส้นทางสุ่มจากsไปทีในSSstS

หากต้องการความช่วยเหลือเกี่ยวกับเรื่องนี้เราจะทำ precomputation การคำนวณสำหรับแต่ละจุดสุดยอดวีในSที่n ( วี)นับจำนวนของเส้นทางที่แตกต่างจากวีไปที การคำนวณล่วงหน้าสามารถทำได้ในเวลาเชิงเส้นโดยการสแกนจุดยอดของSในลำดับการเรียงทอพอโลยีโดยใช้ความสัมพันธ์การเกิดซ้ำดังต่อไปนี้:n(v)vSn(v)vtS

n(v)=wsucc(v)n(w)

ที่หมายถึงผู้สืบทอดของโวลต์คือSucc ( V ) = { W : วีW  เป็นขอบใน  S }และที่เรามีกรณีฐานn ( T ) = 1succ(v)vsucc(v)={w:vw is an edge in S}n(t)=1

ต่อไปเราจะใช้คำอธิบายประกอบเพื่อสุ่มเส้นทางแบบสุ่ม เราเข้ามาครั้งแรกโหนดs จากนั้นเราจะสุ่มเลือกหนึ่งในผู้สืบทอดของsกับทายาทWถ่วงน้ำหนักด้วยn ( W ) ในคำอื่น ๆ :n()sswn(w)

choosesuccessor(v):
    n = 0
    for each w in succ(w):
        n = n + n(w)
    r = a random integer between 0 and n-1
    n = 0
    for each w in succ(w):
        n = n + n(w)
        if r < n:
            return w

ในการเลือกเส้นทางที่สุ่มเราซ้ำ ๆ ย้ำกระบวนการนี้คือและวีฉัน+ 1 = ( V ฉัน ) ส่งผลให้เส้นทางคือเส้นทางที่ต้องการและมันจะถูกเก็บตัวอย่างสม่ำเสมอโดยการสุ่มจากเส้นทางที่สั้นที่สุดจากทั้งหมดsไปทีv0=svi+1= choosesuccessor(vi)st

หวังว่านี่จะช่วยให้คุณเข้าใจโซลูชันของ Realz Slaw ได้ง่ายขึ้น เครดิตทั้งหมดให้กับ Realz Slaw สำหรับวิธีการแก้ปัญหาที่สวยงามและสะอาดสำหรับปัญหานี้!


กรณีหนึ่งนี้ไม่ได้จัดการเป็นกรณีที่ขอบบางมีน้ำหนัก 0 หรือน้ำหนักลบ อย่างไรก็ตามปัญหาอาจไม่ได้รับการกำหนดอย่างชัดเจนในกรณีดังกล่าวเนื่องจากคุณสามารถมีเส้นทางที่สั้นที่สุดได้หลายเส้นทาง


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