1 คะแนน โดย GN⁺ 2024-07-05 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Constraint Programming (CP) เป็นแนวทางเชิงประกาศสำหรับปัญหาการหาค่าเหมาะที่สุดแบบไม่ต่อเนื่อง โดยโมเดลปัญหาด้วยตัวแปร·โดเมน·ข้อจำกัด แทนการเขียนโค้ดตามลำดับขั้น แล้วให้ตัวแก้ปัญหาค้นหาคำตอบที่ตรงตามเงื่อนไข
  • แกนสำคัญของโมเดลคือ ตัวแปร ที่เป็นค่าที่ต้องหา, โดเมนซึ่งเป็นช่วงของค่าที่เป็นไปได้, และข้อจำกัดที่จำกัดความสัมพันธ์ระหว่างตัวแปร โดยหากต้องการก็สามารถใช้ฟังก์ชันวัตถุประสงค์เพื่อเลือกคำตอบที่ดีกว่าได้
  • ตัวอย่างการหารค่าใช้จ่ายค่าขนมของ Alice, Bob, Carol แสดงให้เห็นลำดับการปรับปรุงจากคำตอบที่ใช้ได้ไปสู่คำตอบที่สมดุลมากขึ้นผ่าน alldifferent, maximum, minimize
  • ตัวอย่างใช้งานจริงใช้ตัวแก้ปัญหาโอเพนซอร์ส CP-SAT ของ Google OR-Tools และ Python เพื่อจัดตารางเวรรายสัปดาห์ของพนักงาน 4 คน ตลอด 7 วัน, 3 กะ, 2 บทบาท
  • ในโมเดลเดียวกันสามารถค่อยๆ เพิ่มเงื่อนไข เช่น จำกัดเวลาทำงานสัปดาห์ละ 40 ชั่วโมง, ตารางเรียน, คู่คนที่ห้ามทำงานร่วมกัน, การกระจายเวรวันหยุดสุดสัปดาห์อย่างเท่าเทียม, คำขอลางาน และการลดความต่างของจำนวนกะให้น้อยที่สุด

แนวคิดพื้นฐานของ Constraint Programming

  • Constraint Programming (CP) เป็นกระบวนทัศน์เชิงประกาศสำหรับแก้ปัญหาการหาค่าเหมาะที่สุดแบบไม่ต่อเนื่อง
  • การเขียนโปรแกรมเชิงคำสั่งจะเขียนขั้นตอนเพื่อไปให้ถึงผลลัพธ์ตามลำดับ แต่แนวทางเชิงประกาศจะอธิบายเงื่อนไขของผลลัพธ์ที่ต้องการ แล้วให้ระบบรันไทม์เป็นผู้ค้นหาผลลัพธ์นั้น
  • ในตัวอย่างการดึงรายชื่อผู้ใหญ่ โค้ดเชิงคำสั่งจะวนลูปรายชื่อคนและตรวจสอบ Age >= 18 ขณะที่ SQL เชิงประกาศจะแสดงเงื่อนไขโดยตรงเช่น SELECT person_name FROM people WHERE age >= 18;
  • CP ก็อธิบายผลลัพธ์ที่ต้องการในรูปของ โมเดล โดยองค์ประกอบหลักคือ ตัวแปร·โดเมน·ข้อจำกัด
    • ตัวแปรแสดงว่าเราต้องการหาอะไร
    • โดเมนคือเซตของค่าที่ตัวแปรสามารถมีได้
    • ข้อจำกัดใช้จำกัดความสัมพันธ์ระหว่างตัวแปร

