Làm thế nào người ta có thể quản lý hàng ngàn quy tắc IFSE THEN EL ELSE?


214

Tôi đang xem xét việc xây dựng một ứng dụng, trong đó, ở cốt lõi của nó, sẽ bao gồm hàng ngàn câu lệnh nếu ... thì ... khác. Mục đích của ứng dụng là có thể dự đoán cách bò di chuyển xung quanh trong bất kỳ cảnh quan nào. Họ bị ảnh hưởng bởi những thứ như mặt trời, gió, nguồn thực phẩm, sự kiện bất ngờ, v.v.

Làm thế nào một ứng dụng như vậy có thể được quản lý? Tôi tưởng tượng rằng sau vài trăm câu lệnh IF, sẽ tốt đến mức không thể đoán trước được chương trình sẽ phản ứng như thế nào và gỡ lỗi điều gì dẫn đến một phản ứng nhất định có nghĩa là người ta sẽ phải đi qua toàn bộ cây câu lệnh IF mỗi lần.

Tôi đã đọc một chút về các công cụ quy tắc, nhưng tôi không thấy chúng sẽ xoay quanh sự phức tạp này như thế nào.


22
Bạn cần xem Lập trình DSL: en.wikipedia.org/wiki/Domain-specific_lingu Ngoài ra, bạn cũng có thể tạo một số công cụ quy tắc meta điều khiển dữ liệu. Ví dụ: bạn có thể tạo các mô hình từ dữ liệu (ví dụ: khai thác dữ liệu KDD)
Darknight

14
google cho "hệ thống chuyên gia" và "mạng lưới"; chúc may mắn.
Steven A. Lowe

9
Di chuyển các câu lệnh if / then được mã hóa cứng ra khỏi mã nguồn vào dữ liệu ngoài điều khiển mô phỏng.
Kwebble

6
Tôi sẽ bung một số giá trị trong tệp văn bản và sử dụng vòng lặp để đi qua HashMap chứa tên.
James P.

2
David - trên các câu hỏi của Lập trình viên được chuyển đổi sang CW khi có hơn 15 câu trả lời được đăng. Chúng tôi không thể kiểm soát ai đăng câu trả lời thứ 16.
ChrisF

Câu trả lời:


73

Ngôn ngữ lập trình logic Prolog có thể là thứ bạn đang tìm kiếm. Báo cáo vấn đề của bạn không đủ cụ thể để tôi đánh giá xem nó có phù hợp hay không nhưng nó khá giống với những gì bạn nói.

Một chương trình Prolog bao gồm các sự kiện và quy tắc được áp dụng. Dưới đây là một quy tắc ví dụ đơn giản cho biết "Một con bò di chuyển đến một vị trí nếu con bò đói và có nhiều thức ăn ở vị trí mới hơn ở vị trí cũ":

moves_to(Cow, Location) :-
  hungry(Cow),
  current_location(Cow, OldLoc),
  food_in(OldLoc, OldFood), food_in(Location, NewFood),
  NewFood > OldFood.

Tất cả những thứ trong chữ in hoa là các biến, những thứ bạn không biết giá trị của. Prolog cố gắng tìm các giá trị cho các biến này thỏa mãn tất cả các điều kiện. Quá trình này được thực hiện với một thuật toán mạnh mẽ gọi là hợp nhất là trái tim của Prolog và các môi trường lập trình logic tương tự.

Ngoài các quy tắc, một cơ sở dữ liệu về các sự kiện được cung cấp. Một ví dụ đơn giản hoạt động với các quy tắc trên có thể là một cái gì đó như:

current_location(white_cow, pasture).

current_location(black_cow, barn).
hungry(black_cow).

current_location(angry_bull, forest).
hungry(angry_bull).

food_in(barn, 3).
food_in(pasture, 5).
food_in(forest, 1).

Lưu ý rằng white_cow và đồng cỏ, v.v. không được viết bằng chữ hoa. Chúng không phải là biến, chúng là nguyên tử.

Cuối cùng bạn thực hiện một truy vấn và hỏi những gì sẽ xảy ra.

?- moves_to(white_cow, Destination).
No.
?- moves_to(black_cow, Destination).
Destination = pasture
?- moves_to(Cow, Destination).
Cow = black_cow, Destination = pasture
Cow = angry_bull, Destination = barn
Cow = angry_bull, Destination = pasture

Truy vấn đầu tiên hỏi con bò trắng sẽ di chuyển ở đâu. Đưa ra các quy tắc và sự thật ở trên, câu trả lời là Không. Điều này có thể được hiểu là "Tôi không biết" hoặc "Nó không di chuyển" tùy thuộc vào những gì bạn muốn.

Truy vấn thứ hai hỏi con bò đen di chuyển đến đâu. Nó di chuyển đến đồng cỏ để ăn.

Truy vấn cuối cùng hỏi nơi làm tất cả những con bò di chuyển. Kết quả là bạn có được tất cả những gì có thể (Bò, Đích) có ý nghĩa. Trong trường hợp này, con bò đen di chuyển đến đồng cỏ như mong đợi. Tuy nhiên, con bò giận dữ có hai lựa chọn thỏa mãn các quy tắc, nó có thể di chuyển đến đồng cỏ hoặc chuồng.

Lưu ý: Đã nhiều năm kể từ lần cuối tôi viết Prolog, tất cả các ví dụ có thể không hợp lệ về mặt cú pháp nhưng ý tưởng phải chính xác.


10
-1: Tôi không nghĩ rằng Prolog có thể là câu trả lời đúng. Có, có thể dễ dàng có được các quy tắc if-other trong Prolog. Nhưng chắc chắn bạn sẽ phải làm một cái gì đó khác. Và bất kể đó là gì (IO; GUI, phát triển web, ...) nó sẽ là một nỗi đau với Prolog.
Martin Thoma

4
Kiểm tra learnprolognow.com Và việc nhúng prolog bên trong một ngôn ngữ khác dễ dàng hơn nhiều so với trước đây
Zachary K

