จะสร้างค่าที่กระจายอย่างสม่ำเสมอในช่วงเวลาได้อย่างมีประสิทธิภาพได้อย่างไร


12

(a, b)สมมติว่าผมต้องการที่จะสร้างชุดของตัวเลขสุ่มจากช่วงเวลาที่ ลำดับที่สร้างควรมีคุณสมบัติที่เรียงลำดับด้วย ฉันสามารถนึกถึงสองวิธีในการบรรลุเป้าหมายนี้

อนุญาตnเป็นความยาวของลำดับที่จะสร้าง

อัลกอริทึมที่ 1:

Let `offset = floor((b - a) / n)`
for i = 1 up to n:
   generate a random number r_i from (a, a+offset)
   a = a + offset
   add r_i to the sequence r

อัลกอริทึมที่ 2:

for i = 1 up to n:
    generate a random number s_i from (a, b)
    add s_i to the sequence s
sort(r)

คำถามของฉันคืออัลกอริทึม 1 สร้างลำดับที่ดีเท่าที่สร้างโดยอัลกอริทึม 2 หรือไม่


BTW Rมันเป็นเรื่องง่ายอย่างน่าทึ่งเพื่อสร้างรายการของตัวเลขสุ่มเรียงใน เพื่อที่จะสร้างอาร์เรย์ของชุดตัวเลขสุ่มมากกว่าช่วงเครื่องแบบ , รหัสต่อไปนี้การทำงาน: kn[a,]rand_array <- replicate(k, sort(runif(n, a, b))
RobertF

คำตอบ:


18

อัลกอริทึมแรกล้มเหลวอย่างไม่ดีด้วยเหตุผลสองประการ:

  1. การใช้พื้นของสามารถลดความรุนแรงลงได้ อันที่จริงเมื่อมันจะเป็นศูนย์ให้ชุดที่มีค่าเหมือนกันทั้งหมด!(ab)/n-a<n

  2. เมื่อคุณไม่ปูพื้นค่าที่ได้จะถูกกระจายอย่างสม่ำเสมอ ยกตัวอย่างเช่นในตัวอย่างแบบสุ่มใด ๆ ของชุดเครื่องแบบ iid (พูดระหว่างและ ) จะมีโอกาสที่ ที่ใหญ่ที่สุดจะไม่อยู่ในช่วงเวลาที่ส่วนบนเพื่อ1ด้วยอัลกอริทึม 1 มีโอกาสที่ค่าสูงสุดจะอยู่ในช่วงเวลานั้น สำหรับจุดประสงค์บางอย่างความสม่ำเสมอที่ดีนี้เป็นสิ่งที่ดี แต่โดยทั่วไปแล้วมันเป็นข้อผิดพลาดที่น่ากลัวเพราะ (ก) สถิติจำนวนมากจะถูกทำลาย แต่ (ข) มันยากที่จะระบุว่าทำไมna=0=11 - 1 / n 1 100 %(1-1/n)n1/อี37%1-1/n1100%

  3. หากคุณต้องการหลีกเลี่ยงการเรียงลำดับให้สร้างความแปรปรวนแบบแจกแจงอิสระแทนแทน ทำให้ผลรวมสะสมของพวกเขากลับสู่ระดับปกติโดยการหารด้วยผลรวม ปล่อยค่าที่มากที่สุด (ซึ่งจะเป็น ) rescale ในช่วงB)( 0 , 1 ) 1 ( a , b )n+1(0,1)1(a,)

ฮิสโตแกรมของอัลกอริทึมทั้งสามจะปรากฏขึ้น (แต่ละชุดแสดงให้เห็นถึงผลลัพธ์สะสมของชุดอิสระชุดค่าแต่ละชุด) การขาดการเปลี่ยนแปลงใด ๆ ที่มองเห็นได้ในฮิสโตแกรมสำหรับอัลกอริทึม 1 แสดงปัญหาที่นั่น การเปลี่ยนแปลงในอีกสองอัลกอริทึมเป็นสิ่งที่คาดหวัง - และสิ่งที่คุณต้องการจากตัวสร้างตัวเลขแบบสุ่มn = 1001000n=100

