Làm cách nào để phân loại vấn đề tối ưu hóa đầu vào trình giả lập của tôi và tôi nên tiếp cận với thuật toán nào?


10

Do tính chất của câu hỏi, tôi phải bao gồm nhiều thông tin cơ bản (vì câu hỏi của tôi là: làm thế nào để thu hẹp điều này?) Điều đó nói rằng, nó có thể được tóm tắt (theo hiểu biết tốt nhất của tôi) như:

Phương pháp nào tồn tại để tìm tối ưu cục bộ trên các không gian tìm kiếm kết hợp cực lớn?

Lý lịch

Trong cộng đồng superplay được hỗ trợ bởi công cụ, chúng tôi mong muốn cung cấp đầu vào được chế tạo đặc biệt (không được tạo trong thời gian thực) cho bảng điều khiển hoặc trình giả lập trò chơi video để giảm thiểu chi phí (thường là hoàn thành thời gian). Cách này hiện đang được thực hiện là bằng cách chơi các trò chơi frame-by-frame và xác định đầu vào cho mỗi khung hình, thường làm lại các bộ phận của chạy nhiều lần (ví dụ, công bố gần đây chạy cho The Legend of Zelda: Ocarina of Time có tổng cộng 198.590 lần thử lại).

Làm cho các hoạt động này có được mục tiêu của họ thường đi xuống hai yếu tố chính: lập kế hoạch tuyến đường và đi qua. Cái trước là "sáng tạo" hơn nhiều so với cái trước.

Lập kế hoạch lộ trình là xác định cách người chơi nên điều hướng tổng thể để hoàn thành trò chơi và thường là phần quan trọng nhất của hoạt động. Điều này tương tự với việc chọn phương pháp sắp xếp nào sẽ sử dụng, ví dụ. Loại bong bóng tốt nhất trên thế giới đơn giản là sẽ không vượt trội hơn loại sắp xếp nhanh trên 1 triệu yếu tố.

Tuy nhiên, trong mong muốn cho sự hoàn hảo, việc đi qua (cách thức thực hiện tuyến đường) cũng là một yếu tố rất lớn. Tiếp tục tương tự, đây là cách thuật toán sắp xếp được thực hiện. Một số tuyến thậm chí không thể được thực hiện mà không có khung đầu vào rất cụ thể. Đây là quá trình hỗ trợ công cụ tẻ nhạt nhất và là điều khiến cho việc sản xuất một hoạt động hoàn thành phải mất hàng tháng hoặc thậm chí nhiều năm. Đó không phải là một quá trình khó khăn (với con người) vì phải thử các biến thể khác nhau của cùng một ý tưởng cho đến khi một ý tưởng được coi là tốt nhất, nhưng con người chỉ có thể thử rất nhiều biến thể trong khoảng chú ý của họ. Việc áp dụng máy móc cho nhiệm vụ này có vẻ thích hợp ở đây.

Mục tiêu của tôi bây giờ là cố gắng tự động hóa quá trình truyền tải nói chung cho hệ thống Nintendo 64 . Không gian tìm kiếm cho vấn đề này là xa quá lớn để tấn công với một cách tiếp cận brute-force. Một phân đoạn khung n của một lần chạy N64 có 2 30n đầu vào có thể, nghĩa là chỉ 30 khung hình đầu vào (một giây ở 30FPS) có 2 900 đầu vào có thể; sẽ không thể kiểm tra các giải pháp tiềm năng này, chứ đừng nói đến những giải pháp đó trong hai giờ.

Tuy nhiên, tôi không quan tâm đến việc thử (hay đúng hơn, thậm chí sẽ không cố gắng) tổng tối ưu hóa toàn cầu của một hoạt động đầy đủ. Thay vào đó, tôi muốn, đưa ra một đầu vào ban đầu, xấp xỉ tối ưu cục bộ cho một phân đoạn cụ thể của hoạt động (hoặc tối ưu n địa phương gần nhất , cho một loại tối ưu hóa toàn cầu) . Đó là, đưa ra một tuyến đường và một tuyến đường ban đầu của tuyến đường đó: tìm kiếm các hàng xóm của tuyến đường đó để giảm thiểu chi phí, nhưng không suy thoái trong việc thử tất cả các trường hợp có thể giải quyết vấn đề.