@ZacharyK: Liên kết bị hỏng.
RenniePet

@MartinThoma: bạn có thể giải thích nhận xét của bạn? Các vấn đề chính với Prolog IMHO là thiếu 1. một cách khai báo để kiểm soát tìm kiếm và 2. gõ. Nhưng nếu ứng dụng của bạn không phụ thuộc nhiều vào hai thứ này thì tôi sẽ không gặp vấn đề gì khi sử dụng Prolog tại đây
SN

139

Giải quyết vấn đề về web nếu bạn có thể tạo một công cụ quy tắc trong đó mỗi quy tắc cụ thể được mã hóa độc lập. Một sàng lọc tiếp theo cho điều này sẽ là tạo một ngôn ngữ cụ thể miền (DSL) để tạo các quy tắc, tuy nhiên, một mình DSL chỉ thay thế vấn đề từ một cơ sở mã (chính) sang một cơ sở mã khác (DSL). Không có cấu trúc, DSL sẽ không tốt hơn ngôn ngữ bản địa (Java, C #, v.v.), vì vậy chúng tôi sẽ quay lại với nó sau khi chúng tôi tìm thấy một cách tiếp cận cấu trúc được cải thiện.

Vấn đề cơ bản là bạn đang gặp vấn đề về mô hình hóa. Bất cứ khi nào bạn gặp phải tình huống kết hợp như thế này, đó là một dấu hiệu rõ ràng cho thấy sự trừu tượng mô hình của bạn mô tả tình huống này quá thô. Bạn rất có thể kết hợp các yếu tố nên thuộc về các mô hình khác nhau trong một thực thể.

Nếu bạn tiếp tục phá vỡ mô hình của mình, cuối cùng bạn sẽ hoàn toàn hòa tan hiệu ứng kết hợp này. Tuy nhiên, khi đi theo con đường này, rất dễ bị lạc trong thiết kế của bạn tạo ra một mớ hỗn độn thậm chí còn lớn hơn, sự cầu toàn ở đây không nhất thiết là bạn của bạn.

Các máy trạng thái hữu hạn và các công cụ quy tắc chỉ là một ví dụ về cách giải quyết vấn đề này và dễ quản lý hơn. Ý tưởng chính ở đây là một cách tốt để loại bỏ một vấn đề kết hợp như thế này thường là tạo ra một thiết kế và lặp lại quảng cáo trong các mức độ trừu tượng lồng nhau cho đến khi hệ thống của bạn hoạt động tốt. Akin để làm thế nào fractals được sử dụng để tạo ra các mẫu phức tạp. Các quy tắc vẫn giữ nguyên cho dù bạn nhìn vào hệ thống của mình bằng kính hiển vi hay từ góc nhìn cao của chim.

Ví dụ về việc áp dụng điều này cho tên miền của bạn.

Bạn đang cố gắng mô hình hóa cách những con bò đang di chuyển qua một địa hình. Mặc dù câu hỏi của bạn thiếu chi tiết, tôi sẽ đoán rằng số lượng if lớn của bạn bao gồm cả phần quyết định, chẳng hạn như if cow.isStanding then cow.canRun = truebạn bị sa lầy khi bạn thêm chi tiết về địa hình chẳng hạn. Vì vậy, đối với mọi hành động bạn muốn thực hiện, bạn phải kiểm tra mọi khía cạnh bạn có thể nghĩ ra và lặp lại các xác minh này cho hành động có thể tiếp theo.

Đầu tiên chúng ta cần thiết kế lặp lại, trong trường hợp này sẽ là một FSM để mô hình hóa các trạng thái thay đổi của mô phỏng. Vì vậy, điều đầu tiên tôi sẽ làm là triển khai một FSM tham chiếu, xác định giao diện trạng thái , giao diện chuyển đổi và có lẽ là bối cảnh chuyển đổicó thể chứa thông tin được chia sẻ để cung cấp cho hai người kia. Việc triển khai FSM cơ bản sẽ chuyển từ chuyển đổi này sang chuyển đổi khác bất kể bối cảnh, đây là nơi công cụ quy tắc xuất hiện. Công cụ quy tắc đóng gói sạch các điều kiện phải đáp ứng nếu quá trình chuyển đổi diễn ra. Một công cụ quy tắc ở đây có thể đơn giản như một danh sách các quy tắc mà mỗi hàm có một hàm đánh giá trả về một boolean. Để kiểm tra xem có nên thực hiện quá trình chuyển đổi hay không, lặp lại danh sách các quy tắc và nếu bất kỳ quy tắc nào đánh giá là sai, quá trình chuyển đổi sẽ không diễn ra. Bản thân quá trình chuyển đổi sẽ chứa mã hành vi để sửa đổi trạng thái hiện tại của FSM (và các tác vụ có thể khác).

Bây giờ, nếu tôi bắt đầu thực hiện mô phỏng dưới dạng một FSM lớn duy nhất ở cấp độ GOD, tôi kết thúc với RẤT NHIỀU trạng thái có thể xảy ra, chuyển đổi, v.v ... bây giờ là một quy tắc thực hiện kiểm tra đối với một thông tin cụ thể của bối cảnh (tại thời điểm này có khá nhiều thứ) và mỗi phần thân IF nằm ở đâu đó trong mã chuyển đổi.

Nhập phân tích fractals: bước đầu tiên sẽ là tạo một FSM cho mỗi con bò trong đó các trạng thái là trạng thái bên trong của con bò (đứng, chạy, đi bộ, chăn thả, v.v.) và chuyển đổi giữa chúng sẽ bị ảnh hưởng bởi môi trường. Có thể đồ thị chưa hoàn thành, ví dụ, chăn thả chỉ có thể truy cập được từ trạng thái đứng, bất kỳ chuyển đổi nào khác đều bị loại bỏ vì đơn giản là không có trong mô hình. Ở đây bạn có hiệu quả phân tách dữ liệu theo hai mô hình khác nhau, con bò và địa hình. Mỗi thuộc tính được đặt riêng. Sự cố này sẽ cho phép bạn đơn giản hóa thiết kế động cơ tổng thể của bạn. Bây giờ thay vì có một công cụ quy tắc duy nhất quyết định tất cả những gì bạn có nhiều công cụ quy tắc đơn giản hơn (một cho mỗi lần chuyển đổi) quyết định các chi tiết rất cụ thể.

Bởi vì tôi đang sử dụng lại cùng một mã cho FSM, về cơ bản đây là cấu hình của FSM. Nhớ khi chúng tôi đề cập đến DSL trước đó? Đây là nơi DSL có thể làm rất nhiều việc tốt nếu bạn có nhiều quy tắc và chuyển tiếp để viết.

Đi sâu hơn

Bây giờ THIÊN CHÚA không còn phải đối phó với tất cả sự phức tạp trong việc quản lý trạng thái bên trong của con bò, nhưng chúng ta có thể đẩy nó đi xa hơn. Ví dụ, vẫn còn rất nhiều phức tạp liên quan đến việc quản lý địa hình. Đây là nơi bạn quyết định nơi sự cố là đủ. Ví dụ, trong GOD của bạn, bạn kết thúc việc quản lý động lực địa hình (cỏ dài, bùn, bùn khô, cỏ ngắn, v.v.), chúng ta có thể lặp lại mô hình tương tự. Không có gì ngăn cản bạn nhúng logic như vậy vào địa hình bằng cách trích xuất tất cả các trạng thái địa hình (cỏ dài, cỏ ngắn, bùn, khô, v.v.) vào một FSM địa hình mới với sự chuyển đổi giữa các trạng thái và có lẽ là các quy tắc đơn giản. Ví dụ, để đến trạng thái bùn, công cụ quy tắc nên kiểm tra bối cảnh để tìm chất lỏng, nếu không thì không thể. Bây giờ GOD đã đơn giản hơn.

Bạn có thể hoàn thành hệ thống của FSM bằng cách làm cho chúng tự chủ và cung cấp cho chúng mỗi luồng. Bước cuối cùng này là không cần thiết nhưng nó cho phép bạn thay đổi linh hoạt hệ thống bằng cách điều chỉnh cách bạn ủy thác việc đưa ra quyết định của mình (khởi chạy một FSM chuyên biệt hoặc chỉ trả về trạng thái được xác định trước).

Hãy nhớ làm thế nào chúng ta đề cập rằng việc chuyển đổi cũng có thể thực hiện "các nhiệm vụ có thể khác"? Hãy khám phá điều đó bằng cách thêm khả năng cho các mô hình khác nhau (FSM) giao tiếp với nhau. Bạn có thể xác định một tập hợp các sự kiện và cho phép mỗi FSM đăng ký người nghe các sự kiện này. Do đó, nếu, ví dụ, một con bò đi vào địa hình hex, hex có thể đăng ký người nghe để thay đổi chuyển tiếp. Ở đây có một chút khó khăn vì mỗi FSM được triển khai ở mức rất cao mà không có bất kỳ kiến ​​thức nào về tên miền cụ thể mà nó chứa. Tuy nhiên, bạn có thể đạt được điều này bằng cách cho bò xuất bản danh sách các sự kiện và tế bào có thể đăng ký nếu nó thấy các sự kiện mà nó có thể phản ứng. Một hệ thống phân cấp tốt của gia đình sự kiện ở đây là một sự đầu tư tốt.

Bạn có thể đẩy sâu hơn nữa bằng cách mô hình hóa mức độ dinh dưỡng và chu kỳ phát triển của cỏ, với ... bạn đoán nó ... một FSM cỏ được nhúng trong mô hình riêng của bản vá địa hình.

Nếu bạn đẩy ý tưởng đủ xa, THIÊN CHÚA có rất ít việc phải làm vì tất cả các khía cạnh đều được quản lý khá nhiều, giải phóng thời gian để dành cho những thứ tin kính hơn.

Tóm tắt

Như đã nêu ở trên, FSM ở đây không phải là giải pháp, chỉ là một phương tiện để minh họa rằng giải pháp cho vấn đề như vậy không được tìm thấy trong mã mỗi lần nói mà là cách bạn mô hình hóa vấn đề của mình. Có nhiều khả năng là các giải pháp khác khả thi và rất có thể tốt hơn nhiều so với đề xuất FSM của tôi. Tuy nhiên, phương pháp "fractals" vẫn là một cách tốt để quản lý khó khăn này. Nếu được thực hiện chính xác, bạn có thể tự động phân bổ các mức sâu hơn, nơi nó quan trọng trong khi đưa ra các mô hình đơn giản hơn, nơi nó ít quan trọng hơn. Bạn có thể xếp hàng thay đổi và áp dụng chúng khi tài nguyên trở nên khả dụng hơn. Trong một chuỗi hành động, việc tính toán chuyển chất dinh dưỡng từ bò sang cỏ có thể không quan trọng lắm. Tuy nhiên, bạn có thể ghi lại các chuyển đổi này và áp dụng các thay đổi sau đó hoặc chỉ gần đúng với phỏng đoán có giáo dục bằng cách thay thế các công cụ quy tắc hoặc có thể thay thế hoàn toàn việc triển khai FSM bằng một phiên bản ngây thơ đơn giản hơn cho các yếu tố không thuộc trường trực tiếp quan tâm (con bò ở đầu kia của lĩnh vực) để cho phép các tương tác chi tiết hơn để có được trọng tâm và chia sẻ tài nguyên lớn hơn. Tất cả điều này mà không bao giờ xem xét lại toàn bộ hệ thống; vì mỗi phần được cách ly tốt, việc tạo ra một thay thế thả vào giới hạn hoặc mở rộng độ sâu của mô hình của bạn trở nên dễ dàng hơn. Bằng cách sử dụng một thiết kế tiêu chuẩn, bạn có thể xây dựng dựa trên đó và tối đa hóa các khoản đầu tư được thực hiện vào các công cụ đặc biệt như DSL để xác định quy tắc hoặc từ vựng chuẩn cho các sự kiện, một lần nữa bắt đầu ở mức rất cao và thêm các sàng lọc khi cần. vì mỗi phần được cách ly tốt, việc tạo ra một thay thế thả vào giới hạn hoặc mở rộng độ sâu của mô hình của bạn trở nên dễ dàng hơn. Bằng cách sử dụng một thiết kế tiêu chuẩn, bạn có thể xây dựng dựa trên đó và tối đa hóa các khoản đầu tư được thực hiện vào các công cụ đặc biệt như DSL để xác định quy tắc hoặc từ vựng chuẩn cho các sự kiện, một lần nữa bắt đầu ở mức rất cao và thêm các sàng lọc khi cần. vì mỗi phần được cách ly tốt, việc tạo ra một thay thế thả vào giới hạn hoặc mở rộng độ sâu của mô hình của bạn trở nên dễ dàng hơn. Bằng cách sử dụng một thiết kế tiêu chuẩn, bạn có thể xây dựng dựa trên đó và tối đa hóa các khoản đầu tư được thực hiện vào các công cụ đặc biệt như DSL để xác định quy tắc hoặc từ vựng chuẩn cho các sự kiện, một lần nữa bắt đầu ở mức rất cao và thêm các sàng lọc khi cần.

Tôi sẽ cung cấp một ví dụ mã nhưng đây là tất cả những gì tôi có thể đủ khả năng để làm ngay bây giờ.


1
Tôi đã chấp nhận câu trả lời này, bởi vì đó là một thứ tự cường độ tốt hơn trong việc giải thích một giải pháp so với các giải pháp khác. Tuy nhiên, tôi có thể thay đổi câu trả lời được chấp nhận của mình nếu câu trả lời tốt hơn xuất hiện. Giải pháp của bạn cũng có vẻ đủ triệt để để tạo sự khác biệt. Mặc dù vậy, tôi vẫn gặp vấn đề trong việc hiểu cách xác định các quy tắc về cách các mô hình khác nhau sẽ tương tác. Bạn có thể làm một ví dụ về điều này?
David

-1 Tôi không thấy lý do tại sao điều này không thể được giải quyết đơn giản thông qua cây quyết định? (kết hợp với DSL lấy mô hình và biến nó thành mã có thể chạy được)?
Đêm tối

14
THIÊN CHÚA vs FSM?
John Cromartie

1
Cây quyết định và công cụ quy tắc được sử dụng trong các trường hợp chính xác khi không có giá trị nội tại để mô hình hóa các khía cạnh trong tay vì chúng chỉ là phương tiện để kết thúc một phép tính. Bạn thấy điều này trong phần mềm chăm sóc sức khỏe mọi lúc. Điều đó đang được nói nếu bạn đang cố gắng mô hình hóa hành vi thực tế, bạn nên thử và làm điều đó. Có rất nhiều trường hợp trong đó logic duy nhất được tìm thấy trong một vấn đề là kết quả của hàng ngàn nếu điều này sau đó là quảng cáo vô hạn. Và nó hợp lệ, đó là lý do tại sao chúng ta có các công cụ để đối phó với điều đó.
xóa_user

1
Điều này đã được chứng minh rất thành công trong thế giới lập trình trò chơi; nhanh hơn và dễ dàng hơn để thay đổi quy tắc hoặc tài sản và để hành vi xuất hiện, sau đó kiểm tra giá trị để quyết định cách hành động theo quy tắc đó.
Ben Leggiero

89

Có vẻ như tất cả các câu lệnh có điều kiện mà bạn đang nói thực sự phải là dữ liệu cấu hình chương trình của bạn chứ không phải là một phần của chính chương trình của bạn. Nếu bạn có thể đối xử với họ theo cách đó, thì bạn sẽ được tự do sửa đổi cách chương trình của bạn hoạt động bằng cách chỉ thay đổi cấu hình của nó thay vì phải sửa đổi mã của bạn và biên dịch lại mỗi khi bạn muốn cải thiện mô hình của mình.

Có rất nhiều cách khác nhau để mô hình hóa thế giới thực, tùy thuộc vào bản chất vấn đề của bạn. Các điều kiện khác nhau của bạn có thể trở thành quy tắc hoặc ràng buộc được áp dụng cho mô phỏng. Thay vì có mã trông như:

if (sunLevel > 0.75) {
   foreach(cow in cows) {
       cow.desireForShade += 0.5;
   }
}
if (precipitation > 0.2) {
   foreach(cow in cows) {
       cow.desireForShelter += 0.8;
   }
}

thay vào đó bạn có thể có mã giống như:

foreach(rule in rules) {
   foreach (cow in cows) {
      cow.apply(rule);
   }
}

Hoặc, nếu bạn có thể phát triển một chương trình tuyến tính mô hình hóa hành vi của con bò với một số đầu vào, mỗi ràng buộc có thể trở thành một dòng trong một hệ phương trình. Sau đó, bạn có thể biến nó thành một mô hình Markov mà bạn có thể lặp lại.

Thật khó để nói cách tiếp cận phù hợp với tình huống của bạn, nhưng tôi nghĩ bạn sẽ có thời gian dễ dàng hơn nhiều nếu bạn coi các ràng buộc của mình là đầu vào cho chương trình của mình chứ không phải mã.


4
Vui lòng mô tả cách "cow.apply (quy tắc);" không hoạt động với tập tin cấu hình?
Kromster

8
@Krom, thật khó để nói một cách cụ thể mà không biết chúng ta đang nói về loại hệ thống nào. Quan điểm của tôi ở trên là coi hàng ngàn điều kiện là đầu vào cho chương trình để bạn không phải viết mã cho từng điều kiện và có thể thay đổi các điều kiện mà không thay đổi chương trình. Nhưng có, nếu các điều kiện có thể được coi là dữ liệu, thì bạn sẽ lưu trữ chúng riêng biệt với chương trình trong một số loại tài liệu hoặc tệp cấu hình.
Caleb

2
@Krom - Đơn giản. Bạn sẽ đọc quy tắc sau đó áp dụng nó cho con bò đã cho.
Ramhound

5
Di chuyển mã để tập tin cấu hình không phải luôn luôn là một cách tiếp cận tốt. Phép thuật rất khó để gỡ lỗi.
Ricky Clarkson

44

Không ai đề cập đến điều này, vì vậy tôi nghĩ rằng tôi muốn nói rõ ràng:

Hàng ngàn quy tắc "Nếu .. Sau đó .. Khác" là dấu hiệu của một ứng dụng được thiết kế tồi.

Mặc dù biểu diễn dữ liệu cụ thể của miền có thể trông giống như các quy tắc này, bạn có chắc chắn rằng việc triển khai của bạn phải giống với biểu diễn cụ thể của tên miền không?


18
Không nhất thiết phải đúng. Có những vấn đề chỉ có thể được giải quyết thông qua những cây quyết định khổng lồ. Nhưng tất nhiên, một giải pháp cho những người bao gồm cây theo nghĩa đen của if-then-other là một thiết kế tồi. Có tồn tại nhiều cách linh hoạt và duy trì để làm điều này.
SF.

43
Tôi nghĩ rằng đó là điểm của câu hỏi. OP có một vấn đề cụ thể đối với miền của anh ta, trong một triển khai ngây thơ, sẽ cần hàng ngàn nếu ... thì ... khác. Ông có một trực giác rằng điều này sẽ gây rắc rối và hỏi cộng đồng ở đây về những cách tốt hơn để làm điều này. Thực tế câu hỏi đã được hỏi là một bài hát hay mà điều này đã được hiểu, câu trả lời của bạn, mặc dù đúng, không giúp ích gì trong câu hỏi.
Newtopian

@Newtopian Một người dùng hoặc lập trình viên tiên tiến sẽ hiểu điều đó và coi đó là điều hiển nhiên. Một người dùng hoặc lập trình viên ngây thơ có thể không nhận ra điều đó, mặc dù. Tôi cố ý tuyên bố những gì hầu hết mọi người ở đây đều tỏ ra rõ ràng - tôi đã xác nhận rằng OP là chính xác trong giả định của anh ta rằng điều này sẽ có vấn đề, và chắc chắn không nên đi với việc thực hiện ngay lập tức hoặc ngây thơ.
blueberryfields

Tôi đồng ý, bạn có thể thay thế nếu khác bằng đa hình cũng như DI. Nếu bạn có vô số nếu khác, thiết kế của bạn là hoàn toàn xấu.
DarthVader

17

Xin vui lòng, sử dụng phần mềm / ngôn ngữ máy tính phù hợp cho nhiệm vụ. Matlab được sử dụng rất thường xuyên để mô hình hóa các hệ thống phức tạp, nơi bạn thực sự có thể có hàng ngàn điều kiện. Không sử dụng mệnh đề if / then / other, nhưng bằng phân tích số. R là một ngôn ngữ máy tính nguồn mở chứa đầy các công cụ và gói để làm tương tự. Nhưng điều này có nghĩa là bạn cũng phải điều chỉnh lại mô hình của mình bằng các thuật ngữ toán học hơn, do đó bạn có thể bao gồm cả những ảnh hưởng chính và tương tác giữa các ảnh hưởng trong các mô hình.

Nếu bạn chưa có, xin vui lòng theo một khóa học về mô hình hóa và mô phỏng. Điều cuối cùng bạn nên làm, là xem xét việc viết một mô hình như thế về mặt nếu - thì - khác. Chúng tôi có chuỗi montov carlo markov, máy vectơ hỗ trợ, mạng lưới thần kinh, phân tích biến tiềm ẩn, ... Xin đừng tự quay lại 100 năm bằng cách bỏ qua sự giàu có trên các công cụ mô hình hóa mà bạn có.


Tôi ngạc nhiên khi câu hỏi này được chú ý rất ít. Phân tích và mô hình số là một cỗ máy if-if. Tuy nhiên, nó bị các lỗi tích cực sai có thể không được dung thứ nếu việc tuân thủ nghiêm ngặt các quy tắc là cần thiết cho ứng dụng. (Nghĩ đến ngân hàng)
Arun Jose

13

Các công cụ quy tắc có thể hữu ích vì nếu có rất nhiều if / then quy tắc, có thể hữu ích để đưa tất cả chúng vào một nơi bên ngoài chương trình nơi người dùng có thể chỉnh sửa chúng mà không cần biết ngôn ngữ lập trình. Ngoài ra, các công cụ trực quan có thể có sẵn.

Bạn cũng có thể xem xét các giải pháp lập trình logic (như Prolog). Bạn có thể nhanh chóng sửa đổi danh sách các câu lệnh if / then và để nó thực hiện những việc như xem liệu bất kỳ sự kết hợp đầu vào nào sẽ dẫn đến một số kết quả nhất định, v.v. mã hướng đối tượng).


