Lập trình di truyền [đóng]


13

Gần đây tôi đã duyệt Reddit và tình cờ thấy một bài đăng liên kết đến một ví dụ "thuật toán di truyền JavaScript". Tôi đã thực sự say mê với các khái niệm về thuật toán di truyền và lập trình, tuy nhiên ngay cả sau khi một số Google, tôi vẫn còn hơi bối rối. Làm thế nào nó hoạt động?

Tôi cho rằng các thuật ngữ từ vựng đang làm tôi bối rối hơn bất cứ điều gì khác. Tôi sẽ đánh giá cao các ví dụ ngắn gọn và có lẽ giải thích. Chỉ là khái niệm về lập trình di truyền và làm thế nào tôi có thể thực hiện nó trong các dự án của mình và tại sao?


1
Có một cuốn sách hay của Mat Buckland có tên là "Kỹ thuật AI cho lập trình trò chơi" ( amazon.com/Techniques-Programming-Premier-Press-Development/dp/ .) Trong đó một nửa cuốn sách bao gồm các thuật toán di truyền. Tiêu đề của cuốn sách là một chút sai lầm, đó là một cuốn sách về GA và Mạng lưới thần kinh. Đó là một giới thiệu tuyệt vời cho chủ đề.
Steven Evers

Câu trả lời:


19

Âm thanh giống như bạn đang nói về Thuật toán di truyền nhiều hơn so với Lập trình di truyền, nhưng đây là đóng góp của tôi cho sự hiểu biết của bạn.


Có thể thuận tiện khi nghĩ về GA về các bộ phận mà chúng được cấu thành.

Vì vậy, hãy nói rằng bạn có một số loại vấn đề. Điều đầu tiên bạn cần là một cách để thể hiện một giải pháp sẽ như thế nào. Nếu bạn gặp vấn đề về nhân viên bán hàng du lịch với các thành phố A, B, C, D, E thì bạn đã biết giải pháp có thể trông như thế nào, một mảng tên của các thành phố [B, C, A, D, E].

Đây là gen .

Mặt khác được gọi là một giải pháp tiềm năng cho vấn đề. Giống như Steven A. Lowe đề cập, chuỗi bit là cách phổ biến để mã hóa gen, nhưng nó không cần thiết; nó chỉ làm cho những thứ nhất định dễ dàng hơn Phần quan trọng là bạn có một cách để thể hiện một giải pháp theo kiểu giống như mảng này.

Hiện nay. Làm thế nào để bạn biết nếu giải pháp là tốt? Bạn cần một chức năng có thể cho bạn biết, và phân loại giải pháp. Vì vậy, một lần nữa tại TSP, bạn có thể có chức năng đo khoảng cách di chuyển bằng đường dẫn [B, C, A, D, E]. 'Lớp' mà bạn chỉ định có thể chỉ đơn giản là quãng đường đã đi nhưng trong những vấn đề phức tạp hơn, bạn có thể bao gồm những thứ như chi phí đi lại và những thứ khác.

Đây là chức năng tập thể dục .

Vì vậy, bây giờ bạn có thể có một giải pháp tiềm năng và tìm hiểu xem nó có tốt không. Cái gì tiếp theo?

Tiếp theo chúng ta cần bắt đầu thế hệ đầu tiên của chúng tôi. Vì vậy, chúng tôi tạo ra một loạt các giải pháp ngẫu nhiên. Không quan trọng họ có tốt hay không. Đây là dân số ban đầu, hoặc hạt giống của bạn. Bạn có thể gọi đây là nhóm gen của bạn.

Vì vậy, bạn lấy nhóm gen ban đầu của bạn và bạn áp dụng chức năng tập thể dục của mình cho tất cả chúng và cho chúng tất cả một lớp. Bây giờ bạn cần phải lấy hai trong số chúng và tạo ra một quần thể mới từ chúng - cho thế hệ tiếp theo. Bạn chọn ai Chà, bạn không nhất thiết chỉ muốn lựa chọn phù hợp nhất, điều đó có thể dẫn đến một số vấn đề. Thay vào đó bạn cần một chức năng lựa chọn .