สำหรับข้อมูลเพิ่มเติมจำนวนมาก (หัวเราะ) วิธีการที่จะจำลองเครื่องแบบอิสระ variates ดูการจำลองการดึงออกมาจากเครื่องแบบกระจายใช้ดึงออกมาจากการกระจายปกติ

ภาพ: ฮิสโทแกรม

นี่คือRรหัสที่สร้างตัวเลข

b <- 1
a <- 0
n <- 100
n.iter <- 1e3

offset <- (b-a)/n
as <- seq(a, by=offset, length.out=n)
sim.1 <- matrix(runif(n.iter*n, as, as+offset), nrow=n)
sim.2 <- apply(matrix(runif(n.iter*n, a, b), nrow=n), 2, sort)
sim.3 <- apply(matrix(rexp(n.iter*(n+1)), nrow=n+1), 2, function(x) {
  a + (b-a) * cumsum(x)[-(n+1)] / sum(x)
})

par(mfrow=c(1,3))
hist(sim.1, main="Algorithm 1")
hist(sim.2, main="Algorithm 2")
hist(sim.3, main="Exponential")

คุณคิดอย่างไรกับอัลกอริทึม (ตามสถิติลำดับการจัดอันดับ) ในคำตอบของฉัน ;-)
มี QUIT - Anony-Mousse

@Anony เป็นรุ่นที่มีประสิทธิภาพน้อยกว่าของอัลกอริทึมของฉัน 3 (ดูเหมือนว่าคุณจะเกี่ยวข้องกับการ rescaling ที่ไม่จำเป็นจำนวนมาก) คุณสร้างความแปรปรวนแบบเอ็กซ์โพเนนเชียลโดยการบันทึกชุดเครื่องแบบซึ่งเป็นมาตรฐาน
whuber

6

อัลกอริทึมแรกสร้างตัวเลขที่เว้นระยะเท่ากันเกินไป

ดูเพิ่มเติมชุดความคลาดเคลื่อนต่ำ

สมมติว่าคุณต้องการที่ 2 ตัวเลขสุ่มใน1] ด้วยข้อมูลที่เหมือนกันจริงโอกาสคือ 50:50 พวกเขาทั้งใหญ่กว่าหรือเล็กกว่า 0.5 ในเวลาเดียวกัน โอกาสของคุณคือ 0 ดังนั้นข้อมูลของคุณไม่เหมือนกัน[0;1]

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

วิธีการที่เหมาะสม แต่มีราคาแพง (สำหรับค่าจริง)

... คือการใช้ตัวเลขสุ่มกระจายเบต้า สถิติอันดับของการแจกแจงแบบกระจายนั้นเป็นแบบเบต้า คุณสามารถใช้วิธีนี้ในการวาดภาพที่เล็กที่สุดจากนั้นทำซ้ำที่เล็กที่สุดที่สอง ... ซ้ำ

สมมติว่าข้อมูลจะถูกสร้างขึ้นใน1] ค่าที่เล็กที่สุดคือกระจาย (สำหรับกรณีที่ตามมาลดและ rescale เป็นช่วงเวลาที่เหลือ) ในการสร้างการสุ่มเบต้าแบบทั่วไปเราจะต้องสร้างค่าสุ่มแกมมากระจายสองค่า แต่1] จากนั้น[N] เราสามารถสุ่มตัวเลขสุ่มจากการแจกแจงนี้เป็นสำหรับสิ่งนี้[0;1]เบต้า[1,n]n1-X~เบต้า[n,1]-LN(1-X)~ที่ชี้แจง[n]-LN(ยู[0;1])n

-LN(1-x)=-LN(1-ยู)n1-x=ยู1nx=1-ยู1n

ซึ่งให้อัลกอริทึมดังต่อไปนี้:

x = a
for i in range(n, 0, -1):
    x += (b-x) * (1 - pow(rand(), 1. / i))
    result.append(x) 

