FP cho mô phỏng và mô hình hóa


12

Tôi sắp bắt đầu một dự án mô phỏng / mô hình hóa. Tôi đã biết rằng OOP được sử dụng cho loại dự án này. Tuy nhiên, nghiên cứu Haskell khiến tôi cân nhắc sử dụng mô hình FP để mô hình hóa một hệ thống các thành phần. Hãy để tôi giải thích:

Giả sử tôi có một thành phần loại A, được đặc trưng bởi một tập hợp dữ liệu (tham số như nhiệt độ hoặc áp suất, PDE và một số điều kiện biên, v.v.) và một thành phần của loại B, được đặc trưng bởi một bộ dữ liệu khác nhau (khác nhau hoặc cùng tham số, PDE khác nhau và điều kiện biên). Chúng ta cũng giả sử rằng các hàm / phương thức sẽ được áp dụng trên mỗi thành phần là như nhau (ví dụ phương thức Galerkin). Trạng thái có thể thay đổi của đối tượng sẽ được sử dụng cho các tham số không cố định.

Nếu tôi sử dụng cách tiếp cận OOP, tôi sẽ tạo hai đối tượng sẽ đóng gói dữ liệu của từng loại, các phương thức để giải quyết PDE (kế thừa sẽ được sử dụng ở đây để sử dụng lại mã) và giải pháp cho PDE.

Mặt khác, nếu tôi sử dụng phương pháp FP, mỗi thành phần sẽ được chia thành các phần dữ liệu và các chức năng sẽ tác động lên dữ liệu để có được giải pháp cho PDE. Các tham số không cố định sẽ được truyền dưới dạng các hàm của một thứ khác (ví dụ như thời gian) hoặc được biểu thị bằng một loại biến đổi nào đó (mô phỏng tính biến đổi, v.v.) Cách tiếp cận này có vẻ đơn giản hơn đối với tôi khi cho rằng các hoạt động tuyến tính trên dữ liệu sẽ là tầm thường.

Để kết luận, việc thực hiện phương pháp FP sẽ thực sự đơn giản và dễ quản lý hơn (thêm một loại thành phần hoặc phương pháp mới khác để giải quyết pde) so với phương pháp OOP?

Tôi đến từ nền tảng C ++ / Fortran, cộng với tôi không phải là một lập trình viên chuyên nghiệp, vì vậy hãy sửa cho tôi bất cứ điều gì tôi đã sai.

Câu trả lời:


7

Câu hỏi hay, tôi đã suy nghĩ theo các dòng tương tự. Trong lịch sử, mô hình OO nảy sinh từ nhu cầu mô phỏng máy tính - xem lịch sử của Simula - và mặc dù các ngôn ngữ OO ban đầu như Smalltalk được tạo ra bởi những người biết họ đang làm gì (ví dụ Alan Kay), OO hiện được sử dụng quá mức và mang lại quá nhiều phức tạp tình cờ .

Nói chung, các chương trình kiểu FP sẽ ngắn hơn, dễ kiểm tra hơn và dễ sửa đổi hơn các chương trình OO. Như Rob Harrop đã nói trong bài nói chuyện của mình, Là chức năng tương lai? , bạn không bao giờ có thể nhận được đơn giản hơn các chức năng và dữ liệu; cả hai sáng tác vô tận, để xây dựng bất cứ điều gì trừu tượng là cần thiết. Vì vậy, một cách để trả lời câu hỏi của bạn (hoặc tôi chỉ đang khôi phục nó? :) là hỏi, chức năng cấp cao nhất và dữ liệu đầu vào cấp cao nhất -> dữ liệu đầu ra trông như thế nào? Sau đó, bạn có thể bắt đầu chia các hàm và kiểu dữ liệu "alpha" đó thành lớp trừu tượng tiếp theo và lặp lại khi cần thiết.