Do đó, chương trình của tôi nên có trạng thái bắt đầu, luồng đầu vào, chức năng đánh giá và xuất tối ưu cục bộ bằng cách giảm thiểu kết quả đánh giá.

Tình trạng hiện tại

Hiện tại tôi có tất cả các khung chăm sóc. Điều này bao gồm đánh giá một luồng đầu vào thông qua thao tác của trình giả lập, thiết lập và phá vỡ, cấu hình, v.v. Và như một trình giữ chỗ của các loại, trình tối ưu hóa là một thuật toán di truyền rất cơ bản. Nó chỉ đơn giản là đánh giá một quần thể các luồng đầu vào, lưu trữ / thay thế người chiến thắng và tạo ra một quần thể mới bằng cách thay đổi luồng chiến thắng. Quá trình này tiếp tục cho đến khi một số tiêu chí tùy ý được đáp ứng, như thời gian hoặc số thế hệ.

Lưu ý rằng phần chậm nhất của chương trình này sẽ là đánh giá luồng đầu vào . Điều này là do điều này liên quan đến việc mô phỏng trò chơi cho n khung hình. (Nếu tôi có thời gian tôi sẽ viết trình giả lập của riêng mình, cung cấp các hook cho loại công cụ này, nhưng bây giờ tôi còn lại để tổng hợp tin nhắn và sửa đổi bộ nhớ cho trình giả lập hiện có từ một quy trình khác.) là khá hiện đại, đánh giá 200 khung hình mất khoảng 14 giây. Như vậy, tôi thích một thuật toán (được lựa chọn) để giảm thiểu số lượng đánh giá hàm.

Tôi đã tạo một hệ thống trong khung quản lý đồng thời các trình giả lập. Như vậy tôi có thể đánh giá một số luồng cùng một lúc theo thang hiệu suất tuyến tính, nhưng thực tế, số lượng trình giả lập đang chạy chỉ có thể là 8 đến 32 (và 32 thực sự đang đẩy nó) trước khi hiệu năng hệ thống suy giảm. Điều này có nghĩa (được đưa ra lựa chọn), một thuật toán có thể xử lý trong khi đánh giá đang diễn ra sẽ rất có lợi, bởi vì trình tối ưu hóa có thể thực hiện một số công việc nặng trong khi chờ đánh giá.

Như một thử nghiệm, chức năng đánh giá của tôi (đối với trò chơi Banjo Kazooie ) là tính tổng, trên mỗi khung hình, khoảng cách từ người chơi đến điểm mục tiêu. Điều này có nghĩa là giải pháp tối ưu là đến càng gần điểm đó càng nhanh càng tốt. Hạn chế đột biến chỉ với thanh analog, phải mất một ngày để có được một giải pháp ổn . (Đây là trước khi tôi triển khai đồng thời.)

Sau khi thêm đồng thời, tôi kích hoạt tính năng đột biến của nút A và thực hiện chức năng đánh giá tương tự tại một khu vực yêu cầu nhảy. Với 24 trình giả lập đang chạy, mất khoảng 1 giờ để đạt được mục tiêu từ luồng đầu vào trống ban đầu, nhưng có lẽ sẽ cần phải chạy trong nhiều ngày để đạt được bất cứ điều gì gần với tối ưu.

Vấn đề

Vấn đề tôi gặp phải là tôi không biết đủ về lĩnh vực tối ưu hóa toán học để biết cách mô hình hóa đúng vấn đề tối ưu hóa của mình ! Ví dụ, tôi có thể theo ý tưởng khái niệm của nhiều thuật toán như được mô tả trên Wikipedia, nhưng tôi không biết cách phân loại vấn đề của mình hoặc chọn thuật toán tiên tiến cho danh mục đó.

Từ những gì tôi có thể nói, tôi có một vấn đề kết hợp với một khu phố cực kỳ lớn . Trên hết, chức năng đánh giá cực kỳ không liên tục, không có độ dốc và có nhiều cao nguyên . Ngoài ra, không có nhiều ràng buộc, mặc dù tôi sẵn sàng thêm khả năng diễn đạt nếu điều đó giúp giải quyết vấn đề; Tôi muốn cho phép chỉ định rằng nút Start không nên được sử dụng, ví dụ, nhưng đây không phải là trường hợp chung.

