ผลต่างระหว่างรุ่นของ "418531 ภาคต้น 2552/โจทยปัญหาอัลกอริทึมแบบแบ่งแยกแล้วเอาชนะ/เฉลยข้อ 4"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
 
(ไม่แสดง 11 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน)
แถว 1: แถว 1:
 
ในปัญหาข้อนี้เราจะใช้ binary search เหมือนกับปัญหาข้อที่ผ่านๆ มา แต่วัตถุที่เราทำการค้นหาจะแตกต่างจากข้ออื่นมาก
 
ในปัญหาข้อนี้เราจะใช้ binary search เหมือนกับปัญหาข้อที่ผ่านๆ มา แต่วัตถุที่เราทำการค้นหาจะแตกต่างจากข้ออื่นมาก
  
เพื่อความสะดวก เราจะกำหนดให้อะเรย์ <math>A \,</math> และ <math>B \,</math> มีช่อง <math>A[0] \,</math> และ <math>B[0] \,</math> โดยที่ <math>A[0] = -\infty \,</math> และ <math>B[0] = -\infty \,</math> กล่าวคือ <math>A[0] \,</math> และ <math>B[0] \,</math> จะมีค่าน้อยกว่าอะเรย์ช่องอื่นๆ ทั้งหมด
+
เพื่อความสะดวก เราจะกำหนดให้อะเรย์ <math>A \,</math> และ <math>B \,</math> มีช่อง <math>A[0] \,</math> และ <math>B[0] \,</math> โดยที่ <math>A[0] = -\infty \,</math> และ <math>B[0] = -\infty \,</math> กล่าวคือ <math>A[0] \,</math> และ <math>B[0] \,</math> จะมีค่าน้อยกว่าอะเรย์ช่องอื่นๆ ทั้งหมด แต่เราจะไม่นับว่าช่องที่เพิ่มมาใหม่นี้เป็นส่วนหนึ่งของอะเรย์
  
เราจะพิสูจน์ข้อความสองข้อความต่อไปนี้
+
เราจะพิสูจน์ข้อความสามข้อความต่อไปนี้
  
  
แถว 15: แถว 15:
  
 
'''พิสูจน์:''' ให้ <math>x \,</math> เป็นจำนวนที่น้อยกว่าระหว่าง <math>A[i+1] \,</math> และ <math>B[j+1] \,</math> แล้วจะได้ว่ามีจำนวน <math>i \,</math> ตัวใน <math>A \,</math> ที่น้อยกว่า <math>x \,</math> และจำนวน <math>j \,</math> ตัวใน <math>B \,</math> ที่น้อยกว่ามัน ฉะนั้นมีจำนวน <math>i + j = k-1 \,</math> ตัวใน <math>A \,</math> และ <math>B \,</math> ที่น้อยกว่ามันพอดี ดังนั้น <math>x \,</math> เป็นสมาชิกตัวที่น้อยที่สุดเป็นอันดับที่ <math>k \,</math> พอดี
 
'''พิสูจน์:''' ให้ <math>x \,</math> เป็นจำนวนที่น้อยกว่าระหว่าง <math>A[i+1] \,</math> และ <math>B[j+1] \,</math> แล้วจะได้ว่ามีจำนวน <math>i \,</math> ตัวใน <math>A \,</math> ที่น้อยกว่า <math>x \,</math> และจำนวน <math>j \,</math> ตัวใน <math>B \,</math> ที่น้อยกว่ามัน ฉะนั้นมีจำนวน <math>i + j = k-1 \,</math> ตัวใน <math>A \,</math> และ <math>B \,</math> ที่น้อยกว่ามันพอดี ดังนั้น <math>x \,</math> เป็นสมาชิกตัวที่น้อยที่สุดเป็นอันดับที่ <math>k \,</math> พอดี
 +
 +
 +
'''lemma 2:''' ถ้า <math>A[i+1] \,</math> คือจำนวนที่มีค่าน้อยที่สุดเป็นอันดับที่ <math>k \,</math> ใน <math>A \,</math> และ <math>B \,</math> โดยที่ <math>0 \leq i \leq m \,</math> แล้ว หากให้ <math>j = k-1-i \,</math> แล้ว เราจะได้ว่า <math>A[i+1] > B[j] \,</math> และ <math>B[j+1] > A[i] \,</math>
 +
 +