11

Nó chợt nhận ra tôi:

Bạn cần sử dụng Cây học quyết định (Thuật toán ID3).

Rất có khả năng đó là ai đó đã thực hiện nó bằng ngôn ngữ của bạn. Nếu không bạn có thể chuyển một thư viện hiện có


Đi với ý tưởng DSL được đưa ra ở trên. Cố gắng tìm ra cách trừu tượng hóa vấn đề thành một dạng Đại số tượng trưng, ​​sau đó thực hiện điều đó.
Zachary K

11

Đây là nhiều hơn một câu trả lời wiki cộng đồng, tổng hợp các công cụ mô hình hóa khác nhau được đề xuất bởi các câu trả lời khác, tôi vừa thêm các liên kết bổ sung vào tài nguyên.

Tôi không nghĩ rằng có bất kỳ nhu cầu nào để nhắc lại rằng bạn nên sử dụng một cách tiếp cận khác với hàng ngàn câu lệnh if / other được mã hóa cứng.


9

Mỗi ứng dụng lớn chứa hàng ngàn if-then-elsecâu lệnh, không kể các điều khiển luồng khác và các ứng dụng đó vẫn được gỡ lỗi và duy trì, mặc dù độ phức tạp của chúng.

Ngoài ra, số lượng báo cáo không làm cho dòng chảy không thể đoán trước . Lập trình không đồng bộ nào. Nếu bạn sử dụng thuật toán xác định một cách đồng bộ, bạn sẽ có hành vi có thể dự đoán 100% mọi lúc.

