โครงสร้างข้อมูลสำหรับแผนที่เป็นระยะ


11

ให้เป็นจำนวนเต็มและให้แทนเซตของจำนวนเต็มทั้งหมด ลองแสดงว่าช่วงเวลาของจำนวนเต็ม\}nZ[a,b]{a,a+1,a+2,,b}

ฉันกำลังมองหาโครงสร้างข้อมูลที่จะเป็นตัวแทนของแผนที่{Z} ฉันต้องการโครงสร้างข้อมูลเพื่อสนับสนุนการดำเนินการต่อไปนี้:f:[1,n]Z

  • get(i)ควรกลับ(i)f(i)

  • set([a,b],y)ควรปรับปรุงเพื่อให้คือการปรับปรุงไปแผนที่ใหม่ดังกล่าวว่าสำหรับและสำหรับb]ff(a)=f(a+1)==f(b)=yfff(i)=yi[a,b]f(i)=f(i)i[a,b]

  • stab(i)ควรกลับช่วงเวลาที่ใหญ่ที่สุดเช่นนั้นและเป็นค่าคงที่ใน (เช่น )[a,b]i[a,b]f[a,b]f(a)=f(a+1)==f(b)

  • add([a,b],δ)ควรอัปเดตเป็นแผนที่ใหม่เช่นนั้นสำหรับและfff(i)=f(i)+δi[a,b]f(i)=f(i)สำหรับi[a,b] ]

ฉันต้องการให้การดำเนินการแต่ละอย่างมีประสิทธิภาพ ฉันจะนับเวลาหรืออย่างมีประสิทธิภาพ แต่เวลาช้าเกินไป มันก็โอเคถ้าเวลาการทำงานถูกตัดจำหน่ายเวลาการทำงาน มีโครงสร้างข้อมูลที่ทำให้การดำเนินการทั้งหมดเหล่านี้ไปพร้อม ๆO(1)O(lgn)O(n)

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


ฉันเดาว่าต้นไม้สเปรย์เป็นจุดเริ่มต้น addจะเป็นเส้นตรงในจำนวนช่วงเวลาย่อยของแม้ว่า; คุณเคยคิดเกี่ยวกับต้นไม้สเปรย์ที่มีโหนด“ ” ที่แตกต่างกันอย่างมาก [a,b]+δ
Gilles 'SO- หยุดความชั่วร้าย'

พิจารณาดังกล่าวว่าสำหรับทุก , Jจากนั้นคุณต้องมีค่าเก็บไว้ที่ใดที่หนึ่ง การแสดงมีการกำจัดค่าเหล่านั้นอย่างใด (โดยพวกเขาเขียนใหม่หรือการขว้างปาพวกเขาออกไป - คุณสามารถเลื่อนกับ GC แต่คุณจะต้องทำการดำเนินงาน ในบางจุด). เช่นการดำเนินการจะเป็น(n) ff(i)f(j)ijnset([a,b],y)O(n)O(n)
avakar

@avakar ฉันจะมีความสุขกับโซลูชันที่ปฏิบัติต่อ GC อย่างมีประสิทธิภาพ "ฟรี" โดยทั่วไปแล้วฉันจะมีความสุขกับการแก้ปัญหาที่เวลาทำงานจะถูกตัดจำหน่ายเวลาทำงาน (ดังนั้นค่าใช้จ่ายของ GC สามารถตัดจำหน่ายในค่าใช้จ่ายในการสร้างมูลค่าในสถานที่แรก)
DW

คุณสังเกตเห็นว่าเวลาคงที่และลอการิทึมนั้นมีประสิทธิภาพและเวลาเชิงเส้นช้า จะเวลาช้าเกินไปสำหรับความต้องการของคุณ? O(nlgn)
jbapple

@jbapple เฮ้มันเป็นการเริ่มต้นแล้ว! ฉันคิดว่านั่นเป็นเอกสารคำตอบที่คุ้มค่า
DW

คำตอบ:


4

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