ตัวแปร, โดเมน, ข้อจำกัด, ฟังก์ชันวัตถุประสงค์

  • คำตอบคือการกำหนดค่าให้แต่ละตัวแปรอยู่ภายใน โดเมน ของตัวเองและสอดคล้องกับข้อจำกัดทั้งหมด
  • ตัวอย่างค่าขนมเป็นปัญหาที่ Alice, Bob, Carol มีเงินคนละไม่เกิน 20 ดอลลาร์ และต้องรวมเงินกันซื้อขนมราคา 50 ดอลลาร์
    • ตัวแปร a, b, c คือจำนวนเงินที่แต่ละคนจ่าย
    • โดเมนของทั้งสามตัวแปรคือ {0, ..., 20}
    • ใช้ a + b + c == 50 เพื่อให้ยอดรวมถูกต้อง
    • ใช้ a >= b เพื่อให้ Alice จ่ายไม่น้อยกว่า Bob
    • ใช้ c % 5 == 0 เพื่อจำกัดให้จำนวนเงินของ Carol เป็นพหุคูณของ 5
    • หากไม่ต้องการให้ทั้งสามคนจ่ายเท่ากัน สามารถกำหนด a != b, a != c, b != c ได้
  • เงื่อนไขที่ครอบคลุมหลายตัวแปรสามารถแสดงด้วย global constraints โดย alldifferent(a, b, c) จะบังคับให้ทั้งสามตัวแปรมีค่าต่างกันทั้งหมด
  • ตัวแก้ปัญหาจะรับโมเดลเป็นอินพุตและส่งคืนคำตอบที่ใช้ได้
    • คำตอบตัวอย่าง a = 19, b = 11, c = 20 สอดคล้องกับข้อจำกัดทั้งหมด
    • แต่เนื่องจาก Carol จ่ายเกือบสองเท่าของ Bob จึงอาจยังมีคำตอบที่สมดุลกว่านี้
  • ฟังก์ชันวัตถุประสงค์ใช้เพื่อลดหรือเพิ่มค่าสูงสุดของนิพจน์บางอย่างในบรรดาคำตอบที่สอดคล้องกับข้อจำกัด
    • เพิ่มตัวแปรใหม่ x ให้เป็นจำนวนเงินสมทบที่มากที่สุด และใช้ maximum(x, [a, b, c])
    • เมื่อนำ minimize: x มาใช้ จะได้ a = 18, b = 17, c = 15, x = 18
    • ส่วนต่างระหว่างจำนวนเงินสมทบมากที่สุดกับน้อยที่สุดลดลงจาก 9 ดอลลาร์เหลือ 3 ดอลลาร์

สร้างโมเดลตารางเวรด้วย CP-SAT และ Python

  • ตัวอย่างใช้งานจริงคือปัญหาการสร้าง ตารางเวรรายสัปดาห์ สำหรับร้านค้าขนาดเล็ก
    • ร้านเปิดทุกวันตั้งแต่ 8 โมงเช้าถึง 2 ทุ่ม
    • ในหนึ่งวันมี 3 กะคือ Morning, Afternoon, Evening และแต่ละกะยาว 4 ชั่วโมง
    • บทบาทมี 2 แบบคือ Cashier และ Restocker
    • พนักงานมี 4 คนคือ Phil, Emma, David, Rebecca
  • CP-SAT เป็นตัวแก้ปัญหา CP แบบโอเพนซอร์สที่รวมอยู่ใน Google OR-Tools
  • โมเดลว่างสร้างได้ด้วย cp_model.CpModel() จาก ortools.sat.python
  • บทบาทที่พนักงานแต่ละคนทำได้มีดังนี้
    • Phil: Restocker
    • Emma: Cashier, Restocker
    • David: Cashier, Restocker
    • Rebecca: Cashier
  • ตารางเวรถูกแทนด้วย ตัวแปรบูลีน ที่เป็นการผสมกันของพนักงาน·บทบาท·วัน·กะ
    • schedule["Emma"]["Restocker"]["Monday"]["Evening"] จะเป็น 1 ถ้า Emma ทำงานเป็น Restocker ในกะเย็นวันจันทร์ และเป็น 0 ถ้าไม่ใช่
    • model.new_bool_var() ใช้สร้างตัวแปรที่มีโดเมนเป็น {0, 1}