Bạn có lẽ nên giải thích rõ hơn những gì bạn đang cố gắng thực hiện trên Stack Overflow hoặc Code Review để mọi người có thể đề xuất cho bạn các kỹ thuật tái cấu trúc chính xác để sử dụng. Bạn cũng có thể muốn hỏi những câu hỏi chính xác hơn, như "Làm thế nào để tôi tránh lồng nhau quá nhiều ifcâu lệnh <được đưa ra một đoạn mã>".


1
Hầu hết các ứng dụng có 2-3 cấp độ lồng và điều kiện 1 dòng. Điều gì về một vấn đề đòi hỏi một cây quyết định lồng xuống 50 cấp độ, và nhiều điều kiện là các hợp chất logic của 30 biến trở lên mỗi biến?
SF.

Mặc dù "Mọi ứng dụng lớn ..." chắc chắn là đúng, nhưng khá rõ ràng rằng OP đang nói về chuỗi dài các biểu thức điều kiện về cơ bản tạo thành các quy tắc trong một mô hình. Các nhóm ifbáo cáo lồng nhau rất lớn nhanh chóng trở nên khó sử dụng, vì vậy cần có cách tiếp cận tốt hơn.
Caleb

@Caleb: bạn nói đúng, thì rõ ràng hiện nay , với ví dụ chính xác ngay từ đầu của câu hỏi. Đó không phải là trước khi câu hỏi được chỉnh sửa khi tôi viết câu trả lời của mình. Điều này giải thích sự không phù hợp thực tế của tôi và hai câu trả lời khác được đăng cùng một lúc.
Arseni Mourzenko

