Blog of การุณ สิริธีรธำรง

บันทึกของน้องเนย

คือจริงๆ ก็ได้มาจากรุ่นน้องอีกทีอ่าแหละ

เห็นว่ามันดีมากๆ เลย

MV เพลงก็เพราะ แถม จุดประสงค์ยังดีอีกด้วย

เลยอยากให้ช่วยกันเข้าชม หน่อยอ่า เพื่อช่วยกันสร้างลานเล่นให้น้องๆ ชายแดนใต้
หน่อยนะครับ ^^

ขอบคุณจ้าาา

embedded by Embedded Video

Grader 2.1.3 ออกแล้วจ้า

Jan-12-2010 By น้องเนย

ไม่มีอะไรมากจะบอกว่า โปรแกรม CRU Online Judge เวอร์ชั่น 2.1.3 ออกแล้วอ่ะนะ

เวอร์ชั่นนี้ก็ได้ทำการเพิ่มระบบ ถาม-ตอบ เข้าไปด้วย

ทำให้นักเรียน และอาจาร์ สามารถถาม-ตอบคำถามกันได้

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

เข้าไปโหลดโปรแกรม CRU Online Judge 2.1.3 ได้  ที่นี่

*บทความนี้สามารถใช้ได้กับทั้งผู้ที่เรียน แคลคูลัส 1 และ แคลคูลัส 2 ครับ

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

   “ผมนึกภาพพื้นผิวในปริภูมิ 3 มิติไม่ออก และ จำรูปสมการมาตรฐานของแต่ละพื้นผิวไม่ได้”

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

 

เอาล่ะ แล้ววิชาแคลคูลัส 2 ที่ผมเรียนนี้มันเกี่ยวกับเรื่องอะไรล่ะ (เอาถึงแค่ที่สอบนะครับ) ?
จริงๆ ที่ผมเรียนแบ่งการเรียนเป็นสองส่วนครับ

คือส่วนเรื่องพื้นผิวในปริภูมิสามมิติ (ที่มีแกน X,Y,Z นั่นแหละ)  กับส่วนหลัง(ที่สอบถึง)
ก็คือเรื่องการหาอนุพันธ์ย่อย (Partial Derivative)

 

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

ตัวช่วยที่ว่านี้มีชื่อว่าโปรแกรม   Surface 3D Explorer เรามาดูหน้าตาของโปรแกรมขณะใช้งานกันหน่อยนะครับ

Surface 3D Explorer (เข้าสู่เว็บไซต์ของโปรแกรม)

shot

 

     จากที่เห็นด้านบน  นี่คือหน้าตาขณะทำงานของโปรแกรมนี้ครับ  ที่ผมจับภาพมานี่คือโปรแกรม
เพิ่งพล็อตรูปพาราโบลอยด์เชิงไฮเพอร์โบลิก (Hyperbolic Paraboloid) เสร็จครับซึ่งรูปนี้
ในการวาดเองนั้นถือว่ามีความยากลำบากในการวาดสูงทีเดียวครับ  นอกจากจะวาดยากแล้ว
ผมยังวาดออกมาได้เน่ามากด้วยครับ (ถ้าลองวาดเองแล้วจะรู้)

 

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

Parametric  หรือแบบ   x,y,z(u,v)   พวกฟังก์ชั่นแอบๆ ซ่อนๆ ทั้งหลาย
Explicit       หรือแบบ   z = f(x,y)   หรือฟังชั่นตัวแปรของ x และ y เท่านั้น
Implicit       หรือแบบ   f(x,y,z) = 0  คือฟังก์ชั่นที่มีทั้งตัวแปร x,y และ z อยู่ด้วยกัน (เช่นสมการของวงกลม)

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

ซึ่งวิธีการวาดรูปพื้นผิวในโหมดนี้ผมจะยกตัวอย่างการวาด ทรงรี (Ellipsoid) แล้วกันนะครับ

วิธีใช้โปรแกรมเพื่อวาดรูปทรงรี

  1. เปิดโปรแกรมขึ้นมา
  2. ที่เมนูบาร์เลือก File > New > f(x,y,z) Implicit
  3. ที่กล่อง F(x,y,z) ให้พิมพ์สมการของเราลงไป โดยทำให้ข้างใดข้างหนึ่งของสมการมีค่าเป็น 0
    อาจจะโดยการย้ายข้าง หรือ คูณ/หาร ก็แล้วแต่
  4. จากนั้นกดไอค่อนรูปดินสอ (ดังรูป) เพื่อวาดรูปพื้นผิวออกมา
    plot