ข้อจำกัดพื้นฐานของตารางเวร

  • เนื่องจากต้องมีพนักงานคิดเงินหนึ่งคนพอดีในทุกช่วงเวลา ผลรวมของบทบาท Cashier ในแต่ละวัน·แต่ละกะจึงต้องเท่ากับ 1
  • ส่วนงานเติมสต็อกต้องมีเพียงหนึ่งกะต่อวัน ดังนั้นผลรวมทั้งหมดของบทบาท Restocker ในแต่ละวันจึงกำหนดให้เป็น 1
  • เพื่อไม่ให้กะเติมสต็อก Evening ของวันก่อนหน้าต่อเนื่องกับกะ Morning ของวันถัดไป จึงจำกัดให้ผลรวมของการมอบหมายทั้งสองไม่เกิน 1
  • พนักงานหนึ่งคนไม่สามารถทำสองบทบาทพร้อมกันในกะเดียวกันได้ ดังนั้นผลรวมของบทบาทต่อพนักงาน·วัน·กะต้องไม่เกิน 1
  • เพื่อไม่ให้มีการมอบหมายบทบาทที่ไม่มีคุณสมบัติ ตัวแปรของบทบาทที่พนักงานคนนั้นทำไม่ได้จะถูกตรึงเป็น 0 ทั้งหมด
  • เวลาทำงานสูงสุดต่อวันคือ 8 ชั่วโมง หรือ 2 กะ
    • ถ้าถูกมอบหมายทั้ง Morning และ Evening ในวันเดียวกัน จะเกิดช่วงว่าง 4 ชั่วโมงระหว่าง Afternoon
    • จึงจำกัดผลรวมของการมอบหมาย Morning และ Evening ต่อพนักงาน·วันให้ไม่เกิน 1 เพื่อป้องกันทั้งการทำงานเกิน 2 กะต่อวันและช่วงว่างกลางวัน

การรันตัวแก้ปัญหาและผลลัพธ์เริ่มต้น

  • เมื่อต้องการแก้โมเดล ให้สร้าง cp_model.CpSolver() แล้วเรียก solver.solve(model)
  • หลังได้คำตอบแล้ว สามารถอ่านค่าของตัวแปร schedule ได้ด้วย solver.value(...)
  • ตารางเวรเริ่มต้นสอดคล้องกับข้อจำกัดพื้นฐานทั้งหมด แต่ปรากฏว่า Rebecca ได้ทำงานถึง 14 กะ ในหนึ่งสัปดาห์
  • เพื่อหลีกเลี่ยงการทำงานล่วงเวลา จึงเพิ่มข้อจำกัดให้พนักงานแต่ละคนทำงานสัปดาห์ละไม่เกิน 40 ชั่วโมง หรือ 10 กะ
  • Phil เป็นนักศึกษาเต็มเวลา จึงทำงานได้สัปดาห์ละ 4 กะพอดี และไม่สามารถทำงานในกะ Morning และ Afternoon ของวันธรรมดาเพราะติดเรียน
  • เพื่อไม่ให้ Phil และ Emma ทำงานกะเดียวกัน ในแต่ละวัน·แต่ละกะจึงจำกัดให้ผลรวมการมอบหมายของทั้งสองคนไม่เกิน 1
  • สำหรับเวรสุดสัปดาห์ที่ทุกคนไม่ชอบ มีการกำหนดข้อจำกัดให้กะทั้งหมด 8 กะของวันเสาร์และอาทิตย์ถูกกระจายไปยังพนักงาน 4 คนแบบ คนละ 2 กะ

สถานะของคำตอบ: OPTIMAL, INFEASIBLE, FEASIBLE, UNKNOWN

  • ตัวแก้ปัญหาจะรับโมเดลและส่งคืนทั้ง สถานะ และคำตอบ
  • OPTIMAL หมายถึงพบคำตอบที่ไม่มีคำตอบที่ดีกว่านี้แล้ว
    • ตัวอย่างเช่น ถ้า x + y >= 5 และต้องการทำให้ x + y ต่ำที่สุด ค่า (x, y) = (5, 0) คือคำตอบที่เหมาะที่สุด
    • (x, y) = (3, 2) ก็อาจเป็นคำตอบที่เหมาะที่สุดได้เช่นกันเพราะให้ค่าวัตถุประสงค์เท่ากัน
  • INFEASIBLE หมายถึงไม่ว่าจะกำหนดค่าให้ตัวแปรอย่างไรก็ไม่สามารถทำให้ข้อจำกัดทั้งหมดเป็นจริงได้
    • ตัวอย่างเช่น หาก x ∈ {0, ..., 10} แต่กำหนดให้ x >= 15 ก็เป็นไปไม่ได้
  • หากตัวแก้ปัญหาถูกหยุดเพราะข้อจำกัดด้านเวลาเนื่องจากปัญหาใหญ่หรือฟังก์ชันวัตถุประสงค์ซับซ้อน อาจได้สองสถานะ
    • FEASIBLE: พบคำตอบที่สอดคล้องกับข้อจำกัดแล้ว แต่ยังไม่รู้ว่าเป็นคำตอบที่ดีที่สุดหรือไม่
    • UNKNOWN: ยังหาคำตอบไม่พบ และก็ยังไม่รู้ว่ามีคำตอบอยู่หรือไม่

