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


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,t∈V(G)SstS
— Juho

คำตอบ:


6

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

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

รับกราฟG

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

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

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

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

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

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

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

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


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

ให้แต่ละโหนดใน 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)u→v(u,v)u→vv→u


ขั้นตอนที่ 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 )Su→vu→vGd(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)vi→vi+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=t∑i=1kw(vi−1,vi)แต่ตามนิยามของผลรวมนี้คือ∑ k i = 1 ( d ( s , v i ) - d ( s , v i - 1 ) , ซึ่งกล้องโทรทรรศน์ไปยังd ( s , t ) - d ( s , s ) = d ( s , t )ดังนั้นเส้นทางนี้เป็นเส้นทางที่สั้นที่สุดจากs ถึงtในGS∑i=1k(d(s,vi)−d(s,vi−1)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)=∑w∈succ(v)n(w)

ที่หมายถึงผู้สืบทอดของโวลต์คือSucc ( V ) = { W : วี→ W  เป็นขอบใน  S }และที่เรามีกรณีฐานn ( T ) = 1succ(v)vsucc(v)={w:v→w 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.