'''พิสูจน์:''' เนื่องจาก <math>A[i+1] \,</math> เป็นสมาชิกตัวที่น้อยที่สุดเป็นอันดับที่ <math>k \,</math> ดังนั้นจะต้องมีสมาชิกใน <math>A \,</math> และ <math>B \,</math> ที่น้อยกว่ามัน <math>k-1 \,</math> ตัวพอดี และเนื่องจากมีสมาชิกที่น้อยกว่า <math>A[i+1] \,</math> อยู่ <math>i \,</math> ตัวในอะเรย์ <math>A \,</math> จะต้องมีสมาชิกที่้น้อยกว่า <math>A[i+1] \,</math> อยู่ <math>k-1-i = j\,</math> ตัวใน <math>B \,</math> ซึ่งนี่หมายความว่า <math>A[i+1] > B[j] \,</math>
 +
 +
อนึ่ง เราจะได้ว่า <math>B[j+1] > A[i+1] > A[i] \,</math> ด้วย ฉะนั้น lemma เป็นจริง
 +
 +
 +
'''lemma 3:''' ถ้า <math>B[j+1] \,</math> คือจำนวนที่มีค่าน้อยที่สุดเป็นอันดับที่ <math>k \,</math> ใน <math>A \,</math> และ <math>B \,</math> โดยที่ <math>0 \leq j \leq n \,</math> แล้ว หากให้ <math>i = k-1-j \,</math> แล้ว เราจะได้ว่า <math>A[i+1] > B[j] \,</math> และ <math>B[j+1] > A[i] \,</math>
 +
 +
'''พิสูจน์:''' ใช้วิธีพิสูจน์เดียวกันกับ lemma 2
 +
 +
 +
สังเกตว่า lemma 2 และ lemma 3 เป็น converse ของ lemma 1 ฉะนั้นเราสามารถสรุปได้ว่า
 +
 +
'''Proposition 4:''' เราสามารถหาสมาชิกตัวที่มีค่าน้อยที่สุดเป็นอันดับ <math>k \,</math> ในอะเรย์ <math>A \,</math> และ <math>B \,</math> ได้โดยการหาจำนวนเต็ม <math>i \,</math> และ <math>j \,</math> ที่ทำให้ (1) <math>i+j = k-1 \,</math> และ (2) <math>A[i+1] > B[j] \,</math> และ (3) <math>B[j+1] > A[i] \,</math> แล้วจึีงหาคำตอบด้วยการหาค่าที่น้อยกว่าระหว่าง <math>A[i+1] \,</math> และ <math>B[j+1] \,</math>
 +
 +
(ข้อสังเกต: lemma 2 และ lemma 3 เป็นข้อความที่มีความสำคัญมากเนื่องจากมันรับประกันว่าจะีมี <math>i \,</math> และ <math>j \,</math> เีพียงคู่เดียวเท่านั้นที่จะสอดคล้องกับเงื่อนไขทั้งหมดใน lemma 1)
 +
 +
== อัลกอริทึม ==
 +
อาศัย Proposition 4 เราจะแก้ปัญหานี้ด้วยการทำ binary search บนวัตถุคู่ำลำดับ <math>(i,j) \,</math> โดยที่ <math>i+j = k-1 \,</math> โดยเราจะได้ว่าคู่ำลำดับนี้จะมีอยู่อย่างมาก <math>k \,</math> ตัวด้วยกัน ได้แต่ <math>(0,k-1), (1,k-2), (2,k-3), \ldots, (k-2,1), (k-1,0) \,</math>
 +
 +
สำหรับวัตถุแต่ละอัน เราจะทำการเปรียบเทียบสองครั้ง ได้แก่ (1) เปรียบเทียบ <math>A[i+1] \,</math> กับ <math>B[j] \,</math> และ (2) เปรียบเทียบ <math>B[j+1] \,</math> กับ <math>A[i] \,</math> โดยการเปรียบเทียบนี้เกิดผลได้ 3 แบบด้วยกัน
 +