Câu hỏi

Vì vậy, câu hỏi của tôi là: làm thế nào để tôi mô hình này? Tôi đang cố gắng giải quyết vấn đề tối ưu hóa nào? Tôi nên sử dụng thuật toán nào? Tôi không sợ đọc các tài liệu nghiên cứu vì vậy hãy cho tôi biết những gì tôi nên đọc!

Theo trực giác, một thuật toán di truyền không thể là tốt nhất, bởi vì nó dường như không thực sự học được. Ví dụ: nếu nhấn Start dường như luôn làm cho việc đánh giá trở nên tồi tệ hơn (vì nó tạm dừng trò chơi), cần có một số nhà thiết kế hoặc bộ não học được: "nhấn Bắt đầu tại bất kỳ thời điểm nào là vô ích." Nhưng ngay cả mục tiêu này cũng không tầm thường như âm thanh của nó, bởi vì đôi khi nhấn bắt đầu tối ưu, chẳng hạn như trong cái gọi là "tạm dừng nhảy lùi dài" trong Super Mario 64 ! Ở đây bộ não sẽ phải học một mô hình phức tạp hơn nhiều: "nhấn Bắt đầu là vô ích trừ khi người chơi ở trạng thái rất cụ thể này và sẽ tiếp tục với một số lần nhấn nút ."

Có vẻ như tôi nên (hoặc máy có thể học) thể hiện đầu vào theo một số cách khác phù hợp hơn với sửa đổi. Đầu vào trên mỗi khung hình có vẻ quá chi tiết, bởi vì những gì thực sự cần là "hành động", có thể trải rộng trên nhiều khung hình ... nhưng nhiều khám phá được thực hiện trên cơ sở từng khung hình, vì vậy tôi không thể loại trừ hoàn toàn ( tạm dừng nói trên nhảy lùi đòi hỏi độ chính xác ở mức khung hình). Có vẻ như thực tế là đầu vào được xử lý theo kiểu huyết thanh nên là thứ có thể được viết hoa, nhưng tôi không biết làm thế nào.

Hiện tại tôi đang đọc về Tìm kiếm Tabu (Phản ứng), Tìm kiếm hàng xóm quy mô rất lớn, Tối ưu hóa dựa trên việc dạy học và Tối ưu hóa thuộc địa.

Có phải vấn đề này đơn giản là quá khó để giải quyết với bất cứ điều gì khác ngoài thuật toán di truyền ngẫu nhiên? Hay nó thực sự là một vấn đề tầm thường đã được giải quyết từ lâu? Cảm ơn đã đọc và cảm ơn trước cho bất kỳ câu trả lời.


Bài viết của bạn khá dài, nó sẽ giúp người đọc nếu bạn có một phần ngắn về chủ đề nêu câu hỏi trong điều khoản rõ ràng mà không có thêm thông tin cơ bản.
Kaveh