Một góc nhìn khác (không hoàn toàn là câu trả lời) cho câu hỏi của bạn là xem xét chủ đề này (từ chối trách nhiệm, tôi đã bắt đầu nó) trên StackOverflow, một số câu trả lời rất thú vị: /programming//questions 43231654 / how-does- lập trình chức năng-áp dụng cho mô phỏng

Quan điểm của riêng tôi vào thời điểm này là, trừ khi bạn mô hình hóa một tình huống thực sự có các đối tượng riêng biệt chỉ tương tác theo những cách xác định (ví dụ như mô hình của mạng máy tính) - và do đó ánh xạ trực tiếp đến khả năng của một tin nhắn sạch sẽ- ngôn ngữ OO vượt qua mô hình - đơn giản hơn để đi FP. Lưu ý rằng ngay cả trong cộng đồng lập trình trò chơi - nơi mô phỏng rất phổ biến và yêu cầu về hiệu suất là tối quan trọng - các nhà phát triển có kinh nghiệm đang rời khỏi mô hình OO và / hoặc sử dụng thêm FP, ví dụ như xem thảo luận về HN này hoặc bình luận của John Carmack về FP


Thật tốt khi biết rằng tôi không phải là người duy nhất nghi ngờ về OOP trong mô phỏng và cảm ơn vì đã trả lời câu hỏi của tôi! Tôi đã đọc các bình luận của John Carmack về FP và tôi nghĩ về việc triển khai một số khía cạnh của FP trên C ++ (sao chép các đối tượng hoặc thu thập dữ liệu đầu vào và chuyển nó vào một chức năng) nhưng sau đó tôi không biết liệu tôi có nên bắt đầu dự án của mình với C ++ không thay vì ngôn ngữ FP, như Haskell, vì các khía cạnh của FP được tích hợp sẵn và bạn chỉ thể hiện khả năng biến đổi khi cần thiết. Bạn có tiếp tục sử dụng Clojure hoặc FP nói chung, xem xét rằng bạn có một vấn đề / câu hỏi tương tự?
mũ sắt

@ematptobesapes - Vâng, tôi đã liên tục tăng tốc Clojure-fu của mình với mục tiêu viết mô phỏng trong đó. Chưa có gì sẵn sàng để hiển thị, nhưng tôi thấy không có điểm dừng nào và thiết kế của Clojure rất thực dụng, ví dụ: bạn có thể sử dụng tạm thời / đột biến nếu cần, cộng với các tác nhân của nó rất phù hợp với các khía cạnh không đồng bộ. Tại một số điểm (không hứa hẹn khi nào) tôi sẽ viết một bài viết về chủ đề này ...
limist

Tôi đã xem Clojure nhưng tôi không thể nói tôi thích biểu cảm S. Tôi biết nó là thực tế (mã Lisp là dữ liệu) nhưng nó có dễ làm quen không?
mũ sắt

@ematptobesapes - cú pháp s-biểu thức / Lisp thực sự rất dễ làm quen; trước tiên hãy chọn một biên tập viên giỏi (Emacs hoặc vim, phiếu bầu của tôi là dành cho Emacs, xem dev.clojure.org/display/doc/Getting+Started+with+Emacs ) có chế độ cho Clojure, nhận một cuốn sách hay (ví dụ: Lập trình Clojure ), và bắt đầu hack. Sau một vài tuần, cú pháp sẽ mờ dần vào nền, vì vậy - nó hoàn toàn phù hợp, bạn sẽ nghĩ về nó theo cấp số nhân ít thường xuyên hơn và giải phóng các chu kỳ tinh thần cho những điều quan trọng hơn. :)
limist

Tôi chắc chắn sẽ thử nó sau đó. Rốt cuộc đồng âm của Lisp là thú vị sau khi tất cả.
mũ sắt

2

IMHO cho hầu hết mọi nhiệm vụ có độ phức tạp hợp lý, câu hỏi "là kiểu FP hay kiểu OOP, sự lựa chọn tốt hơn" không thể được trả lời một cách khách quan. Thông thường, trong tình huống như vậy, câu hỏi không phải là "hoặc là FP hoặc OOP", mà là cách kết hợp các phần tốt nhất của cả hai mô hình để giải quyết vấn đề của bạn.