Một cách để chọn dễ hình dung là sử dụng một loại bánh xe: mỗi gen là một lát cắt trên bánh xe và điểm thể lực của chúng cho biết lát cắt của chúng lớn như thế nào (thể lực càng tốt, lát càng lớn). Đặt ghim chỉ vào bánh xe và quay nó (nghĩa là tạo ra một số ngẫu nhiên). Các pin chỉ vào cha mẹ đầu tiên. Làm lại cho cha mẹ thứ hai.

Bây giờ, bạn cần tạo ra những đứa trẻ mới. Bạn muốn kết hợp cha mẹ để tạo ra một dân số mới. Có nhiều cách khác nhau để làm điều này, nhưng tất cả chúng đều được gọi là chức năng chéo . Bạn có thể chia chúng làm đôi và trao đổi một nửa giữa cha mẹ hoặc thực hiện một số cách xen kẽ. Điều này rất giống với cha mẹ động vật có vú sinh con mới -> cả hai đều đóng góp gen của họ cho đứa trẻ mới.

Một khi bạn có thế hệ mới này, bạn sẽ tạo ra sự đột biến ngẫu nhiên nhưng hiếm gặp cho mỗi đứa trẻ. Tôi thường thấy tỷ lệ đột biến xảy ra ở mức dưới 1%. Hàm đột biến sẽ thay đổi ngẫu nhiên một cái gì đó trong gen được mã hóa của bạn. Nếu gen của bạn là một chuỗi bit, nó có thể hoán đổi một chút, nếu đó là một mảng các thành phố, nó có thể hoán đổi 2 thành phố trong danh sách. Phần quan trọng là nó là một sự xuất hiện tương đối hiếm và trộn lẫn mọi thứ.

Lặp lại quy trình này cho đến khi có số lượng thế hệ mong muốn hoặc cho đến khi chức năng thể dục của bạn tạo ra cha mẹ có điểm thể lực cao liên tục và bạn có một giải pháp (hy vọng, nếu bạn đã làm mọi thứ đúng) tối ưu.


Đó là một chút dài dòng, vì vậy hãy để tôi tóm tắt với một ẩn dụ:

  1. Gen là người: người giải quyết vấn đề
  2. Chức năng thể dục là điểm số: Mọi người đạt điểm dựa trên mức độ họ giải quyết vấn đề
  3. Bạn chọn 2 người để nhân giống một quần thể mới: bạn cho những người có điểm số tốt hơn cơ hội sinh sản tốt hơn
  4. Khi bố mẹ sinh sản, chúng kết hợp để sinh con.
  5. Bạn hiếm khi và ngẫu nhiên đột biến con cái của họ
  6. Bạn học lớp trẻ em của dân số mới
  7. Rửa sạch và lặp lại

Hi vọng điêu nay co ich.


Đây là một lời giải thích tuyệt vời. Tôi luôn nghĩ rằng thuật toán di truyền được mô tả tốt hơn là thuật toán darwinian hoặc thuật toán tiến hóa, nhưng "di truyền" chắc chắn mô tả cơ học tốt hơn (nếu không phải là ý tưởng tổng thể của nó). Tôi sẽ gọi chúng là thuật toán di truyền của Darwin.
Steven Lu

Trò chơi cuộc sống của Conway có phải là một thuật toán di truyền không?
Florian Margaine

@Florian Margaine: Trò chơi cuộc sống là một thiết bị tự động di động, một khái niệm không liên quan (bắt đầu từ thực tế là trò chơi cuộc sống hoàn toàn mang tính quyết định, trong khi GA là ngẫu nhiên).
Scrwtp

1
Đây là lời giải thích tốt nhất về GA mà tôi từng nghe. Tôi đã thấy các thuật toán di truyền được đề cập trong quá khứ nhiều lần, thường là với các khám phá thủ công, nhưng chưa bao giờ thực sự hiểu chúng là gì cho đến bây giờ. Cảm ơn!
Locke

Tôi ước tôi đã thấy lời giải thích này khi tôi mới bắt đầu học GA!
Avrohom Yisroel

7

mã hóa một giải pháp cho một vấn đề dưới dạng chuỗi bit

viết một hàm (được gọi là hàm "thể dục") để đánh giá mức độ "tốt" của giải pháp được mã hóa được cung cấp một chuỗi bit - kết quả thường là một số trong khoảng từ 0 đến 1