แบบแผนง่ายๆ (รองรับการรับและการตั้งค่า แต่ไม่เพิ่มหรือแทง)

บอกว่าช่วงเวลาเป็นแบนถ้าฟังก์ชันเป็นค่าคงที่บน[ , ]คือถ้า( ) = F ( + 1 ) = = F ( )[a,b]f[a,b]f(a)=f(a+1)==f(b)

โครงสร้างข้อมูลอย่างง่ายของเราจะเป็นแผนผังช่วงเวลา ในคำอื่น ๆ เรามีต้นไม้ไบนารีที่แต่ละโหนดสอดคล้องกับช่วงเวลา (ของดัชนี) เราจะเก็บช่วงเวลาที่สอดคล้องกันในแต่ละโหนดvของต้นไม้ แต่ละใบจะตรงกับช่วงเวลาที่แบนและพวกเขาจะได้รับการจัดเพื่อให้อ่านออกใบซ้ายไปขวาจะช่วยให้เราลำดับของช่วงเวลาแบนติดต่อกันซึ่งเป็นเคล็ดและมีสหภาพแรงงานคือทั้งหมดของ[ 1 , n ] ช่วงเวลาสำหรับโหนดภายในจะเป็นการรวมกันของช่วงเวลาของลูกทั้งสอง นอกจากนี้ในโหนดใบไม้แต่ละโหนดเราจะเก็บค่าV ( )I(v)v[1,n]V()ของฟังก์ชันในช่วงเวลาI ( ) ที่สอดคล้องกับโหนดนี้ (โปรดทราบว่าช่วงนี้แบนดังนั้นfคือค่าคงที่ในช่วงเวลาดังนั้นเราจึงเก็บค่าfเดียวในโหนดใบแต่ละโหนด)fI()ff

เท่ากันคุณสามารถจินตนาการได้ว่าเราแบ่งพาร์ติชันออกเป็นช่วงแบน ๆ แล้วโครงสร้างข้อมูลคือแผนภูมิการค้นหาแบบไบนารี่โดยที่ปุ่มเป็นจุดสิ้นสุดด้านซ้ายของช่วงเวลาเหล่านั้น ใบมีค่าfในช่วงดัชนีบางช่วงที่fมีค่าคงที่[1,n]ff

ใช้วิธีการมาตรฐานเพื่อให้แน่ใจว่าต้นไม้ไบนารียังคงสมดุลเช่นความลึกของมันคือ (โดยที่mจะนับจำนวนใบปัจจุบันในต้นไม้) แน่นอนm nดังนั้นความลึกจึงอยู่ที่O ( lg n )เสมอ สิ่งนี้จะเป็นประโยชน์ด้านล่างO(lgm)mmnO(lgn)