คำขอลางานและการกระจายงานอย่างเป็นธรรม

  • หากเพิ่มข้อจำกัดว่า Emma ต้องการหยุดตั้งแต่วันจันทร์ถึงวันศุกร์ สถานะของตัวแก้ปัญหาจะกลายเป็น INFEASIBLE
    • เพราะไม่สามารถจัดตารางเวรให้ครบได้โดยไม่ละเมิดข้อจำกัดอื่น
  • หากเปลี่ยนเป็นให้ Emma หยุดแค่วันจันทร์ถึงวันพุธ ก็ยังสามารถสร้างตารางเวรได้
    • Phil ทำงานครบ 4 กะตามที่ต้องการ
    • Emma ได้ 6 กะ, David ได้ 10 กะ, Rebecca ได้ 8 กะ
  • เพื่อให้จำนวนกะของ Emma, David, Rebecca สมดุลกันมากขึ้น จึงเพิ่มฟังก์ชันวัตถุประสงค์
    • สร้างตัวแปรจำนวนเต็ม total_shifts เพื่อแทนจำนวนกะรวมของพนักงานแต่ละคน
    • ใช้ model.new_int_var(0, 10, ...) เพื่อสร้างตัวแปรจำนวนเต็มที่มีค่าได้ตั้งแต่ 0 ถึง 10
    • เนื่องจาก Phil เป็นพาร์ตไทม์จึงถูกยกเว้น และใช้ model.add_min_equality(...) กับ model.add_max_equality(...) เพื่อติดตามจำนวนกะต่ำสุดและสูงสุด
    • ใช้ model.minimize(max_shifts - min_shifts) เพื่อลดส่วนต่างระหว่างจำนวนกะมากที่สุดกับน้อยที่สุด
  • ผลลัพธ์สุดท้ายคือ Phil 4 กะ, Emma 6 กะ, David 9 กะ, Rebecca 9 กะ
    • Emma ได้ 6 กะเพราะหยุด 3 วัน
    • David และ Rebecca ถูกกระจายงานเท่ากันที่ 9 กะ

โค้ดตัวอย่างและหัวข้อถัดไป

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