เช่นผมต้องการวาดพื้นผิวของรูปทรงรี ที่มีสมการ \frac{x^2}{72}+\frac{y^2}{4}+\frac{z^2}{18}=2

ผมก็จะกรอกสมการด้านบนนี้ในกล่อง F(x,y,z) แล้วกดไอค่อนดินสอ
แล้วก็จะได้รูปที่มีหน้าตาแบบด้านล่างนี้ (ผมได้เปลี่ยนสีพื้นหลังแล้วจะได้เห็นชัดๆ

ellipsoid

หรืออีกรูปพื้นผิวที่วาดแบบ Implicit (ทั้งๆ ที่จะวาดแบบ Explicit ก็ได้ซึ่งนั่นก็คือ Hyperbolic Paraboloid)

hyperbolic_paraboloid

 

เราสามารถเลือกให้โปรแกรมแสดงแกน x,y,z หรือไม่ก็ได้ภายในโปรแกรมครับ
และเราสามารถปรับ min,max ของ x,y,z ได้ด้วย เพื่อให้โปรแกรมแสดงขอบเขตที่เหมาะสม

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

โปรแกรม Surface 3D Explorer ถึงแม้ว่าจะวาดรูปพื้นผิวออกมาได้สวยงาม แต่ว่ามันไม่สามารถ
ทำการอินทิเกรต หรือ หาอนุพันธ์ได้ (Integrate and Differentiate)

แต่โปรแกรมฟรี ที่สามารถทำสิ่งเหล่านี้ได้ (และทำได้มากกว่านี้เสียอีก) คือโปรแกรมที่ชื่อว่า Maxima ครับ
แต่ตัวอย่างที่ผมจะเอามาให้ดูนั้นเป็นของโปรแกรม wxMaxima (ก็อันเดียวกันนั่นแหละ) ซึ่งเป็นหน้าตาโปรแกรม
ที่ใช้งานง่ายกว่าเยอะครับ :)

Maxima  (and also wxMaxima)  (เข้าสู่เว็บไซต์ของโปรแกรม)

*สำหรับโปรแกรมนี้ log(x) หมายถึง ln x ครับ (ทางภาษาโปรแกรมคอมพิวเตอร์)

หน้าตาของโปรแกรมนี้ จริงๆ แล้วไม่ค่อยมีอะไร (แทบไม่มีอะไรเลยมากกว่า)
เพราะฉะนั้นเรามาดูวิธีการที่ทำให้โปรแกรมหา ปริพันธ์ให้เราเลยดีกว่าครับ (ติดตั้งโปรแกรมให้เรียบร้อยก่อนนะ)

การหาปริพันธ์

  1. เปิดโปรแกรม wxMaxima
  2. ที่เมนูบาร์เลือก Calculus > Integrate…  ดังรูป
    integrate
  3. ที่กล่อง Expression ให้ใส่สมการที่ต้องการอินทิเกรตลงไป และในกล่อง Variable ให้ใส่ตัวแปร
    ที่จะทำการอินทิเกรตลงไป ส่วนจะเลือกจำกัดเขตหรือไม่นั้นก็แล้วแต่ครับ  สำหรับผมเลือกหาปริพันธ์
    ไม่จำกัดเขต ดังรูป
    box 

  4. สมการที่ใส่ลงในกล่องนั้นดูยาก  แต่แรกเริ่มเดิมทีเป็นสมการนี้ \int\frac{xsin\sqrt {x^2 + 5}}{\sqrt{x^2 + 5}}dx 
  5. เมื่อเรากด OK โปรแกรมจะอินทิเกรตและให้ผลลัพธ์กับเราแทบจะในทันทีเลยครับ ดังรูป
    solved1

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

ตัวอย่างอีกสมการครับ \int \frac{e^{arctan(2x)}}{1 + 4x^2}dx

คำตอบจะได้
solved2

โดยที่ atan() หมายถึง arctan() ครับ (atan เป็นสิ่งที่ภาษาโปรแกรมนี้เข้าใจครับ)
และ log(e) หมายถึง ln e ครับ

 