ตอนนี้เราสามารถสนับสนุนการดำเนินการรับและตั้งค่าดังนี้:

  • เป็นเรื่องง่ายที่เราสำรวจต้นไม้ที่จะหาใบที่มีช่วงเวลาที่มีฉัน นี่เป็นเพียงการสำรวจแผนภูมิการค้นหาแบบไบนารี ตั้งแต่ความลึกเป็น O ( LG n ) , เวลาการทำงานเป็น O ( LG n )get(i)iO(lgn)O(lgn)

  • เป็นเล่ห์เหลี่ยม มันทำงานได้เช่นนี้:set([a,b],y)

    1. ก่อนอื่นเราจะพบช่วงเวลาของใบไม้ที่มีa ; ถ้า0 <แล้วเราแบ่งช่วงเวลานี้ใบเป็นสองช่วง[ 0 , - 1 ]และ[ , 0 ] (ดังนั้นการเปลี่ยนใบเหลืองนี้เป็นโหนดภายในและแนะนำเด็กสองคน)[a0,b0]aa0<a[a0,a1][a,b0]

    2. ต่อไปเราจะพบช่วงเวลาของใบไม้ที่มีb ; ถ้าb < b 1เราแบ่งช่วงเวลาของใบไม้นี้เป็นสองช่วง[ a 1 , b ]และ[ b + 1 , b 1 ] (ดังนั้นจึงเปลี่ยนโหนดใบนี้เป็นโหนดภายในและแนะนำลูกสองคน)[a1,b1]bb<b1[a1,b][b+1,b1]

    3. ณ จุดนี้ฉันอ้างว่าช่วงเวลาสามารถแสดงเป็นช่วงเวลาที่แยกจากกันของO ( lg n )ช่วงเวลาที่สอดคล้องกับชุดย่อยบางส่วนของโหนดO ( lg n )ในต้นไม้ ดังนั้นลบลูกหลานทั้งหมดของโหนดเหล่านั้น (เปลี่ยนเป็นใบ) และการตั้งค่าที่เก็บไว้ในต่อมน้ำเหล่านั้นไปยังY[a,b]O(lgn)O(lgn)y

    4. ในที่สุดเนื่องจากเราปรับเปลี่ยนรูปร่างของต้นไม้เราจะทำการหมุนที่จำเป็นเพื่อปรับสมดุลต้นไม้อีกครั้ง (โดยใช้เทคนิคมาตรฐานใด ๆ เพื่อรักษาสมดุลของต้นไม้)

    เนื่องจากการดำเนินการนี้เกี่ยวข้องกับการดำเนินงานที่เรียบง่ายไม่กี่โหนด (และชุดของโหนดที่สามารถพบได้ง่ายในO ( LG n )เวลา), เวลาทั้งหมดสำหรับการดำเนินการนี้เป็นO ( LG n )O(lgn)O(lgn)O(lgn)

สิ่งนี้แสดงให้เห็นว่าเราสามารถรองรับทั้งการรับและการตั้งค่าในเวลาต่อการดำเนินการ ในความเป็นจริงเวลาทำงานสามารถแสดงเป็นO ( lg min ( n , s ) )โดยที่sคือจำนวนชุดปฏิบัติการที่ดำเนินการจนถึงปัจจุบันO(lgn)O(lgmin(n,s))s

การเพิ่มการรองรับสำหรับการเพิ่ม

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

แม่นยำมากขึ้นค่าของฟังก์ชั่นในการป้อนข้อมูลที่ฉันจะได้รับคืนเป็นผลรวมของค่าที่เก็บไว้ในโหนดบนเส้นทางจากรากของต้นไม้ลงไปใบที่มีช่วงเวลาที่มีฉัน ในแต่ละโหนดVเราจะเก็บค่าV ( วี) ; ถ้าv 0 , v 1 , , v kแสดงถึงบรรพบุรุษของ leaf v k (รวมถึง leaf เอง) จากนั้นค่าของฟังก์ชันที่I ( v k )จะเป็นf(i)iivV(v)v0,v1,,vkvkI(vk) )V(v0)++V(vk)

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

และตอนนี้เราสามารถรองรับการอย่างมีประสิทธิภาพ ครั้งแรกที่เราแสดงช่วงเวลา[ , B ]เป็นสหภาพของO ( LG n )ช่วงเวลาที่สอดคล้องกับชุดบางส่วนของO ( LG n )โหนดในต้นไม้ (แยกโหนดที่ปลายทางซ้ายและปลายทางที่เหมาะสมถ้าจำเป็น) เหมือนกับที่ทำในขั้นตอนที่ 1-3 ของการตั้งค่า ตอนนี้เราเพียงแค่เพิ่มδให้กับค่าที่เก็บไว้ในแต่ละO ( lg n )add([a,b],δ)[a,b]O(lgn)O(lgn)δO(lgn)โหนด (เราไม่ลบลูกหลานของพวกเขา)

สิ่งนี้มีวิธีในการสนับสนุนรับตั้งค่าและเพิ่มในเวลาต่อการดำเนินการ ในความเป็นจริงเวลาทำงานต่อการดำเนินการคือO ( lg min ( n , s ) )โดยที่sจะนับจำนวนชุดการดำเนินการบวกจำนวนการเพิ่มการดำเนินการO(lgn)O(lgmin(n,s))s