tạo ngẫu nhiên một loạt các chuỗi bit này và đánh giá thể lực của chúng

chọn một số bó - thường là những cái phù hợp hơn - và cắt chúng làm đôi và hoán đổi một nửa để tạo ra một số chuỗi bit mới (chéo)

sau đó đôi khi, ngẫu nhiên lật một vài bit trong một số chuỗi bit mới (đột biến)

lặp lại cho đến khi một giải pháp tốt phát triển

Tại sao phải làm điều này: một số vấn đề có không gian giải pháp rất lớn, lớn đến mức việc đánh giá tất cả các khả năng là không thực tế (cf Vấn đề nhân viên bán hàng du lịch)

Tôi đánh giá cao cuốn sách Thuật toán di truyền trong Tìm kiếm, Tối ưu hóa và Học máy


Một tìm kiếm trên Amazon về "Thuật toán di truyền" đã cho tôi bốn trang. Tôi chỉ nhìn vào trang đầu tiên, nhưng không có cuốn sách nào có tiêu đề "Thuật toán di truyền". Bạn có thể cung cấp thêm chi tiết về cuốn sách, chẳng hạn như tiêu đề đầy đủ và tác giả?
David Thornley

Thách thức: trình bày lại câu trả lời như một thuật toán di truyền. [-:
ngớ ngẩn

Liên kết @David được thêm vào; xuất bản năm 1989 vì vậy có thể có những cái tốt hơn bây giờ nhưng cái này đã giải thích mọi thứ tốt
Steven A. Lowe

1
@veryfoolish: trước tiên, hãy đặt lại câu hỏi dưới dạng một giải pháp không gian rời rạc giới hạn
Steven A. Lowe

Các thuật toán di truyền @David cũng có thể là một hoặc hai chương trong một cuốn sách lớn hơn về trí tuệ nhân tạo.
Barry Brown

6

Lập trình di truyền là một cách để máy tính viết chương trình cho bạn!

Đừng nghĩ "chương trình" như MS Word, hãy nghĩ về "chương trình" như sau:

function(x){ return x*2; }

Hàm này (hoặc chương trình), tự nó, không có lý do để tồn tại. Chúng tôi đang tìm kiếm giải pháp cho các vấn đề. Nếu bạn cần tìm tổng của hai số, bạn chỉ cần mở máy tính và làm toán. Có gì nếu ai đó đưa cho bạn bảng sau và hỏi bạn để tìm ra mối quan hệ giữa resultxy:

x   y   result
99  1   (3.02)
79  88   2.01 
21  62   5.01 
84  52  (6.58)
12  70   5.54 
67  18   0.73 

Dữ liệu này là dữ liệu "đào tạo" của bạn. Máy tính của bạn sẽ sử dụng dữ liệu này để tạo ra một số giả thuyết, sau đó bạn sẽ kiểm tra nó dựa trên dữ liệu thực tế.

Giả sử bạn không biết số liệu thống kê và quyết định vấn đề này quá khó để tự mình tìm ra, vì vậy bạn sẽ có máy tính để tìm ra nó cho bạn.

Có máy tính ngẫu nhiên tạo ra các dự đoán hoang dã

Bạn có máy tính tạo ra một triệu câu trả lời và xem liệu có câu nào trong số chúng không (đoán ... một triệu lần!). Sau đây là một ví dụ về một vài dự đoán:

function(x,y){ return x+y; } // wrong
function(x,y){ return x/1*1*1*1*1*1+y; } //wrong, silly

Bạn có thể biết hoặc không biết điều này, nhưng các chức năng hoặc chương trình cũng có thể được biểu diễn dưới dạng cây, ví dụ, chức năng thứ hai sẽ là:

(+ (/ x (* 1 (* 1 (* 1 (* 1 (* 1 1)))) y)

Bạn có thể làm cho nó trông giống như một cái cây bằng cách thụt vào như vậy (btw, tra cứu ký hiệu đánh bóng ngược và cú pháp lisp ... nhưng bạn sẽ hiểu tại sao chúng tôi đại diện cho các chương trình như thế này trong thời gian ngắn):

(+ 
    (/ x 
        (* 1 
            (* 1 
                (* 1 
                    (* 1 
                        (* 1 1)))) 
    y)

( +ở trên cùng với hai "lá" /y. /Bản thân nó có nhiều con, v.v.)

Đây là lý do tại sao bạn đọc rất nhiều về "cây" trong lập trình di truyền. Trong mọi trường hợp, chúng tôi cắm các giá trị của xyvào hàm này và nó cho chúng ta câu trả lời SAU. Không có gì đáng ngạc nhiên vì chúng tôi ngẫu nhiên tạo ra điều này.

Bây giờ bạn quyết định tạo ra một triệu giải pháp như vậy. Tất cả đều sai. Tuy nhiên, bạn nhận thấy rằng một số câu trả lời gần với câu trả lời đúng hơn những câu trả lời khác. Nói cách khác, một số giải pháp "phù hợp" hơn những giải pháp khác. Lưu ý rằng máy tính không biết "đúng" và "sai" là gì, do đó bạn phải cung cấp "chức năng thể dục" của riêng mình. Chức năng này được trao một giải pháp tiềm năng, dữ liệu đào tạo và chịu trách nhiệm cho hệ thống GP biết mức độ "phù hợp" của giải pháp này. Như bạn có thể tưởng tượng, chức năng này được chạy hàng triệu lần.

Điều gì làm cho GP khác biệt

Đây là những gì làm cho lập trình di truyền khác với dự đoán hoang dã. Bạn quyết định thực hiện một vòng triệu lần đoán khác; tuy nhiên, bạn làm điều đó thông minh hơn một chút. Bạn lấy 10% dự đoán hàng đầu (những dự đoán gần với giá trị thực) và biến chúng thành một phần của thế hệ thứ hai. Bạn cũng thực hiện nhiều giải pháp này (có thể là 10% giống nhau ... tôi không nhớ) và quyết định "trộn chúng lại".

Bạn chọn ngẫu nhiên hai giải pháp, chọn ngẫu nhiên các cây con và bắt đầu hoán đổi chúng. Vì vậy, một phần của giải pháp A kết thúc theo giải pháp B và ngược lại - bạn chỉ cần "vượt qua" chúng. Bạn cũng thực hiện một số giải pháp và chỉ đơn giản là "biến đổi" chúng ... lấy một số cây con và 'vặn nó lên' một chút (hey, nếu giải pháp đó tồi tệ, 'vặn vẹo nó không vì lý do gì' thực sự có thể cải thiện nó).

Một cách nghĩ tốt về điều này là như sau: mẹ và bố bạn có những thuộc tính nhất định - màu tóc, chiều cao, khả năng mắc bệnh, v.v ... Bạn, khi còn nhỏ, thừa hưởng những thuộc tính khác nhau từ cả bố và mẹ. Nếu cả hai cha mẹ bạn đều là vận động viên olympic, bạn cũng sẽ là một vận động viên siêu hạng, phải không? Vâng, các nhà sinh học, nhà xã hội học và thậm chí các nhà sử học có thể có vấn đề với ý tưởng này, nhưng các nhà khoa học máy tính không quan tâm đến đạo đức của thuyết ưu sinh ở đây. Họ chỉ thấy một "hệ thống" làm một công việc khá tốt cung cấp giải pháp, vì vậy họ quyết định mô hình hóa nó trong phần mềm.

Nếu nó không thực sự phù hợp với sinh học, nhưng vẫn cung cấp câu trả lời tốt ... nhiều nhà khoa học máy tính nói chung "bất cứ điều gì anh chàng, và cảm ơn về thuật ngữ." Cũng lưu ý rằng tất cả các anh chị em của bạn và không hoàn toàn giống nhau ... thậm chí thông qua họ có cùng cha mẹ. Mỗi người có các gen đột biến vì bất kỳ lý do gì (xin đừng trình bày điều này với một nhà sinh vật học, vấn đề là phải hiểu động lực đằng sau phần lớn thuật ngữ).

Vì vậy, bây giờ chúng tôi đang có được máy tính để tạo ra hàng triệu chương trình và đo lường sức khỏe của họ. Các giải pháp tốt nhất tồn tại vào thế hệ tiếp theo. Chúng tôi cũng "đột biến" và thực hiện giao thoa với "dân số" (chú ý cách sử dụng ngôn ngữ di truyền và sinh học). Một khi thế hệ thứ hai được tạo ra, thể dục một lần nữa được đo. Vì thế hệ này có các giải pháp tốt nhất từ ​​thế hệ trước VÀ chúng tôi đã vượt qua và biến đổi các giải pháp tốt nhất (cùng với dân số tầm thường - để theo kịp sự đa dạng), thế hệ này nên tốt hơn một chút so với thế hệ trước.

Chúng tôi tiếp tục điều này cho một số lượng lớn các thế hệ. Mỗi thế hệ (hy vọng) cung cấp các giải pháp tốt hơn và tốt hơn, cho đến khi chúng tôi có được câu trả lời đúng. Ví dụ:

(+ (- 2.2 (/ x 11) (* 7 (cos y))))

Vâng nhìn vào điều này, điều này là chính xác!
(Tôi đã sao chép từ http://en.wikipedia.org/wiki/Genetic_programming , cũng có một hình đại diện của cây này)

Vụn vặt

Có một số vấn đề quan trọng, như làm thế nào để bạn quyết định "thiết bị đầu cuối" ( +, -, *, /, cos, sin, tan) nào có sẵn cho hệ thống GP của bạn, cách bạn viết chức năng tập thể dục và cách hệ thống xử lý các chương trình không nhạy cảm như (1 + cos)hoặc (2 / "hello")(trong số nhiều thiết bị khác).

Nó là khá nhàm chán để phát triển phương trình. Sẽ thú vị hơn nếu bộ thiết bị đầu cuối của bạn trông giống như sau: (lửa, cảm giác kẻ thù, di chuyển, ...) và chức năng thể dục của bạn đo lường sức khỏe của bạn và số xác chết của quái vật võ thuật.

Tôi đã viết hầu hết những điều này từ bộ nhớ nhưng đây là ý tưởng cơ bản. Tôi đã làm một số GP trong những năm đại học của tôi. Bạn chắc chắn nên chơi xung quanh với nó. Đừng lo lắng về việc hiểu tất cả các thuật ngữ, chỉ cần tải xuống một số hệ thống GP miễn phí, chạy qua một vài ví dụ để cảm nhận về nó và tạo ra các ví dụ thú vị của riêng bạn (tìm mối quan hệ giữa các bộ dữ liệu khác nhau, cố gắng nối nó với trò chơi API, v.v.)


1

Survival of the Fittest: Chọn lọc tự nhiên với Windows Forms là cách tôi được giới thiệu về Lập trình di truyền. Nó dễ đọc với mã có sẵn để tải xuống. Nhược điểm là GP yêu cầu một phương tiện để thực thi mã được tạo trong thời gian chạy và tại thời điểm bài viết được viết, C # không phù hợp với nhiệm vụ này. Đó là lý do tại sao ví dụ sử dụng CodeDOM để tạo, biên dịch và chạy mã trong thời gian chạy, chính nó thêm một lớp phức tạp khác cho nó.

Mọi thứ đã thay đổi kể từ đó với .NET hiện có API ExpressionTree của riêng mình, điều này có thể sẽ cho phép triển khai GP thanh lịch hơn trong C # so với mô tả trong bài viết. Nhưng nó đủ tốt để hiểu về cách thức hoạt động của GP.

Tại đây bạn có thể tải xuống một ebook miễn phí trên GP, ​​bao gồm một ví dụ mã java rất ngắn mà bạn cũng có thể thấy thú vị.


-1

Các thuật toán di truyền và lập trình di truyền có liên quan, nhưng các khái niệm khác nhau.

Thuật toán di truyền (GA) là thuật toán tìm kiếm cho các vấn đề tối ưu hóa phức tạp. Trong GA, bạn mã hóa các tham số của giải pháp cho một số vấn đề trong chuỗi bit "DNA", sau đó "nhân giống" ngẫu nhiên các bitstrings này: để chúng sinh sản bằng cách kết hợp các phần của chúng và áp dụng "sự sống sót mạnh nhất" bằng cách xóa tất cả các bitstr bạn đã có ngoại trừ những người giỏi nhất trong việc giải quyết vấn đề của bạn.

Lập trình di truyền (GP) thậm chí còn phức tạp hơn: ở đây, bạn không đại diện cho các chương trình bằng DNA của chúng (bitstrings), mà bằng cách phân tích các cây mà bạn nhân giống và chọ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.