2

Làm cho ứng dụng của bạn có thể quản lý bằng cách thiết kế nó tốt. Thiết kế ứng dụng của bạn bằng cách tách logic kinh doanh khác nhau thành các lớp / mô-đun riêng biệt. Viết các bài kiểm tra đơn vị kiểm tra từng lớp / mô-đun riêng lẻ. Điều này rất quan trọng và sẽ giúp bạn đảm bảo rằng logic kinh doanh được triển khai như mong đợi.


2

Có lẽ sẽ không có một cách duy nhất để thiết kế giải quyết vấn đề của bạn, nhưng bạn có thể quản lý sự phức tạp của từng mảnh nếu bạn cố tách ra các khu vực khác nhau nơi bạn thấy mình viết các khối lớn nếu phát biểu và áp dụng các giải pháp cho mỗi vấn đề nhỏ hơn

Nhìn vào các kỹ thuật như các quy tắc được nói đến trong Tái cấu trúc để tìm cách chia các điều kiện lớn thành các phần có thể quản lý - ví dụ, nhiều lớp với giao diện chung có thể thay thế một câu lệnh tình huống.

Thoát sớm là một trợ giúp lớn, quá. Nếu bạn có các điều kiện lỗi, hãy đưa chúng ra khỏi đầu khi bắt đầu hàm bằng cách ném một ngoại lệ hoặc trả về thay vì để chúng lồng lên.