1 ความคิดเห็น

 
GN⁺ 2024-07-05
ความคิดเห็นจาก Hacker News
  • เคยลองใช้ ตัวแก้ปัญหาเงื่อนไขข้อจำกัด มาก่อน สิ่งที่มันทำได้ให้ความรู้สึกเหมือนเวทมนตร์จริง ๆ ปัญหาคือมีแหล่งข้อมูลสำหรับมือใหม่ไม่มากนัก
    ส่วนใหญ่จะเป็นการแก้ซูโดกุ (Hello World ของสาขานี้) หรือไม่ก็เป็นเอกสารวิจัยขั้นต้นที่มีเทคนิคสูงสำหรับผู้เชี่ยวชาญเฉพาะโดเมนเท่านั้น
    ที่น่าเสียดายคือถ้าเครื่องมือพวกนี้เข้าถึงได้ง่ายขึ้น น่าจะช่วยแก้ปัญหาได้มหาศาล คำว่าเข้าถึงได้ในที่นี้ก็ยังหมายความว่าต้องมีโปรแกรมเมอร์อยู่ดี และการปั้นปัญหาให้อยู่ในรูป DSL ของเงื่อนไขข้อจำกัดก็ไม่ใช่สิ่งที่คนส่วนใหญ่ทำได้ดี

    • ผมคิดว่าสาเหตุที่เครื่องมือแบบนี้ยังเข้าถึงได้ไม่พอ เป็นเพราะตัวแก้ปัญหาส่วนใหญ่มีพื้นฐานจาก Mixed Integer Programming (MIP) ทำให้ต้องเขียนโดเมนออกมาเป็นสมการคณิตศาสตร์ ซึ่งผู้ใช้ต้องรู้ทั้งโดเมนและคณิตศาสตร์ จึงจะเขียนเงื่อนไขข้อจำกัดได้ถูกต้อง
      อย่างไรก็ตาม MIP ไม่ใช่ทั้งหมดของตัวแก้ปัญหา ยังมีตัวแก้ปัญหาเงื่อนไขข้อจำกัดแบบ local search ด้วย วิธีนี้ไม่มีข้อจำกัดว่าต้องโมเดลเงื่อนไขข้อจำกัดทั้งหมดเป็นความสัมพันธ์หรือสมการระหว่างตัวแปรจำนวนเต็ม
      ในตัวแก้ปัญหาแบบ local search โดยทั่วไปจะมองเงื่อนไขข้อจำกัดเป็นกล่องดำที่บอกว่าเฉลยหนึ่ง ๆ ดีแค่ไหน ดังนั้นจึงรับประกันเฉลยที่ดีที่สุดได้ยาก เว้นแต่จะลองทุกเฉลยที่เป็นไปได้ แต่ก็มักหาเฉลยใกล้เหมาะที่สุดได้ภายในเวลาที่สมเหตุสมผล
      Timefold Solver เป็นหนึ่งในตัวแก้ปัญหาแบบ local search เหล่านี้ ผู้ใช้ใส่ annotation ให้โดเมน เพื่อให้ตัวแก้ปัญหารู้จักตัวแปรและค่าที่เป็นไปได้ ดังนั้นเงื่อนไขข้อจำกัดจึงจัดการกับ Shift และ Employee แทน int และยังเข้าถึงเมธอดของสิ่งเหล่านั้นได้ด้วย
      เปิดเผย: ผมทำงานที่ Timefold Solver
    • ใช่เลยตามนั้น ไวยากรณ์หรือ API จริง ๆ ของตัวแก้ปัญหาเงื่อนไขข้อจำกัดนั้นเรียบง่ายมากจนเรียนรู้ได้เร็ว ส่วนที่ต้องใช้เวลาและความเชี่ยวชาญจริง ๆ คือการ โมเดลปัญหา ด้วยวิธีนี้ แต่แทบไม่มีตัวอย่างที่มีขนาดและความซับซ้อนระดับใช้งานจริงให้ดูเลย
      ผมมีประสบการณ์ประมาณ 5 ปีในการแก้ปัญหาการจัดตารางด้วย MiniZinc แต่น่าเสียดายว่าโค้ดทั้งหมดเป็นแบบปิด จึงไม่มีทางเผยแพร่เป็นโอเพนซอร์ส
      ผมอยากทำตัวอย่าง constraint programming แบบสมบูรณ์ที่รวมทั้ง containerization, visualization และ modeling แต่สิ่งที่เป็นอุปสรรคคือการหาปัญหาที่คุ้มค่าจริง ๆ ต่อการแก้ และมีข้อมูลโอเพนซอร์สที่ใช้งานได้
    • เห็นด้วยว่า reduction ยากกว่าทฤษฎีเองมาก หนังสือ "SAT/SMT by Example" ของ Dennis Yurichev (https://smt.st/) เป็นแหล่งข้อมูลที่ดีในหัวข้อนี้ แต่ก็ค่อนข้างน่าเกรงขาม
    • คำพูดที่ว่า “แหล่งข้อมูลส่วนใหญ่เป็นการแก้ซูโดกุหรือเอกสารวิจัยสำหรับผู้เชี่ยวชาญเฉพาะโดเมน” นั้นตรงมาก ผมเคยพยายามใช้ SAT solver กับ rule engine แต่ไม่รู้เลยว่าควรใช้ยังไง
      หลังจากอนุมานอยู่พักใหญ่ก็ทำ proof of concept พื้นฐานออกมาได้ แต่ขยายไปถึงระดับที่ต้องการจริง ๆ ไม่ได้ ช่องว่างระหว่าง implementation แบบของเล่นกับสิ่งที่ใช้งานได้จริงกว่านั้นใหญ่มาก
    • เขียนโค้ดมานาน แต่ตอนนี้ฝีมือขึ้นสนิมไปบ้าง ปีที่แล้วผมทำตัวเพิ่มประสิทธิภาพทีมฟุตบอลด้วย OR-Tools ของ Google มีเงื่อนไขข้อจำกัดแบบตัวเลือก เช่น การได้เล่นกับเพื่อน และเงื่อนไขอย่างการปรับสมดุลทักษะระหว่างทีม
      LLM ช่วยพาไปในทิศทางที่คร่าว ๆ ถูกต้องได้ค่อนข้างเร็ว ตอนนี้มันยังทำให้ถูกเป๊ะไม่ได้ แต่ก็ช่วยมากพอให้ผมไปทำส่วนที่เหลือต่อเองจนเสร็จได้
  • แก่นของทั้งหมดนี้อยู่ที่การเรียนรู้วิธี โมเดล บางอย่างให้อยู่ในรูปที่ส่งให้ตัวแก้ปัญหาได้ จากนั้นคือวิธีนำเสนอเฉลยที่ได้ให้อยู่ในรูปที่มนุษย์เข้าใจได้
    ที่น่าเสียดายคือโปรแกรมส่วนใหญ่พยายามเก็บข้อมูลไว้ในรูปแบบเดียวเท่านั้น ซึ่งสวนทางกับวิธีคิดแบบนี้ ส่วนใหญ่แล้วการทำแบบนั้นไม่สมเหตุสมผล และทำให้เกิดความบิดเบี้ยวมากมายเพื่อปรับอัลกอริทึมให้เข้ากับรูปแบบใหม่
    บทความนี้ก็แตะประเด็นนี้ตั้งแต่ช่วงต้น ๆ โดยพูดถึงแนว declarative สั้น ๆ ผมเสียใจอยู่เสมอที่โค้ดของตัวเองไม่ได้แปลงระหว่างรูปแทนข้อมูลให้บ่อยกว่านี้ การทำเช่นนั้นจะได้รูปแทนที่กระชับมาก และเพราะมันกระชับขึ้นจึงได้ประโยชน์สองต่อคือเร็วขึ้นด้วย
    แน่นอน ผมรู้ว่าสุดท้ายแล้วนี่ก็เป็นคำอธิบายของ data pipeline จำนวนมาก โครงสร้างที่ใช้เวลาส่วนใหญ่ไปกับการแปลงข้อมูลและแยกไปยังตำแหน่งคำนวณหลายแห่ง

  • ในหนังสือเล่มหนึ่งที่ผมเคยเขียนและกำลังเขียนใหม่อยู่ตอนนี้ มีบทสั้น ๆ เกี่ยวกับการใช้ MiniZinc ใน Python: https://leanpub.com/pythonai/read#constraint-programming-wit...
    MiniZinc เป็นระบบ constraint programming และยังมีคอร์ส Coursera ดี ๆ ที่ใช้ MiniZinc ด้วย

    • มีลิงก์คอร์ส Coursera ไหม
  • หลังจากเรียนเศรษฐมิติ ผมใช้ตัวแก้ปัญหาเยอะมากในหลักสูตรปริญญาโทด้าน operations research ช่วงต้นทศวรรษ 2000 ตอนนี้ทำงานสายซอฟต์แวร์เว็บที่ใช้ Python พอได้เห็นบทความเชิงลึกในหัวข้อนี้ก็รู้สึกดี
    ผมชอบหัวข้อนี้ และพออ่านบทความก็ทำให้นึกถึงความทรงจำมากมาย อีกทั้งยังตระหนักอีกครั้งว่าการย้ายเงื่อนไขข้อจำกัดไปเป็นโมเดล (ตัวแปร โครงสร้าง ฯลฯ) คือ 90% ของงานและเป็นส่วนที่ยากที่สุด

    • ตอนเรียนปริญญาโท ผมใช้โปรแกรมชื่อ GAMS
      โครงสร้างไวยากรณ์เป็นแบบ free form อย่างสมบูรณ์
      https://www.gams.com/latest/docs/UG_GAMSPrograms.html#UG_GAM...
    • LLM อาจช่วยได้ค่อนข้างมากในการย้ายเงื่อนไขข้อจำกัดไปเป็นโมเดล ผมเคยอยากลองใช้อะแดปเตอร์ที่แปลงจาก LLM ไปเป็น constraint model
      ดูเหมือนเป็นผลไม้ที่เด็ดได้ค่อนข้างง่าย แต่ก็สงสัยว่าคนอื่น ๆ จะได้ประโยชน์ด้วยไหม
    • ผมคิดว่าส่วนที่ยากที่สุดคือการทำให้ปัญหารันโดยย่อให้เล็กที่สุดใน สภาพแวดล้อมโปรดักชัน การสเกลและทำให้ทนทานต่อการเปลี่ยนแปลงของข้อมูลใช้เวลานาน
  • มีลูกค้ารายหนึ่งที่ดำเนินการแคมป์กีฬาสำหรับเด็ก เด็ก ๆ สามารถขอกีฬาที่อยากเล่น และขอเพื่อนที่อยากอยู่ห้องเดียวกันได้
    ด้วยเหตุนี้จึงเกิด ปัญหาการจัดตารางเวลา ที่มนุษย์แก้ได้ยาก และเมื่อก่อนต้องใช้แรงคนหลายสัปดาห์ทุกปีในการทำงานนี้ เราสร้างระบบง่าย ๆ ที่เชื่อมข้อมูลของลูกค้าเข้ากับตัวเพิ่มประสิทธิภาพบนพื้นฐาน OR-Tools ให้ และตอนนี้การจัดตารางเวลาก็เสร็จได้ด้วยการคลิกไม่กี่ครั้ง

    • ใช่เลย ถ้าใส่ข้อมูล ข้อจำกัด และฟังก์ชันอรรถประโยชน์ลงในระบบอย่างถูกต้อง ก็สามารถหาคำตอบที่ดีพอได้จำนวนมากอย่างรวดเร็วมาก
      ผมเป็นโค้ชลีกบาสเกตบอลที่มี 8 ช่วงเวลา ผู้เล่นคนใดก็ตามจะลงเล่นมากกว่าผู้เล่นคนอื่นเกิน 2 ช่วงเวลาไม่ได้ จำนวนไลน์อัปที่เป็นไปได้ต่อเกมนั้นมีมากมายมหาศาล แม้ต้องเป็นไปตามข้อจำกัดเรื่องเวลาเล่น
      การหาชุดไลน์อัปที่เป็นไปตามข้อจำกัดนั้นง่ายมาก แต่การหาชุดไลน์อัปที่เหมาะที่สุดหรือเกือบเหมาะที่สุดนั้นยากมาก และจะยิ่งน่าสนุกขึ้นถ้าต้องสะท้อนผู้เล่นที่มาสายหรือหายไปโดยไม่บอก
      *ไม่ได้เป็นไปได้อย่างสมบูรณ์เสมอไป
    • บทความบล็อก ที่เขียนรายละเอียดว่าทำสิ่งนี้อย่างไร จะต้องได้รับความนิยมอย่างมหาศาลแน่นอน
  • สงสัยว่ามี parametric CAD ที่ทำงานหลัก ๆ เป็นตัวแก้ข้อจำกัดหรือไม่
    บ่อยครั้งที่น่ารำคาญมาก เพราะตอนแรกต้องเดาค่าพารามิเตอร์ที่ไม่ได้สนใจแบบคร่าว ๆ ถ้าสามารถตั้งพารามิเตอร์ที่สนใจเป็นข้อจำกัด แล้วเพิ่มประสิทธิภาพส่วนที่เหลือได้ก็คงดี

  • สงสัยว่าวิธีนี้เทียบกับ mixed-integer programming อย่างไร แล้วถ้าเป็นปัญหาทางฟิสิกส์ล่ะ

    • ปัญหาหลายอย่างสามารถตั้งโจทย์ได้ทั้งสองวิธี MILP จะมีฟังก์ชันวัตถุประสงค์เสมอ และข้อจำกัดจะเป็นการรวมเชิงเส้นของตัวแปรตัดสินใจเสมอ
      เพราะ Gurobi เร็วอย่างไม่น่าเชื่อ จึงอาจคุ้มที่จะบิดปัญหาให้เข้าเป็น MILP แม้จะฝืนบ้าง เพื่อให้ได้คำตอบ
    • CP-SAT รองรับเฉพาะจำนวนเต็ม จึงคิดว่าไม่น่าจะเหมาะกับฟิสิกส์นัก แม้จะสเกลจำนวนจริงได้ แต่ก็ไม่ดีเท่าการจัดการเลขทศนิยมลอยตัวโดยตรง
      จุดแข็งของ CP-SAT คือจัดการตัวแปรและข้อจำกัดแบบบูลีนกับจำนวนเต็มได้มีประสิทธิภาพกว่าตัวแก้ MIP มาก โดยเฉพาะกับข้อจำกัดระดับสูงอย่าง all_different
    • เดาว่าโดยรวมค่อนข้างคล้ายกัน https://www.amazon.com/gp/product/1107658799/ เป็นหนังสือเล่มล่าสุดที่อ่านเกี่ยวกับหัวข้อนี้ และพูดถึงไอเดียเดียวกันหลายอย่าง
      โดยเฉพาะส่วนในบทความนี้ที่พยายามทำให้ค่าบางอย่างน้อยที่สุด ก็มองได้ว่าเขียนสิ่งเดียวกันออกมาตรง ๆ