ด้านล่างเป็น colab โจทย์ปัญหา optimization ที่รวบรวม/จัดทำโดย อาจารย์อุดมศักดิ์ รักวงษ์วาน และคุณกฤติพัฒน์ กฤตาคม) อยากให้ทุกคนเซฟโพสต์นี้เก็บไว้ก่อน แล้วเก็บไว้ฝึกทำในเวลาว่าง ๆ นะ
จากโพสต์ที่แล้วเราก็คงได้เล่นกับ CVXPY สำหรับทำ Optimization ไปบ้างแล้ว (ถ้ายังไม่ได้เล่น ให้อ่านโพสต์ และลองเล่นกับ colab ที่แนบไว้ในโพสต์ที่แล้วด้วยตนเองก่อนนะ) ตั้งแต่ย่อหน้าถัดไปจะเป็นคำอธิบายเฉลยของทั้ง 3 ข้อ ขอให้ลองทำด้วยตนเองดูก่อนนะครับ
ข้อ 1.)
key idea ของข้อนี้คือการโยกเงินไปมาระหว่างสินทรัพย์ชนิดต่าง ๆ ได้ ดังนั้นเราเลยกำหนดตัวแปรใหม่ให้กับสินทรัพย์แต่ละตัวในแต่ละปีไปเลย (โดย annuity โจทย์กำหนดให้ปีแรกลงเงินไปเท่าไหร่ ก็ต้องลงต่อเนื่องเท่านั้นไป 3 ปี และ corporate bond ลงได้แค่ในปีที่ 2 ช่องอื่น ๆ เลยกรอก 0 ลงไป)
โดยข้อนี้เราพยายาม max return เราก็เริ่มค่อย ๆ ลองเขียนข้อจำกัดของตั้งแต่ปีที่ 1 ดู จะเห็นว่าปีแรก ตังค์ทั้งหมดของเรายังลงได้กับแค่ annuity และ bank account เพราะงั้นเลยเขียนได้เป็น x_1+x_2 = 100000
มาปีที่ 2 จะเริ่มซับซ้อนขึ้นนิดหน่อย แต่ไอเดียจริง ๆ ก็เรียบง่ายเหมือนเดิม จะลงตังค์อะไรเพิ่มก็บวก จะเอาตังค์ออกไปทำอย่างอื่นก็ลบ ก็เป็น x_1 + x_5 - 1.06*x_2 + x_3 = 0 ซึ่งไอเดียก็เหมือนของปีที่ 3 เลย ที่เขียนได้เป็น x_1 - 1.06 * x_3 + x_4 = 0
นอกจากนั้นก็กำหนดขั้นต่ำของแต่ละตัว คือ bank account โจทย์ให้เอาเงินออกได้เต็มที่ 20000 ดังนั้นทั้ง 3 ปี y_1, y_2, y_3 จึงต้องมีค่ามากกว่าหรือเท่ากับ -20000 ส่วนสินทรัพย์ชนิดอื่น ๆ ที่เอาเงินออกไม่ได้ ก็ต้องมากกว่าหรือเท่ากับ 0 ตลอด
สุดท้ายก็เขียน objective function ว่าสุดท้ายแล้วได้เงินมาเท่าไหร่ ก็จะเขียนได้เป็น 1.303x_1+1.06x_4+1.30x_5 (โดย 1.06, 1.30 มาจากการบวก rates of return ที่มีค่า 6%, 30% เพิ่มเข้าไป)
สิ่งที่ข้อนี้บอกเราคือการเล่นกับช่วงเวลา 3 ปี ว่าถ้า optimize ครั้งเดียวไปเลยตั้งแต่ตอนเริ่มต้น เราจะได้ผลตอบแทนกลับมาเยอะกว่า optimize ปีละครั้งไป 3 ครั้ง (เพราะคำนึงถึงการโยกเงินไปใช้ในปีถัดไป) และเราสามารถทำแบบนั้นได้ด้วยการกำหนดตัวแปรของสินทรัพย์ในแต่ละปีขึ้นมา
ข้อ 2.)
จะเห็นว่าข้อนี้อาจารย์ให้ทั้ง objective function และข้อจำกัดมาหมดแล้ว
แต่ไอเดียที่อยากเตือนในข้อนี้ คือ CVXPY จะแก้สมการไม่ออก ถ้าเจอตัวแปรหลายตัวเอามาคูณกัน (สำหรับข้อนี้ก็จะหมายถึง 2x_1x_2 ใน objective function)
ดังนั้นเราต้องช่วยจัด form (เปลี่ยน 2x1x2เป็นรูปอื่นโดยที่ค่ายังคงเดิม) โดยจัดเข้ากำลัง 2 สมบูรณ์ แล้วบวกเข้าลบออกให้ค่าเท่าเดิม ก็จะได้ objective function เป็น 4x_1**2 + 4x_2**2+(x_1-x_2)**2+6x_1+4x_2 ซึ่งก็สามารถกรอกให้ CVXPY แก้ได้แล้ว
โดยถ้าลืมเรื่องนี้ไปแล้ว สามารถศึกษาได้จากวิดิโอของ Khan Academy คลิปนี้เลย https://www.youtube.com/watch?v=bNQY0z76M5A
ข้อ 3.)
ข้อนี้ต้องการให้ลองนั่งหา function ของ CVXPY สำหรับมาเขียน objective function หน้าตาแปลก ๆ โดยสามารถดู function ได้จาก
คืออย่างในข้อนี้เศษส่วนที่ซ้อน ๆ กันอยู่นั้นถ้าลองเลื่อน ๆ หาดูใน ก็จะเจอว่าเวลาเขียน syntax เค้าให้เขียนเป็น harmonic_mean(x)
อีกเรื่องที่สำคัญมากคือเวลานับ index ในภาษา python เราจะเริ่มกันที่ 0 ไม่ได้เริ่มที่ 1 เหมือนทาง math ดังนั้นสมการข้อจำกัดที่ 2 ที่เขียนเป็น x_2-3/4x_3 = 0 ในทาง math พอมาเขียนบน python เลยกลายเป็น x[1]-3/4x[2] == 0
Comments