Nếu bạn chia các điều kiện của mình thành các hàm vị ngữ, việc theo dõi chúng có thể dễ dàng hơn. Ngoài ra, nếu bạn có thể đưa chúng vào dạng chuẩn, có thể đưa chúng vào cấu trúc dữ liệu được xây dựng linh hoạt, thay vì dạng mã hóa cứng.


2

Tôi sẽ đề nghị bạn sử dụng một công cụ quy tắc. Trong trường hợp Java, jBPM hoặc Oracle BPM có thể hữu ích. Các công cụ quy tắc về cơ bản cho phép bạn định cấu hình ứng dụng thông qua XML.


+1 Tôi đã sử dụng Drools gần đây cùng với Mvel là ngôn ngữ để thể hiện các quy tắc và đó chính xác là những gì bạn đang tìm kiếm. Mặc dù thực tế là nó rất nhanh.
Jalayn

Thuốc nhỏ là một lựa chọn tốt. Cá nhân tôi đang sử dụng Oracle BPM ngay bây giờ. Ngoài ra còn có Feugo. Rất nhiều công cụ mã nguồn mở và quyền sở hữu có sẵn.
Sid

2

Vấn đề không phải là giải quyết tốt bằng "quy tắc", cho dù được mô tả bằng mã thủ tục "nếu-thì" hoặc nhiều giải pháp quy tắc được đưa ra cho các ứng dụng kinh doanh. Học máy cung cấp một số cơ chế để mô hình hóa các kịch bản như vậy.

Về cơ bản, người ta phải xây dựng một số sơ đồ để biểu diễn các yếu tố (ví dụ: mặt trời, gió, nguồn thức ăn, các sự kiện bất ngờ, v.v.) ảnh hưởng đến "hệ thống" (tức là những con bò trên đồng cỏ). Mặc dù có niềm tin sai lầm rằng người ta có thể tạo ra một đại diện chức năng có giá trị thực sự, trái ngược với sự rời rạc, không có máy tính nào trong thế giới thực (bao gồm cả hệ thần kinh của con người) là giá trị thực dựa trên các giá trị thực.