@Kaveh: Tôi hiểu độ dài của nó, nhưng do bản chất của câu hỏi nên rất khó để thu hẹp, vì tôi hỏi khá nhiều về cách thu hẹp nó. :(

Câu trả lời:


6

Từ thông tin bạn đưa ra trong câu hỏi của bạn, tôi không thể thấy cách áp dụng các phương pháp tối ưu hóa tiêu chuẩn (mà tôi biết). Các đối tượng của bạn không quá phức tạp (nhiều hơn về sau) nhưng chức năng mục tiêu của bạn là một điều khó chịu: các giá trị của nó được xác định bởi một hệ thống bên ngoài ngoài tầm kiểm soát của bạn, không có khả năng có bất kỳ thuộc tính đẹp nào, v.v. Do đó, tôi nghĩ rằng sử dụng thuật toán di truyền không phải là không khả thi và thậm chí có thể là một cách tiếp cận tốt ở đây; chúng thường hoạt động tốt hơn các phương pháp khác nếu bạn không biết gì về cấu trúc vấn đề của mình. Có nhiều điều để xem xét về

  • không gian đối tượng,
  • chức năng mục tiêu và
  • các tham số của thuật toán di truyền của bạn,

cho phép tôi giải thích.

Đối tượng của bạn là gì?

Bạn đã trả lời rằng: bạn đang xem một chuỗi các hành động, mỗi hành động chiếm một khung. Tôi nghĩ rằng điều này có thể là quá tốt hạt; có thể thử một chuỗi các hành động, mỗi hành động có thời lượng (tính theo số khung). Điều này sẽ cho phép có các đột biến như "đi bộ lâu hơn một chút" để có xác suất khác với "chèn một ấn A" một cách tự nhiên. Hãy thử những gì hoạt động tốt nhất; bạn có thể phải xem lại mục này sau khi nghĩ về các thành phần khác.

Chức năng mục tiêu của bạn là gì?

Điều này là thực sự quan trọng. Những gì bạn muốn tối ưu hóa? Thời gian để mục tiêu? Số hành động khác nhau? Số lượng sao thu được? Một sự kết hợp của một số yếu tố? Ngay khi bạn nhận được nhiều mục tiêu, mọi thứ sẽ có lông - ở đó (thường) không còn tối ưu nữa!

Bạn đã đề cập đến thời gian để mục tiêu. Đây có thể không phải là một chức năng mục tiêu tốt ở tất cả. Tại sao? Bởi vì hầu hết các chuỗi thậm chí sẽ không đạt được mục tiêu, vì vậy chúng sẽ kết thúc ở một số hằng số, tạo ra một cảnh quan thể dục như thế này (phác họa khái niệm theo một chiều):

nhập mô tả hình ảnh ở đây
[ nguồn ]

Có những khu vực rộng lớn mà chức năng mục tiêu là . Các thuật toán di truyền là tất cả về tín hiệu : những thay đổi nhỏ trong giải pháp phải chỉ ra sự cải thiện (hoặc suy giảm) về chất lượng nếu và chỉ khi thay đổi đó được "hướng" tới một giải pháp tối ưu (lý tưởng). Nếu đó không phải là trường hợp (quyết liệt), bạn có ít hơn một tìm kiếm ngẫu nhiên, đạt được một giải pháp tốt với xác suất gần . Điều đó có nghĩa gì cho chức năng mục tiêu của chúng tôi? Nó phải là một cái gì đó cải thiện bất cứ khi nào một giải pháp cải thiện một chút, ngay cả khi chất lượng tổng thể vẫn còn thấp . Vậy còn000

11+final distance to goal+11+time to goal

sử dụng "vô cực" làm thời gian cho mục tiêu nếu không đạt được mục tiêu, đó là đặt tổng kết thứ hai thành . Miễn là mục tiêu không đạt được, việc di chuyển gần hơn sẽ tăng thể lực lên . Tất cả các chuỗi đạt được mục tiêu có đường cơ sở là và cải thiện hơn nữa nhanh hơn.1 1011

Vậy làm thế nào để bạn đo khoảng cách? Khoảng cách tuyến tính có thể trông hấp dẫn nhưng có vấn đề của nó; một lần nữa, tín hiệu sai có thể được gửi. Hãy xem xét kịch bản đơn giản này:

nhập mô tả hình ảnh ở đây
[ nguồn ]

Mỗi chuỗi bắt đầu bằng một cú nhảy lên hành lang phía trên sẽ cải thiện cho đến khi nó đạt đến một điểm ngay phía trên mục tiêu, nhưng nó không bao giờ thực sự có thể đạt được mục tiêu! Thậm chí tệ hơn, trong số tất cả các chuỗi không đạt được mục tiêu, những chuỗi tăng lên cũng tốt như những chuỗi đi xuống, vì vậy GA không thể từ chối các chuỗi rõ ràng đã bị tiêu diệt. Nói cách khác, khoảng cách tuyến tính tạo ra tối ưu cục bộ đặc biệt xấu có thể bẫy GA nếu có điểm chết trong cấp độ.

Do đó, tôi khuyên bạn nên phủ một lưới qua cấp độ của mình và kết nối các điểm lân cận nếu nhân vật trò chơi có thể đi từ điểm này sang điểm khác. Sau đó, bạn tính khoảng cách từ mục tiêu theo độ dài của con đường ngắn nhất từ ​​điểm gần nhất đến nơi chuỗi sẽ đưa nhân vật đến điểm gần nhất với mục tiêu. Điều này là dễ dàng để tính toán và đi vào thời hạn (tối ưu cục bộ) ngay lập tức bị trừng phạt¹. Tất nhiên bạn cần truy cập vào dữ liệu cấp độ, nhưng tôi giả sử bạn có những dữ liệu đó.

GA của bạn hoạt động như thế nào?

Bây giờ chúng ta có thể nhận được các thuật toán di truyền thực tế. Các cân nhắc quan trọng là dân số, lựa chọn, sinh sản / đột biến và tiêu chí dừng.

Dân số

Làm thế nào lớn là dân số của bạn sẽ là? Nếu nó quá nhỏ, nó có thể không cung cấp sự đa dạng cần thiết để đạt được một giải pháp tốt. Nếu nó quá lớn, bạn có nhiều khả năng mang theo rác vô dụng, làm chậm quá trình.

Làm thế nào để bạn khởi tạo dân số của bạn? Bạn có chọn chuỗi hành động ngẫu nhiên? Nếu vậy, độ dài nào? Bạn có số lượng (nhỏ) các giải pháp hợp lý được tạo thủ công để tạo hạt giống, có thể như vậy đạt được mục tiêu không?

Lựa chọn

Những cá nhân nào được chọn để sinh tồn / sinh sản? Các tốt nhất? Bạn có tổ chức các giải đấu ? Bạn có quyết định ngẫu nhiên sự sống sót của một cá nhân liên quan đến thể lực của nó không? Bạn có muốn điều tốt nhất để sống sót trong mọi trường hợp hoặc họ có thể chết (có thể hữu ích để rời khỏi tối ưu cục bộ) ² không?k

Khái niệm cốt lõi ở đây là áp lực lựa chọn : khó tồn tại đến mức nào? Làm cho nó quá nhỏ và bạn không loại bỏ các giải pháp tào lao. Làm cho nó quá cao và bạn thực hiện thay đổi (đặc biệt là di chuyển giữa tối ưu cục bộ).

Sinh sản và đột biến

Một khi bạn đã chọn những người sống sót sau một vòng, bạn phải tạo ra thế hệ tiếp theo từ họ (cha mẹ có sống sót và là một phần của thế hệ tiếp theo không?). Có hai chiến lược chính: đột biến và tái tổ hợp.

Đột biến khá rõ ràng, mặc dù các chi tiết cụ thể có thể khác nhau. Đối với mọi vị trí trong chuỗi của một cá nhân, hãy biến đổi nó với một số xác suất. Bạn có thể thực hiện việc này một cách độc lập cho mọi vị trí hoặc chọn ngẫu nhiên số lượng đột biến hoặc bạn có thể thực hiện các đột biến khác nhau với các xác suất khác nhau (chẳng hạn như chèn một yếu tố mới, loại bỏ một yếu tố, thay đổi một, ...). Đột biến thường là về những thay đổi nhỏ .

Tái hợp, kết hợp các khía cạnh của hai hoặc nhiều giải pháp cho một giải pháp mới, khó khăn hơn nhưng có thể cho phép các bước lớn , đó là để lại một "ngọn núi thể dục" và di chuyển trực tiếp đến độ dốc của một giải pháp khác (có thể cao hơn). Một ý tưởng cổ điển là sự giao nhau ; Tôi không biết liệu điều đó có ý nghĩa ở đây hay không (dường như với tôi rằng việc hoán đổi tiền tố của một chuỗi đã cho cho một thứ khác rất có thể sẽ làm giảm giá trị của hậu tố). Có lẽ bạn có thể sử dụng kiến ​​thức về cấp độ và vị trí của nhân vật trong các điểm khác nhau trong chuỗi để hướng dẫn điều này, đó là tạo các điểm giao nhau chỉ khi nhân vật ở cùng một vị trí trong cả hai chuỗi.

Chấm dứt

Khi nào bạn dừng lại Sau thế hệ? Khi thể lực tối đa không được cải thiện kể từ vòng ? Bạn có dừng lại sớm nếu một số thể dục (với chức năng trên, ) không đạt được sau vòng để loại bỏ sớm dân số vô dụng ban đầu?k 1 nNk1n


Như bạn có thể thấy, tất cả những điều này đan xen để ảnh hưởng đến hiệu suất thực tế. Nếu bạn chạy song song nhiều quần thể, bạn thậm chí có thể nghĩ về việc thực hiện trôi dạt di truyền do di cư và / hoặc thảm họa. Có rất ít lý thuyết để hướng dẫn theo cách của bạn, vì vậy bạn phải thử các thiết lập khác nhau và xem nơi nó đưa bạn đến. Hy vọng, những gì làm việc cho một cấp độ cũng sẽ làm việc cho những người khác. Chúc mừng mày mò!

Ghi chú: Hãy nhìn vào BoxCar 2D dưới ánh sáng ở trên. Họ làm một số thứ khá tốt (những thứ khác, không phải vậy) và bạn có thể có được một trực giác về cách các tham số của GA có thể ảnh hưởng đến hiệu suất của nó.


  1. Trên thực tế, xây dựng một chuỗi tham lam sử dụng thể dục này, đó là chọn hành động giảm thiểu khoảng cách đến mục tiêu trong tất cả các hành động tiếp theo có thể, có thể hoạt động khá tốt. Hãy thử điều đó trước khi sử dụng GA!
  2. Tất nhiên, bạn là người quan sát luôn nhớ giải pháp tốt nhất từng gặp.

1
Đẹp! Hai câu hỏi. Điều gì khiến bạn nói rằng (thường) không có tối ưu trong MOO? Các điểm là tối ưu Pareto, nghĩa là bạn không thể cải thiện thứ gì đó mà không phải hy sinh thứ khác. Đưa ra giá trị cho họ là tùy thuộc vào người lập mô hình. Ngoài ra, không phải là đột biến về những thay đổi nhỏ với xác suất nhỏ sao? Với xác suất đột biến lớn, tìm kiếm có xu hướng thực hiện các động tác ngẫu nhiên, không có điều kiện thường làm tổn hại đến hiệu suất. Tôi nghĩ rằng nó đã được quan sát thấy rằng xác suất đột biến nhỏ hoạt động tốt nhất.
Juho

@Juho: 1) Yea, Pareto tối ưu! = Tối ưu. Không muốn đi sâu vào chi tiết về cái đó. 2) Tôi thấy làm thế nào mà tôi có thể hiểu lầm. Tôi có nghĩa là với xác suất cao, những thay đổi nhỏ sẽ xảy ra. 3) Tôi giả sử rằng "xác suất đột biến nhỏ hoạt động tốt nhất" đề cập đến mô hình trong đó mỗi bit được thay đổi độc lập với các bit khác với xác suất (nhỏ), thường là ( độ dài chuỗi). Xác suất đột biến tổng thể là cao và số lượng thay đổi dự kiến ​​là . n 11/nn1
Raphael