รองรับการทำงานแบบแทง

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

(*) ช่วงเวลาสอดคล้องกับแต่ละ leaf คือช่วงสูงสุดแบบแบนI()

ที่นี่ผมบอกว่าช่วงเวลาเป็นช่วงเวลาแบนสูงสุดถ้า (i) [ , ]จะแบนและ (ii) ช่วงเวลาไม่มีมี[ , ]แบน (ในคำอื่น ๆ สำหรับทุก' , b พอใจ1 a a b b nทั้ง[ a , b ] = [[a,b][a,b][a,b]a,b1aabbnหรือ [ a , b ]ไม่แบน)[a,b]=[a,b][a,b]

สิ่งนี้ทำให้การดำเนินการแทงง่ายต่อการใช้งาน:

  • ค้นหา leaf ที่ช่วงเวลามี iและจากนั้นส่งคืนช่วงเวลานั้นstab(i)i

อย่างไรก็ตามตอนนี้เราจำเป็นต้องแก้ไขการตั้งค่าและเพิ่มการดำเนินการเพื่อรักษาค่าคงที่ (*) ทุกครั้งที่เราแยกใบออกเป็นสองเราอาจละเมิดคงที่ถ้าบางคู่อยู่ติดกันของใบช่วงเวลาที่มีค่าเดียวกันของฟังก์ชันฉโชคดีที่การดำเนินการแต่ละชุด / เพิ่มเพิ่มได้มากที่สุด 4 ช่วงเวลาลีฟใหม่ นอกจากนี้สำหรับแต่ละช่วงเวลาใหม่นั้นจะง่ายต่อการค้นหาช่วงเวลาของใบไม้ทันทีไปทางซ้ายและขวาของมัน ดังนั้นเราสามารถบอกได้ว่าค่าคงที่ถูกละเมิดหรือไม่ ถ้าเป็นเช่นนั้นเราจะรวมช่วงเวลาที่อยู่ติดกันโดยที่fมีค่าเท่ากัน โชคดีที่การรวมช่วงเวลาสองช่วงที่อยู่ติดกันไม่ได้ทำให้เกิดการเปลี่ยนแปลงเรียงซ้อน (ดังนั้นเราจึงไม่จำเป็นต้องตรวจสอบว่าการควบรวมกิจการอาจมีการละเมิดค่าคงที่เพิ่มเติมหรือไม่) ในทั้งหมดนี้เกี่ยวข้องกับการตรวจสอบ12ffคู่ของช่วงเวลาและอาจรวมเข้าด้วยกัน ในที่สุดเนื่องจากการควบรวมกิจการเปลี่ยนแปลงรูปร่างของต้นไม้ถ้าสิ่งนี้เป็นการละเมิดดุลคงที่ให้ทำการหมุนเวียนที่จำเป็นเพื่อรักษาความสมดุลของต้นไม้ (ทำตามเทคนิคมาตรฐานในการรักษาสมดุลต้นไม้ไบนารี) โดยรวมแล้วสิ่งนี้จะเพิ่มงานเพิ่มเติม O ( lg n )ส่วนใหญ่ให้กับการดำเนินการ set / add12=O(1)O(lgn)

ดังนั้นโครงสร้างข้อมูลขั้นสุดท้ายนี้สนับสนุนทั้งสี่การดำเนินงานและเวลาการทำงานสำหรับการดำเนินงานแต่ละคนคือ ) การประมาณการที่แม่นยำยิ่งขึ้นคือเวลาO ( lg min ( n , s ) )ต่อการดำเนินการโดยที่sจะนับจำนวนชุดและเพิ่มการดำเนินการO(lgn)O(lgmin(n,s))s

พรากจากความคิด

ว้านี่เป็นโครงการที่ค่อนข้างซับซ้อน ฉันหวังว่าฉันจะไม่ทำผิดพลาดใด ๆ โปรดตรวจสอบงานของฉันอย่างรอบคอบก่อนที่จะพึ่งพาวิธีนี้

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