Những chiến lược lập trình nào tôi có thể thực hiện để dễ dàng sửa đổi các tham số thuật toán?


17

Phát triển các thuật toán khoa học là một quá trình lặp đi lặp lại thường liên quan đến việc thay đổi nhiều tham số mà tôi sẽ muốn thay đổi như là một phần của thiết kế thử nghiệm hoặc là một phần của hiệu suất thuật toán điều chỉnh. Những chiến lược nào tôi có thể thực hiện để cấu trúc các tham số này để tôi có thể dễ dàng thay đổi chúng giữa các lần lặp và để tôi có thể dễ dàng thêm các tham số mới?

Câu trả lời:


14

Nó là khó khăn cho người dùng để xác định mọi khía cạnh của một thuật toán. Nếu thuật toán cho phép các thành phần lồng nhau, thì không có số lượng tùy chọn hữu hạn nào là đủ. Do đó, điều quan trọng là các tùy chọn không nhất thiết phải "nổi bong bóng" lên mức cao nhất, như trong trường hợp đối số rõ ràng hoặc tham số mẫu. Điều này đôi khi được gọi là "vấn đề cấu hình" trong công nghệ phần mềm. Tôi tin rằng PETSc có một hệ thống mạnh mẽ duy nhất để quản lý cấu hình. Nó tương tự như mẫu Trình định vị dịch vụ trong bài tiểu luận về sự đảo ngược quyền kiểm soát của Martin Fowler .

Hệ thống cấu hình của PETSc hoạt động thông qua sự kết hợp của cấu hình do người dùng chỉ định được quản lý bởi các đối tượng người giải (với các truy vấn get và set) và Cơ sở dữ liệu tùy chọn. Bất kỳ thành phần nào của mô phỏng đều có thể khai báo tùy chọn cấu hình, giá trị mặc định và vị trí để đặt kết quả. Các đối tượng lồng nhau có các tiền tố có thể được tạo thành, sao cho mọi đối tượng cần cấu hình có thể được xử lý độc lập. Các tùy chọn có thể được đọc từ dòng lệnh, môi trường, tệp cấu hình hoặc từ mã. Khi một tùy chọn được khai báo, một chuỗi trợ giúp và trang man được chỉ định, để -helptùy chọn đó có thể hiểu được và để có thể viết GUI được liên kết chính xác.

Người dùng gọi một SetFromOptionsphương thức để làm cho một đối tượng tự cấu hình dựa trên các tùy chọn dòng lệnh. Gọi chức năng này là tùy chọn và có thể không được gọi nếu người dùng (người viết mã gọi PETSc) đang hiển thị các tùy chọn thông qua một số giao diện khác. Chúng tôi đặc biệt khuyên người dùng nên phơi bày cơ sở dữ liệu tùy chọn vì nó cung cấp cho người dùng cuối (người đang chạy ứng dụng) một sức mạnh lớn, nhưng không bắt buộc.

Một cấu hình điển hình, được gọi thông qua

PetscObjectOptionsBegin(object); /* object has prefix and descriptive string */
PetscOptionsReal("-ts_atol",                                      /* options database key */
                 "Absolute tolerance for local truncation error", /* long description */
                 "TSSetTolerances",                               /* function and man page on topic */
                  ts->atol,                                       /* current/default value *?
                  &ts->atol,                                      /* place to store value */
                  &option_set);                                   /* TRUE if the option was set */
PetscOptionsList("-ts_type","Time stepping method","TSSetType",TSList,
                 defaultType,typeName,sizeof typeName,&option_set);
TSAdaptSetFromOptions(ts->adapt);                                 /* configures adaptive controller method */
/* ... many others */
/* ... the following is only called from implicit implementations */
SNESSetFromOptions(ts->snes);                                     /* configure nonlinear solver. */
PetscOptionsEnd();

Ghi chú:

  • PetscOptionsList()trình bày cho người dùng một sự lựa chọn từ một danh sách động. Có một kiến ​​trúc plugin mà các triển khai mới có thể sử dụng để hiển thị bản thân như là hạng nhất cho người gọi. (Những triển khai này có thể được đặt trong các thư viện dùng chung và được sử dụng làm lớp đầu tiên mà không cần biên dịch lại chương trình.)
  • SNESSetFromOptions() cấu hình đệ quy các bộ giải tuyến tính, tiền điều kiện và bất kỳ thành phần nào khác cần cấu hình.