Khi bạn có biểu diễn bằng số cho các yếu tố liên quan, bạn có thể xây dựng bất kỳ mô hình toán học nào. Tôi sẽ đề xuất một biểu đồ lưỡng cực trong đó một tập hợp các nút đại diện cho bò và một số đơn vị diện tích đồng cỏ khác. Một con bò tại bất kỳ trường hợp nào chiếm một số đơn vị diện tích đồng cỏ. Đối với mỗi con bò sau đó tồn tại một giá trị tiện ích liên quan đến hiện tại và tất cả các đơn vị đồng cỏ khác. Nếu mô hình giả định con bò tìm cách tối ưu hóa (bất cứ thứ gì có nghĩa là con bò) thì giá trị tiện ích của đơn vị đồng cỏ của nó, sau đó bò sẽ chuyển từ đơn vị này sang đơn vị khác để nỗ lực tối ưu hóa.

Một thiết bị tự động di động hoạt động tốt để thực hiện mô hình. Toán học cơ bản trong thế giới toán học có giá trị thực sự thúc đẩy chăn bò là một mô hình gradient trường. Bò chuyển từ các vị trí có giá trị tiện ích thấp hơn nhận thức sang vị trí có giá trị tiện ích cao hơn nhận thức.

Nếu một người tiêm thay đổi môi trường vào hệ thống thì nó sẽ không chuyển sang một giải pháp ổn định về định vị bò. Nó cũng sẽ trở thành một mô hình mà các khía cạnh của lý thuyết trò chơi có thể được áp dụng; không phải như vậy sẽ nhất thiết phải thêm nhiều vào trường hợp này.

Lợi thế ở đây là giết mổ bò hoặc mua bò mới có thể được quản lý dễ dàng bằng cách trừ và thêm các ô "bò" vào biểu đồ lưỡng cực, trong khi mô hình đang chạy.


1

Tôi không nghĩ bạn nên định nghĩa nhiều câu lệnh if-other. Theo quan điểm của tôi, vấn đề của bạn có nhiều thành phần:

  • Nó nên không đồng bộ hoặc đa luồng, bởi vì bạn có nhiều con bò với tính cách khác nhau, cấu hình khác nhau. Mỗi con bò tự hỏi mình nên đi theo hướng nào trước khi di chuyển tiếp theo. Theo tôi, mã đồng bộ là một công cụ kém cho vấn đề này.

  • Cấu hình của cây quyết định liên tục thay đổi. Nó phụ thuộc vào vị trí của con bò thực tế, thời tiết, thời gian, địa hình, vv ... Thay vì xây dựng một khu phức hợp if-else cây, tôi nghĩ chúng ta nên giảm bớt vấn đề để một gió tăng hoặc một hướng - Chức năng cân : Hình 1 hình 1 - hàm hướng - trọng số cho một số quy tắc

    Con bò phải luôn luôn đi về hướng có trọng lượng tổng lớn nhất. Vì vậy, thay vì xây dựng một cây quyết định lớn, bạn có thể thêm một bộ quy tắc (với các hàm trọng lượng - hướng khác nhau) cho mỗi con bò và chỉ cần xử lý kết quả theo mỗi lần bạn hỏi hướng. Bạn có thể cấu hình lại các quy tắc đó bằng mọi thay đổi vị trí hoặc bằng cách chuyển thời gian hoặc bạn có thể thêm các chi tiết này làm tham số, mọi quy tắc sẽ nhận được. Đó là một quyết định thực hiện. Cách đơn giản nhất để có được một hướng, để thêm một vòng lặp đơn giản từ 0 ° đến 360 ° với bước 1 °. Sau đó, bạn có thể đếm tổng trọng lượng của mỗi hướng 360 và chạy qua hàm max () để có hướng thích hợp.

  • Bạn không nhất thiết cần một mạng lưới thần kinh để làm điều này, chỉ cần một lớp cho mỗi quy tắc, một lớp cho bò, có thể cho địa hình, v.v ... và một lớp cho kịch bản (ví dụ 3 con bò với các quy tắc khác nhau & 1 địa hình cụ thể). Hình 2 Hình 2 - các nút và kết nối không đồng bộ của ứng dụng bò

    • màu đỏ cho hướng nhắn tin - bản đồ trọng lượng thông qua các quy tắc
    • màu xanh cho định hướng và cập nhật vị trí sau khi ra quyết định
    • màu xanh lá cây để cập nhật đầu vào sau khi cập nhật định hướng và vị trí
    • màu đen để nhận đầu vào

    lưu ý: có thể bạn sẽ cần một khung nhắn tin để thực hiện một cái gì đó như thế này

    Vì vậy, nếu làm cho việc học bò không phải là một phần của vấn đề của bạn, bạn không cần một mạng lưới thần kinh hoặc thuật toán di truyền. Tôi không phải là chuyên gia về AI, nhưng tôi đoán nếu bạn muốn điều chỉnh những con bò của mình thành người thật, thì bạn có thể làm điều đó đơn giản với một thuật toán di truyền và bộ quy tắc phù hợp. Nếu tôi hiểu rõ, bạn cần một đàn bò với các thiết lập quy tắc ngẫu nhiên. Sau đó, bạn có thể so sánh hành vi của những con bò thật với hành vi của quần thể người mẫu của bạn và giữ 10% đi theo con đường gần nhất với những con bò thật. Sau đó, bạn có thể thêm các ràng buộc cấu hình quy tắc mới cho nhà máy sản xuất bò của mình dựa trên 10% bạn giữ và thêm bò ngẫu nhiên mới vào dân số, v.v., cho đến khi bạn có một con bò mô hình hoạt động giống như con bò thật ...


0

Tôi muốn nói thêm rằng đó có thể là trường hợp nếu bạn thực sự có hàng ngàn NẾU ... THÌ bạn có thể bị bội thực. Để biết giá trị của nó, các cuộc thảo luận về mô hình mạng nơ-ron mà tôi tham dự thường bắt đầu bằng cách nói với "một bộ quy tắc đơn giản", chúng có thể tạo ra hành vi phù hợp thực tế khá phức tạp và hợp lý (trong những trường hợp đó là các nơ-ron thực tế hoạt động). Vì vậy, bạn có chắc chắnBạn cần hàng ngàn điều kiện? Ý tôi là, ngoài 4-5 khía cạnh của thời tiết, vị trí của nguồn thức ăn, sự kiện bất ngờ, chăn gia súc và địa hình, bạn có thực sự sẽ có nhiều biến số hơn không? Chắc chắn, nếu bạn đã cố gắng thực hiện tất cả các hoán vị có thể có của việc kết hợp các điều kiện đó, thì bạn có thể dễ dàng có hàng ngàn quy tắc, nhưng đó không phải là phương pháp đúng. Có thể cách tiếp cận kiểu logic mờ trong đó các yếu tố khác nhau đưa ra sự thiên vị trên từng vị trí của con bò kết hợp với quyết định chung sẽ cho phép bạn thực hiện điều này trong ít quy tắc hơn.