หากเราต้องการจะหาอนุพันธ์ ก็แค่เลือก Calculus > Differentiate.. แล้วก็ทำแบบเดิม ก็ได้แล้วครับ

ขอให้เรียนแคลคูลัสให้สนุกสนานนะครับ ;)

ในที่สุด… หลังจากที่หมักดองมาเป็นเวลาสามเดือนเศษๆ

โปรแกรม CRU Grader 2.1.0 ก็เสร็จเสียที

สิ่งที่เปลี่ยนแปลงไปในเวอร์ชั่นนี้ก็ได้แก่

1.) ตัวตรวจ หรือ Grader นั่นเอง โดยเพิ่มความปลอดภัยในการเชื่อมต่อกับฐานข้อมูล MySQL
2.) ระบบ Announcement หรือระบบประกาศ ไว้ประกาศเรื่องต่างๆ ให้ผู้ใช้ทราบ
3.) มีการใช้ CSS ในหลายๆ หน้า (จากเมื่อก่อนไม่มี)

ก็นั่นแหละ

        ที่เห็นเปลี่ยนแปลงอยู่สามข้อหลักๆ ซึ่งจริงๆ ถ้าหากคิดดูแล้วไม่น่าใช้เวลายาวนานมากถึง 3 เดือน
แต่ที่เป็นเช่นนั้นก็เพราะว่า เวลาว่างของผมนั้นมีน้อยมาก   ต้องเอาไปเล่นเกม   เล่น Hi5   อ่านการ์ตูน
ฟังเพลง  ฯลฯ  เหอะๆ  เลยทำให้เพิ่งอัพเดทตอนนี้ไงล่ะครับ  :)

        หากต้องการดาวน์โหลดโปรแกรม CRU Grader 2.1.0 – Onlinejudge System ก็สามารถดาวน์โหลด
ได้ ที่นี่

       สำหรับผมวันนี้คงพอแค่นี้ก่อนครับ เพราะเริ่มเบลอๆ แล้ว เพราะว่านี่ก็ดึกแล้ว (ตีสองครึ่งแล้วนะ)

5555+  ฝันดีครับ

         Memoization เป็นเทคนิคหนึ่งในการเขียนโปรแกรมที่จะทำให้โปรแกรมเร็วขึ้นโดยการหลีกเลี่ยงการทำงานที่ซ้ำๆ กันของการเรียกฟังก์ชั่นแต่ละครั้ง โดยการเก็บข้อมูลที่เคยถูกคำนวณหรือประมวลผลไว้ก่อนแล้ว
เพื่อที่โปรแกรมจะได้ไม่ต้องประมวลผลซ้ำในส่วนนั้นอีก  เทคนิคนี้ยังเป็นเทคนิคหนึ่งในการเขียนโปรแกรมแบบ Dynamic Programming ในรูปแบบ Top-Down Approach อีกด้วย ก็คือการมองปัญหาใหญ่ๆ ก่อน แล้วก็ค่อยแตกปัญหาออกเป็นส่วนเล็กๆ   แล้วจากนั้นก็แก้ปัญหาส่วนเล็กๆ เหล่านั้น แล้วจึงนำมาประกอบกันเป็นการแก้ปัญหาที่สมบูรณ์

         ในภาษาคอมพิวเตอร์หลายๆ ภาษาเช่นภาษา Lisp, Prolog และ Haskell นั้นโปรแกรมเมอร์ผู้เขียนโปรแกรม
ภาษาดังกล่าวสามารถใช้ประโยชน์จาก  memoization  ได้เลยเพราะว่าในภาษาเหล่านี้ได้มีระบบ memoization
อัตโนมัติให้อยู่แล้ว เพราะฉะนั้นโปรแกรมเมอร์จึงไม่ต้องเพียรเขียนโค้ดขึ้นมาเองให้เหนื่อย

 

จากที่ได้กล่าวมาข้างต้นที่ว่า memoization เป็นรูปแบบหนึ่งของ dynamic programming แต่การเขียนโปรแกรม
แบบ dynamic programming แบบใช้และไม่ใช้ memoization นั้นก็มีแง่คิดต่างกันไปเช่น

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

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

เอาล่ะ เราพูดถึง memoization คร่าวๆแล้ว ทีนี้ลองมาดูการโปรแกรมกันบ้างดีกว่าครับ

 