อาจมีความไม่แน่นอนเชิงตัวเลขที่เกี่ยวข้องและการคำนวณpowและการหารสำหรับวัตถุทุกอย่างอาจช้ากว่าการเรียงลำดับ

สำหรับค่าจำนวนเต็มคุณอาจต้องใช้การแจกแจงแบบอื่น

การเรียงลำดับมีราคาถูกอย่างไม่น่าเชื่อดังนั้นเพียงแค่ใช้มัน

แต่ไม่ต้องกังวล การเรียงลำดับนั้นราคาถูกมาก ในช่วงหลายปีที่ผ่านมาเราเข้าใจดีว่าจะใช้อัลกอริธึมการเรียงลำดับที่การเรียงลำดับคู่ไม่คุ้มที่จะหลีกเลี่ยง ในทางทฤษฎีมันเป็นแต่เทอมคงที่มีขนาดเล็กอย่างน่าขันในการใช้งานที่ดีว่านี่เป็นตัวอย่างที่สมบูรณ์แบบว่าผลลัพธ์เชิงความซับซ้อนเชิงทฤษฎีไร้ประโยชน์สามารถเป็นอย่างไร เรียกใช้เกณฑ์มาตรฐาน สร้าง 1 ล้าน randoms ทั้งที่มีและไม่มีการเรียงลำดับ เรียกใช้สองสามครั้งและฉันจะไม่แปลกใจหากการเรียงลำดับมักจะเต้นแบบไม่เรียงเนื่องจากค่าใช้จ่ายในการคัดแยกจะยังคงน้อยกว่าข้อผิดพลาดการวัดของคุณมากO(nเข้าสู่ระบบn)


1
อาจมีเหตุผลที่จะหลีกเลี่ยงการเรียงลำดับ หนึ่งคือเมื่อคุณต้องการสร้างตัวแปรสุ่มจำนวนมากดังนั้นจำนวนมากที่รูทีนการเรียงลำดับมาตรฐานไม่สามารถจัดการกับมันได้
whuber

ฉันคิดว่าปัญหาเชิงตัวเลขเกี่ยวกับผลบวกด้วยการใช้เลขทศนิยมเป็นปัญหาก่อนหน้านี้มาก (และปัญหาเกี่ยวกับรูปแบบวงจรในจำนวนสุ่มหลอก!) มันค่อนข้างง่ายที่จะปรับขนาดวิธีการเรียงลำดับเป็นเทราไบต์และต่อไบต์ในระบบกระจาย
มี QUIT - Anony-Mousse

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

ตกลงไม่ต้องเก็บพวกเขาเป็นอาร์กิวเมนต์ แต่แล้วคุณจะต้องเข้าใกล้ฉันตัวแปร 3 ของคุณที่ใช้ผลรวมสะสมจะไม่ทำงาน
มี QUIT - Anony-Mousse

นั่นคือจุดที่ยอดเยี่ยม ตอนนี้ฉันเห็นคุณค่าของการคำนวณพิเศษ! (+1)
whuber

5

นอกจากนี้ยังขึ้นอยู่กับสิ่งที่คุณกำลังทำกับตัวเลขสุ่ม สำหรับวิธีการรวมปัญหาเชิงตัวเลขวิธีที่หนึ่ง (เมื่อแก้ไขโดยการลบผู้ปฏิบัติงานพื้น) จะทำให้เกิดชุดจุดที่เหนือกว่า สิ่งที่คุณกำลังทำคือรูปแบบของการสุ่มตัวอย่างแบบแบ่งชั้นและมีข้อได้เปรียบที่หลีกเลี่ยงการจับกันเป็นก้อน ไม่สามารถรับค่าทั้งหมดของคุณในช่วง 0- (ba) / n ที่กล่าวว่าสำหรับแอปพลิเคชันอื่น ๆ สิ่งนี้อาจแย่มากขึ้นอยู่กับสิ่งที่คุณต้องการจะทำ


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