2010-02-18 24 views
4

很抱歉,如果我在寫這樣的移動設備上,我試圖讓它快,這是不明確的。在用戶界面中使用GA

我寫了一個基本的遺傳算法與建立一個適應值,並使用錦標賽選擇,突變和交叉通過多次迭代進化的二進制編碼(基因)。作爲一個基本的命令行示例,它似乎起作用。

我有這個問題是因爲我寫一個使用GA找到通過迷宮的方法的迷宮解決程序的GUI中應用遺傳算法。如何將我的隨機二進制編碼基因和適應度函數(將所有二進制值加在一起)轉換爲控制迷宮周圍bot的方法?我用Java構建了一個基本的圖形用戶界面(GUI),其中包含一系列標籤(如網格),可用路由爲藍色,牆壁爲黑色。

重申我的遺傳算法執行得很好,包含任何典型的遺傳算法(健身方法,獲取和設置種羣,選擇,交叉等),但現在我需要將其插入GUI以使我的迷宮運行。爲了獲得一個可以在不同方向移動的機器人,需要去哪裏取決於GA所說的內容?如果可能的話

按照要求,一個人是使用一個單獨的類(逐張)建,與所有的主要工作正在波普類完成粗糙的僞代碼將是巨大的。當一個新個體被實例化時,一個int數組代表所述個體的基因,隨機從0到1之間的數字中挑選基因。適應度函數僅將這些基因的值加在一起,並且在Pop類中處理選擇,兩個選定個體的突變和交叉。除此之外,命令行程序僅顯示n代以上的進化,總體適應度在每次迭代中都有所提高。

編輯:它開始讓更多的意義,現在,雖然有被竊聽我的幾件事情...

正如亞當斯基曾建議我想創建一個「代理」與如下所示的選項。我遇到的問題是隨機比特串在這裏發揮作用。代理知道牆壁在哪裏,並且以4位字符串(即0111)排列,但這對隨機32位字符串有什麼影響? (即10001011011001001010011011010101)如果我有以下迷宮(x爲出發地,2是目標,1是牆):

x 1 1 1 1 
0 0 1 0 0 
1 0 0 0 2 

如果我左轉,我面對錯誤的方式,代理將如果向前移動,則完全離開迷宮。我認爲第一代的字符串是完全隨機的,隨着健身的增長它會發展,但我不明白字符串如何在迷宮中工作。

因此,爲了得到這個直...

健身是當代理能夠移動,是一堵牆的結果。

基因是一串32比特,分成16組2比特以顯示可用的動作,機器人移動兩比特需要通過代理顯示中的四位傳遞其靠近牆壁的位置。如果移動是通過牆壁移動,則該移動不被執行,並且被認爲是無效的,如果移動已經完成,並且如果發現新的牆壁,則健身狀態會上升。

是嗎?

+0

也許你可以提供一些關於每個進化個體中編碼信息的更多細節? – 2010-02-18 11:16:45

+0

我編輯了主要問題,但目前沒有真正重要的編碼,此刻每個個體有500個基因,隨機數字方法在其中添加1或0。 – AlexT 2010-02-18 11:24:07

回答

4

,如果你想解決一個特定的迷宮BadHorse的回答是不錯的;您只需解讀爲此你的位串作爲精確指令一個序列通過迷宮引導代理。在這種情況下,你的健身不是比特串的總和(正如你在你的問題中陳述的那樣),而是衡量代理人在解決問題方面取得成功的一些指標。例如,您的健身可能被定義爲「在處理20條指令」之後從迷宮末端沿直線的距離「」。

因此,在評估每一個人,當你允許它從你的比特串處理第一個20條指令,然後計算其適應度,執行任何交叉/突變,然後創建下一代的個體。

如果你想開發你的代理來解決任何迷宮你需要在你的位串而不是一系列指令中編碼規則。您可以根據牆壁是在機器人的後面,前面,左側還是右側來定義規則。例如

FBLR Action 
0000 Move Forward 
0001 Move Forward 
0010 Turn Right 
etc 

這給你由16個動作的比特串,編碼爲2位(00 =向前,01 =右轉,10 =左轉,11 =向後移動)的每個動作。在評估您的代理時,它只是簡單地確定其當前狀態,並使用位串作爲查找表來確定它應該如何響應。然後,在評估其適應性之後,它會重複此操作若干次。

鑑於這種編碼的代理可以評估規則人類通常使用,這是「連續跟蹤左手牆」。很顯然,如果迷宮沒有完全連接,這種方法就會失敗,在這種情況下,您需要將更多的狀態編碼爲基於規則的方法(例如,如果經過「舊地」,代理可能會有不同的響應)。

希望有所幫助。

編輯

在回答您的最新編輯:

,我已經編碼的代理「傳感器」檢測是否它旁邊的牆壁或沒有事實是不相關的(你的基因),也許我用我的例子稍微混淆了一些事情。該基因僅編碼動作(向前移動等)而不是傳感器狀態。

因此,你應該寫代碼來查找給定的傳感器讀數的特定組合的比特串的相關部分;例如

/** 
* Enumeration describing the four available actions to the agent 
* and methods for decoding a given action from the "bit" string 
* (actually represented using booleans). 
*/ 
public enum Action { 
    MOVE_FORWARD, REVERSE, TURN_LEFT, TURN_RIGHT 

    Action decodeAction(boolean b1, boolean b2) { 
    Action ret; 

    if (b1) { 
     ret = b2 ? Action.MOVE_FORWARD : Action.TURN_LEFT; 
    } else { 
     ret = b2 ? Action.TURN_RIGHT : Action.REVERSE; 
    } 

    return ret; 
    } 
} 

/** 
* Class encapsulating the 32-bit "bit string" represented using booleans. 
* Given the state of the four agent inputs the gene will provide a specific 
* action for the agent to perform. 
*/ 
public class Gene { 
    private final boolean[] values = new boolean[32]; 

    public Action getActionForSensorInputs(boolean wallInFront, 
    boolean wallBehind, boolean wallToLeft, boolean wallToRight) { 

    int i=0; 

    // Encode the four sensor inputs as a single integer value by 
    // bitwise-ORing each sensor value with a power of 2. 
    // The encoded value will be in the range [0, 15]. 
    if (wallToRight) { 
     i |= 0x01; 
    } 

    if (wallToLeft) { 
     i |= 0x02; 
    } 

    if (wallBehind) { 
     i |= 0x04; 
    } 

    if (wallInFront) { 
     i |= 0x08; 
    } 

    // The look-up index is i * 2 because each action is encoded as 2 
    // booleans. 
    int index = i * 2; 

    // Retrieve the two action bits from the bit string. 
    boolean b1 = this.values[index]; 
    boolean b2 = this.values[index + 1]; 

    // Finally decode the action to perform. 
    return Action.decodeAction(b1, b2); 
    } 

    // TODO: Add method to support crossover and mutation with other Genes. 
} 

給出一個Gene的這個簡單的定義,你可以在Agent實施中嵌入這個類,記錄劑「已安裝」當前基因如何執行;例如

private enum Direction { NORTH, SOUTH, EAST, WEST }; 

public class Agent { 
    private final Geneva gene; 
    private final int x; // x position in maze; 
    private final int y; // y position in maze; 
    private Direction currentDirection; 

    public double evaluate() { 
    double fitness; 

    // Perform up to 20 actions and then evaluate fitness. 
    for (int i=0; i<20; ++i) { 
     // TODO Determine sensor inputs. 

     Action action = gene.getActionForSensorInputs(...); 

     // TODO: Now apply action to update agent's state. 
     // If agent has reached goal exit loop and return fitness 1.0 (max fitness). 
     // If agent has exited the maze then exit loop and return 0.0 (min fitness). 
    } 

    // Calculate fitness after 100 steps taken. For example could be 
    // calculated as sqrt((goal.x - x)^2 + (goal.y - y)^2). 

    return fitness; 
    } 
} 
+0

後半部分是我想要做的,所以它會使用規則解決任何給定的迷宮。我遇到的問題是分配規則。據我瞭解,代理將有自己的「查找」與您在頂部給出的值,然後一串32位,分成16位2位(行動)從基因獲得,與四可用的行動。我編輯了這個問題,以顯示我遇到麻煩,以便我不會在這裏耗盡空間。 – AlexT 2010-02-19 03:08:58

+0

@AlexT:很抱歉,我編輯了我的答案,並添加了一些示例代碼以幫助您入門。 – Adamski 2010-02-22 22:44:24

+0

這看起來很棒!我會玩一些代碼,然後嘗試構建一個Maze類,然後如果一切按計劃進行,我會回來接受這個答案。 – AlexT 2010-03-01 12:02:05

0

如果我理解正確的話,你需要確定如何你的機器人在GUI的操作是由你的遺傳算法的結果來表示?我認爲確定你想使用的表示應該是你的出發點。因此,您需要爲您的個體中的每個(一組)基因創建一個映射,以針對您的機器人的某個動作或某個運動算法的變化。

只要你選擇了一個可行的表示,實施將在一定程度上更符合邏輯。

一個運動的非常簡單的表現是讓基因硬編碼了一定的路線。您可以使用四個基因塊來表示不同的方向,然後0代表'不在這個方向移動',1代表移動。

然後表示01001101可以轉化爲以下運行模式:

stand still 
go one step east 
stand still 
stand still 
go one step north 
go one step east 
stand still 
go one step west