Được rồi, tôi hiểu rồi. Về điểm thứ ba, vâng, tôi có ý gì đó chính xác như thế. Cảm ơn!
Juho

Cảm ơn tất cả các thông tin.! Thực sự độc đáo đặt ra câu trả lời làm rõ sự hiểu biết của tôi.
GManNickG

1

Để biết thêm chi tiết về phương pháp tối ưu hóa dựa trên Dạy-học (TLBO) và mã của nó, hãy tham khảo bài viết sau:

Một thuật toán tối ưu hóa dựa trên giảng dạy-học tập tinh hoa để giải quyết các vấn đề tối ưu hóa bị ràng buộc phức tạp của R. Venkata Rao và V. Patel; Tạp chí quốc tế về tính toán kỹ thuật công nghiệp 3 (4): 535 đi560 (2012)

Để đọc thêm:


1
Chào mừng bạn đến với cs.SE, và cảm ơn bạn đã trả lời! Lưu ý rằng bạn có thể sử dụng Markdown để định dạng bài đăng của mình; Tôi đề nghị bạn kiểm tra chỉnh sửa của tôi. Về nội dung, tôi không nghĩ rằng điều này giúp OP dường như muốn biết cách mô hình hóa vấn đề của mình, chứ không phải chi tiết về một kỹ thuật cụ thể. Bên cạnh đó, chỉ có một anh chàng này làm việc trên TLBO?
Raphael
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.