Vấn đề bạn đã tìm hiểu ở trên dường như là một vấn đề rất toán học, và tôi đoán một cách hoang dã rằng bạn sẽ cần một số thao tác ma trận. OOP rất tốt để mô hình hóa các kiểu dữ liệu trừu tượng và phép tính ma trận có thể dễ dàng thực hiện dưới dạng "đối tượng ma trận" với các phép toán trên ma trận. Thực hiện điều này theo cách mà tất cả các hoạt động ma trận là một phần của lớp ma trận giúp bạn giữ mọi thứ cùng thuộc về nhau, do đó duy trì cấu trúc tổng thể tốt.

Mặt khác, PDE là các phương trình trên các hàm và giải pháp có thể là chức năng một lần nữa. Vì vậy, sử dụng một cách tiếp cận chức năng cho loại "thành phần" đó có vẻ tự nhiên ở đây. Các hàm này có thể có các tham số ma trận, hiển thị một ví dụ về cách kết hợp OOP và FP. Một ví dụ khác là triển khai lớp ma trận, sử dụng các công cụ chức năng để ánh xạ một hoạt động nhất định đến mọi phần tử của ma trận của bạn. Vì vậy, ở đây cũng vậy, nó không phải là "OOP so với FP" mà là "OOP kết hợp với FP" mang lại cho bạn kết quả tốt nhất.


Cảm ơn về câu trả lời của bạn! Vì vậy, nếu tôi sử dụng C ++ ở đâu, sẽ chỉ gói gọn dữ liệu (đó là tham số, điều kiện biên và PDE ở dạng ma trận) của thành phần cho một đối tượng và xác định các hàm (ngay cả một số thứ tự cao hơn, trong trường hợp a tham số là một chức năng của một cái gì đó khác), ngoài phạm vi của đối tượng, sẽ hoạt động trên dữ liệu của đối tượng, có hiệu quả không?
mũ sắt

@ematptobesapes: Thành thật mà nói, tôi không thể nói cho bạn biết nếu nó sẽ hiệu quả trong trường hợp của bạn . Hãy thử, nghĩ lớn, bắt đầu nhỏ. Bắt đầu lập trình một số "mã theo dõi" ( artima.com/intv/tracer.html ) để tìm ra cái gì hoạt động tốt nhất và cái gì không. Và nếu bạn gặp phải tình huống mà bạn nhận thấy rằng một cái gì đó không hoạt động đúng, hãy cấu trúc lại.
Doc Brown

Haskell có thư viện Hmatrix, đó là các ràng buộc cho các thư viện BLAS / LAPACK và một cú pháp rất hay cho nó, mà tôi sẽ chọn theo cách tiếp cận OOP cá nhân.
paul

@paul: Cảm ơn, tôi chắc chắn sẽ xem nó! Các thư viện Haskell thường nhất quán và phong phú về nội dung? Các wiki nói như vậy nhưng đây có phải là sự thật?
mũ sắt

@ematptobesapes: Thư viện Haskell duy nhất tôi từng sử dụng ở bất kỳ mức độ nào là Parsec (Tôi đã sử dụng nó để viết một trình biên dịch), nhưng tôi thích sử dụng nó. Tôi mới chỉ thực hiện khám phá GHCI về Hmatrix và các ràng buộc OpenGL của Haskell nhưng chúng có vẻ khá hay. Hmatrix trông có vẻ ngắn gọn như MATLAB (mà tôi đã sử dụng khá nhiều) - được tạo ra dành riêng cho loại điều đó. Từ kinh nghiệm hạn chế của tôi, các thư viện phù hợp - điều này là do Haskell được xây dựng trên một số lượng nhỏ các khối xây dựng đơn giản - và họ cũng giàu có vì Haskeller không thích làm những việc trần tục :)
paul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.