* <math>A[i+1] > B[j] \,</math> และ <math>B[j+1] > A[i] \,</math>: ในกรณีเราจะได้ว่าเราหา <math>(i,j) \,</math> ที่ต้องการเจอแล้ว เราสามารถหยุดการทำงานของ binary search ได้
 +
 +
* <math>A[i+1] > B[j] \,</math> และ <math>B[j+1] < A[i] \,</math>: ในกรณีเราพบว่าสำหรับคู่ลำดับ <math>(i', j') \,</math> อื่นๆ ที่ <math>i' > i \,</math> เราจะได้ว่า <math>A[i'+1] > A[i+1] > B[j] > B[j'] \,</math> และ <math>B[j'+1] \leq B[j] < A[i] < A[i'] \,</math> ด้วยเหตุนี้ <math>(i',j') \,</math> จึีงไม่สามารถนำไปสู่จำนวนที่มีค่าน้อยที่สุดเป็นอันดับที่ <math>k \,</math> ได้ ฉะนั้นในกรณีนี้เราสามารถตัดวัตถุ <math>(i',j') \,</math> โดยที่ <math>i' > i \,</math> ออกจากวัตถุที่เป็นไปได้ทั้งหมด
 +
 +
* <math>A[i+1] < B[j] \,</math> และ <math>B[j+1] > A[i] \,</math>: ในกรณีเราพบว่าสำหรับคู่ลำดับ <math>(i', j') \,</math> อื่นๆ ที่ <math>i' < i \,</math> เราจะได้ว่า <math>A[i'+1] < A[i+1] < B[j] < B[j'] \,</math> และ <math>B[j'+1] > B[j+1] > A[i] > A[i'] \,</math> ด้วยเหตุนี้ <math>(i',j') \,</math> จึีงไม่สามารถนำไปสู่จำนวนที่มีค่าน้อยที่สุดเป็นอันดับที่ <math>k \,</math> ได้ ฉะนั้นในกรณีนี้เราสามารถตัดวัตถุ <math>(i',j') \,</math> โดยที่ <math>i' < i \,</math> ออกจากวัตถุที่เป็นไปได้ทั้งหมด
 +
 +
จากแนวคิดข้างต้น เราสามารถเขียน pseudocode ของอัลกอริืทึมได้ดังต่อไปนี้
 +
 +
<geshi lang="c">
 +
Search(A, B, k)
 +
{
 +
    i_left = 0
 +
    i_right = k-1
 +
 +
    while i_left <= i_right do
 +
    {
 +
      i = (i_left + i_right) / 2
 +
      j = k - 1 - i
 +
 +
      if A[i+1] > B[j] and B[j+1] > A[i] then
 +
            return min(A[i+1], B[j+1])
 +
      else if A[i+1] > B[j] and B[j+1] < A[i] then
 +
            i_right = i-1
 +
      else if A[i+1] < B[j] and B[j+1] > A[i] then
 +
            i_left = i+1
 +
    }
 +
}
 +
</geshi>
 +
 +
เนื่องจากในการเช็คเงื่อนไขแต่ละครั้งเราสามารถตัดวัตถุที่เป็นไปได้ออกประมาณครึ่งหนึ่ง เราจะได้ว่าจะมีการวนลูปใน pseudocode อย่างมาก <math>O(\log k) = O(\log(m+n)) = O(\log m + \log n) \,</math> ครั้ง ฉะนั้นอัลกอริทึมข้างบนจึงทำงานภายในเวลา <math>O(\log n + \log m)\,</math> ตามต้องการ

รุ่นแก้ไขปัจจุบันเมื่อ 14:28, 2 กันยายน 2552

ในปัญหาข้อนี้เราจะใช้ binary search เหมือนกับปัญหาข้อที่ผ่านๆ มา แต่วัตถุที่เราทำการค้นหาจะแตกต่างจากข้ออื่นมาก

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

เราจะพิสูจน์ข้อความสามข้อความต่อไปนี้


lemma 1: ถ้า และ เป็นจำนวนเต็มที่

  • และ
  • และ
  • และ
  • และ

แล้วสมาชิกตัวที่น้อยที่สุดเป็นอันดับที่ ในอะเรย์ และ คือ

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


lemma 2: ถ้า คือจำนวนที่มีค่าน้อยที่สุดเป็นอันดับที่ ใน และ โดยที่ แล้ว หากให้ แล้ว เราจะได้ว่า และ

พิสูจน์: เนื่องจาก เป็นสมาชิกตัวที่น้อยที่สุดเป็นอันดับที่ ดังนั้นจะต้องมีสมาชิกใน และ ที่น้อยกว่ามัน ตัวพอดี และเนื่องจากมีสมาชิกที่น้อยกว่า อยู่ ตัวในอะเรย์ จะต้องมีสมาชิกที่้น้อยกว่า อยู่ ตัวใน ซึ่งนี่หมายความว่า

อนึ่ง เราจะได้ว่า ด้วย ฉะนั้น lemma เป็นจริง


lemma 3: ถ้า คือจำนวนที่มีค่าน้อยที่สุดเป็นอันดับที่ ใน และ โดยที่ แล้ว หากให้ แล้ว เราจะได้ว่า และ

พิสูจน์: ใช้วิธีพิสูจน์เดียวกันกับ lemma 2


สังเกตว่า lemma 2 และ lemma 3 เป็น converse ของ lemma 1 ฉะนั้นเราสามารถสรุปได้ว่า

Proposition 4: เราสามารถหาสมาชิกตัวที่มีค่าน้อยที่สุดเป็นอันดับ ในอะเรย์ และ ได้โดยการหาจำนวนเต็ม และ ที่ทำให้ (1) และ (2) และ (3) แล้วจึีงหาคำตอบด้วยการหาค่าที่น้อยกว่าระหว่าง และ

(ข้อสังเกต: lemma 2 และ lemma 3 เป็นข้อความที่มีความสำคัญมากเนื่องจากมันรับประกันว่าจะีมี และ เีพียงคู่เดียวเท่านั้นที่จะสอดคล้องกับเงื่อนไขทั้งหมดใน lemma 1)

อัลกอริทึม

อาศัย Proposition 4 เราจะแก้ปัญหานี้ด้วยการทำ binary search บนวัตถุคู่ำลำดับ โดยที่ โดยเราจะได้ว่าคู่ำลำดับนี้จะมีอยู่อย่างมาก ตัวด้วยกัน ได้แต่

สำหรับวัตถุแต่ละอัน เราจะทำการเปรียบเทียบสองครั้ง ได้แก่ (1) เปรียบเทียบ กับ และ (2) เปรียบเทียบ กับ โดยการเปรียบเทียบนี้เกิดผลได้ 3 แบบด้วยกัน

  • และ : ในกรณีเราจะได้ว่าเราหา ที่ต้องการเจอแล้ว เราสามารถหยุดการทำงานของ binary search ได้
  • และ : ในกรณีเราพบว่าสำหรับคู่ลำดับ อื่นๆ ที่ เราจะได้ว่า และ ด้วยเหตุนี้ จึีงไม่สามารถนำไปสู่จำนวนที่มีค่าน้อยที่สุดเป็นอันดับที่ ได้ ฉะนั้นในกรณีนี้เราสามารถตัดวัตถุ โดยที่ ออกจากวัตถุที่เป็นไปได้ทั้งหมด
  • และ : ในกรณีเราพบว่าสำหรับคู่ลำดับ อื่นๆ ที่ เราจะได้ว่า และ ด้วยเหตุนี้ จึีงไม่สามารถนำไปสู่จำนวนที่มีค่าน้อยที่สุดเป็นอันดับที่ ได้ ฉะนั้นในกรณีนี้เราสามารถตัดวัตถุ โดยที่ ออกจากวัตถุที่เป็นไปได้ทั้งหมด

จากแนวคิดข้างต้น เราสามารถเขียน pseudocode ของอัลกอริืทึมได้ดังต่อไปนี้

<geshi lang="c"> Search(A, B, k) {

   i_left = 0
   i_right = k-1
   while i_left <= i_right do
   {
      i = (i_left + i_right) / 2
      j = k - 1 - i
      if A[i+1] > B[j] and B[j+1] > A[i] then
           return min(A[i+1], B[j+1])
      else if A[i+1] > B[j] and B[j+1] < A[i] then
           i_right = i-1
      else if A[i+1] < B[j] and B[j+1] > A[i] then
           i_left = i+1
   }

} </geshi>

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