Tôi cũng đồng ý với mọi người rằng bộ quy tắc nên tách biệt với dòng mã chung, để bạn có thể dễ dàng điều chỉnh nó mà không thay đổi chương trình. Bạn thậm chí có thể đưa ra các bộ quy tắc cạnh tranh và xem cách chúng chống lại dữ liệu di chuyển bò thật. Nghe có vẻ vui.


0

Expert Systems đã được đề cập, đó là một lĩnh vực của AI. Để mở rộng một chút về những điều này, đọc lên Công cụ suy luận có thể giúp bạn với điều này. Một tìm kiếm Google có thể được sử dụng nhiều hơn - viết DSL là phần dễ dàng, bạn có thể thực hiện việc này một cách tầm thường với trình phân tích cú pháp như Gold Parser. Phần khó khăn đến từ việc xây dựng cây quyết định của bạn và chạy hiệu quả qua chúng.

Nhiều hệ thống y tế đã sử dụng các động cơ này, ví dụ trang web NHS Direct của Vương quốc Anh .

Nếu bạn là .NET'er thì Infer.NET có thể hữu ích cho bạn.


0

Vì bạn nhìn vào chuyển động của con bò, chúng bị mắc kẹt theo hướng 360 độ (bò không thể bay.) Bạn cũng có một tỷ lệ rằng việc bạn đi du lịch. Điều này có thể được định nghĩa là một vector.

Bây giờ làm thế nào để bạn đối phó với những thứ như vị trí mặt trời, độ dốc của ngọn đồi, tiếng ồn lớn?

Mỗi độ sẽ là một biến số biểu thị mong muốn đi theo hướng đó. Nói một cái búng vào bên phải của con bò ở 90 độ (giả sử con bò phải đối mặt với 0 độ). Mong muốn đi bên phải sẽ đi xuống và mong muốn đi 270 (trái) sẽ tăng lên. Đi qua tất cả các kích thích thêm hoặc bớt ảnh hưởng của chúng đối với những con bò mong muốn đi theo một hướng. Một khi tất cả các kích thích được áp dụng, con bò sẽ đi theo hướng ham muốn cao nhất.

Bạn cũng có thể áp dụng độ dốc để các kích thích không phải là nhị phân. Ví dụ, một ngọn đồi không thẳng lên theo một hướng. Có lẽ con bò đang ở trong một thung lũng hoặc trên một con đường trên một ngọn đồi bằng phẳng thẳng về phía trước, ở ngọn đồi nhẹ 45 * ở ngọn đồi nhẹ 90 *. Ở 180 * dốc lên đồi.

Sau đó, bạn có thể điều chỉnh trọng lượng của một sự kiện và hướng ảnh hưởng của nó. Thay vào đó là một danh sách nếu thens, bạn có một bài kiểm tra tìm max. Ngoài ra, khi bạn muốn thêm một kích thích, bạn chỉ cần áp dụng nó trước khi thử nghiệm và bạn không phải đối phó với việc thêm nhiều hơn và phức tạp hơn.

Thay vào đó, nói rằng con bò sẽ đi theo bất kỳ hướng 360 nào, hãy chia nó thành 36 hướng. Mỗi độ 10 độ

Thay vào đó, nói rằng con bò sẽ đi theo bất kỳ hướng 360 nào, hãy chia nó thành 36 hướng. Mỗi người 10 độ. Tùy thuộc vào mức độ cụ thể bạn cần phải được.


-2

Sử dụng OOP. Làm thế nào về việc tạo ra một loạt các lớp xử lý các điều kiện cơ bản và chạy các phương thức ngẫu nhiên để mô phỏng những gì bạn đang làm.

Nhận một lập trình viên để giúp đỡ.

class COW_METHODS {

    Function = array('Action1','Action2',....'ActionX');

    function doAction() {
       execute(Function[random(1,5000]);
    }

    function execute(DynamicFunction) {
        exec(DynamicFunction());
    }

    Function Action1() {
        turnRight();
        eatGrass();
    }
    /*  keep adding functions for COW Methods ...  etc  */
    /*  and add classes for conditions inherit them as needed  */
    /*  keep an object to define conditions =  Singleton etc.  */
}

Tại sao đây là câu trả lời cuối cùng. Nó đạt đến điểm, đó là hàng ngàn câu lệnh khác nếu bây giờ chỉ đơn giản là cách để thiết kế một chương trình.
wfbarksdale

1
Bởi vì khuyến nghị " Sử dụng OOP. Hãy nhờ một lập trình viên giúp đỡ. " Cũng giống như đưa ra lời khuyên " Thực hiện nhiều cuộc gọi điện thoại hơn! " Khi được hỏi " Làm cách nào tôi có thể tăng gấp bốn lần doanh số của mình? ". Nó không hoàn toàn sai, nhưng nó cũng không giúp được gì nhiều.
JensG

2
Tôi đánh giá thấp, bởi vì đây là một câu trả lời xấu. Về mặt kỹ thuật; câu trả lời của bạn ít liên quan đến OOP. Một lớp được gọi COW_METHODSdường như không có gì khác hơn là một tập hợp các phương thức liên quan lỏng lẻo. Đâu là sự tách biệt của mối quan tâm? Liên quan đến câu hỏi, làm thế nào điều này giúp người hỏi?
oɔɯǝɹ
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.