ขอยกตัวอย่างปัญหาของ Fibonacci แล้วกันนะครับ

ลำดับเลขฟิโบนักชีก็ชุดตัวเลขดังต่อไปนี้
0, 1, 1, 2, 3, 5, 8, 13, 21, …..

ซึ่งสามารถนิยามได้โดยความสัมพันธ์แบบเวียนบังเกิดดังนี้

Fn = Fn-1 + Fn-1 โดยที่ F0 = 0 และ F1 = 1

หากเราเรียกหา F5 เราจะได้คำตอบ 5
และหากเราเรียกหา  F7 เราจะได้คำตอบ 13 ครับ

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

int Fibonacci(int N) {
    if(N == 0)
        return 0;
    if(N == 1)
        return 1;
   
    return Fibonacci(N-1) + Fibonacci(N-2);
}

จากฟังก์ชั่นเวียนบังเกิดนี้ จำนวนครั้งในการเรียกและเวลาในการทำงานจะขึ้นอยู่กับ ค่า N ถ้าค่า N ยิ่งมาก โปรแกรมก็จะทำงานช้าไปด้วย เช่นโปรแกรมเรียกฟังก์ชั่น Fibonacci(5) จะอธิบายดังนี้

Fibonacci(5) = Fibonacci(4) + Fibonacci(3)
    Fibonacci(4) = Fibonacci(3) + Fibonacci(2)
        Fibonacci(3) = Fibonacci(2) + Fibonacci(1)
            Fibonacci(2) = Fibonacci(1) + Fibonacci(0)
            Fibonacci(2) = 1 + 0 = 1
        Fibonacci(3) = 1 + 1 = 2
    Fibonacci(4) = 2 + 1 = 3
Fibonacci(5) = 3 + 2 = 5

เพราะฉะนั้น Fibonacci(5) = 5 จะเห็นว่าการเรียกฟังก์ชั่นแต่ละครั้ง ฟังก์ชั่นจะเรียกตัวเองซ้ำแล้วซ้ำอีก เยอะมากและหลายครั้งมาก ถ้าไม่เชื่อลองเรียก Fibonacci(50) ดูสิครับ จะรู้ชัดเจนว่า โปรแกรมจะหายต๋อมไปเลย (ยังทำงานไม่เสร็จ)

 

เอาล่ะทีนี้เราจะมาลองใช้เทคนิค memoization กันนะครับ ก็เพียงแต่เก็บผลการคำนวณที่เคยคำนวณไว้แล้ว

ใส่อาเรย์หรือโครงสร้างข้อมูลอะไรก็ได้ตามสะดวกที่เรียกใช้ได้ทันที เช่นในตัวอย่าง

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
long Fibonacci_table[100] = {0}; //ทำให้สมาชิกทุกตัวเป็น 0
                                 //หมายถึงยังไม่เคยถูกคำนวนมาก่อน

/* ฟังก์ชั่น Fibonacci แบบใช้เทคนิค Memoization */
long Fibonacci(int N) {
    if(N == 0)
        return 0;
    if(N == 1)
        return 1;
   
    if(Fibonacci_table[N]!=0) // ตัวที่ N เคยถูกคำนวนมาแล้ว
        return Fibonacci_table[N];

    Fibonacci_table[N] = Fibonacci(N-1) + Fibonacci(N-2);
    return Fibonacci_table[N];
}

จากตัวอย่างข้างต้นฟังก์ชั่นนี้จะเรียกตัวเองซ้ำเฉพาะในกรณีลำดับที่เรียกใช้ ยังไม่เคยถูกคำนวณมาก่อน

ซึ่งจะลดจำนวนครั้งในการทำงานลงไปได้มากอย่างไม่น่าเชื่อครับ

แล้วการเรียก Fibonacci(50) ก็จะเร็วขึ้นอย่างทันตาเห็น !!

จริงๆ แล้วโปรแกรมนี้สามารถเขียนใหม่ได้อีกแบบโดยใช้ Dynamic Programming แต่จะยังไม่พูดถึงคราวนี้

แต่ว่าอาจจะมาเขียนต่อในคราวต่อๆ ไปนะครับผม ^^

หวังว่าความรู้เบื้องต้นเกี่ยวกับเรื่อง memoization นี้จะเป็นประโยชน์นะครับ


สวัสดีครับ :)