11

Tôi đã gặp phải vấn đề này nhiều lần khi phát triển mã mô phỏng của riêng mình từ đầu: tham số nào sẽ có trong tệp đầu vào, nên lấy từ dòng lệnh, v.v. Sau một số thử nghiệm, cách sau đây hóa ra là hiệu quả. (Nó không tiên tiến như PETSc.)

Thay vì viết một 'chương trình' mô phỏng thử nghiệm, tôi thiên về viết gói Python chứa tất cả các hàm & lớp cần thiết để chạy mô phỏng. Sau đó, tệp đầu vào truyền thống được thay thế bằng tập lệnh Python nhỏ với 5 đến 10 dòng mã. Một số dòng thường liên quan đến tải tệp dữ liệu và chỉ định đầu ra. Những người khác là hướng dẫn cho tính toán thực tế. Các giá trị mặc định tốt cho các đối số tùy chọn trong gói Python giúp người mới bắt đầu có thể sử dụng thư viện cho các mô phỏng đơn giản, trong khi người dùng nâng cao vẫn có quyền truy cập vào tất cả các chuông và còi.

Một vài ví dụ:


Điều này thật tuyệt, nhưng tôi nghĩ nó trực giao với vấn đề cấu hình. Nếu bạn cần chỉ định một thuật toán phân cấp hoặc lồng nhau, thì bạn có các tùy chọn để chỉ định cho nhiều đối tượng bên trong. Mã gọi những người thậm chí không thực sự biết về sự tồn tại của họ vì số cấp và loại lồng có thể thay đổi. Đây là vấn đề của tất cả những lựa chọn "sủi bọt". Với mã Python cấp cao của bạn, bạn có thể dễ dàng chỉ định các tùy chọn đó, nhưng bạn vẫn phải chỉ định chúng trong mã. Tôi nghĩ rằng đó không phải là một điều tốt.
Jed Brown

xmonad sử dụng phương pháp này để định cấu hình trình quản lý cửa sổ của họ cho X.
rcollyer

2

Như một điểm đầu tiên, tôi sẽ làm phần mềm VÀ thuật toán càng chung càng tốt. Tôi đã học được điều này một cách khó khăn.

Giả sử bạn bắt đầu với một trường hợp thử nghiệm đơn giản. Bạn có thể làm điều này nhanh hơn. Nhưng sau đó, nếu bạn làm cho phần mềm quá cụ thể (quá ít tham số) cho trường hợp ban đầu này, bạn sẽ mất nhiều thời gian hơn để thích nghi với nó mỗi khi bạn thêm một mức độ tự do mới. Những gì tôi làm bây giờ nó dành nhiều thời gian hơn vào lúc đầu để làm cho mọi thứ trở nên khá chung chung và tăng sự thay đổi của các tham số khi tôi tiến về phía trước.

Điều này bao gồm nhiều thử nghiệm hơn từ đầu vì bạn sẽ có nhiều tham số hơn từ điểm bắt đầu, nhưng sẽ có nghĩa là sau này bạn có thể chơi rất nhiều với thuật toán ở mức 0 hoặc chi phí rất thấp.

Ví dụ: thuật toán liên quan đến việc tính tích phân bề mặt tích của hai hàm vectơ. Đừng cho rằng ngay từ đầu kích thước, hình học và sự rời rạc của bề mặt nếu trong tương lai bạn có thể muốn thay đổi điều đó. Tạo một hàm sản phẩm chấm, làm cho bề mặt càng chung càng tốt, tính tích phân một cách trang trọng. Bạn có thể kiểm tra từng chức năng bạn thực hiện riêng biệt.

Lúc đầu, bạn có thể và bắt đầu tích hợp trên các hình học đơn giản và khai báo các tham số có thể khi bắt đầu là hằng số. Thời gian trôi qua, nếu bạn muốn thay đổi hình học, bạn có thể làm điều đó một cách dễ dàng. Nếu bạn đã đưa ra các giả định ngay từ đầu, bạn sẽ phải thay đổi toàn bộ mã mỗi lần.

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.