• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
groovy & grails - lecture 8
 

groovy & grails - lecture 8

on

  • 813 views

Eclipse tips

Eclipse tips
8 queens on a chess board
Genetic algorithm
Abstract class (a little bit more about inheritance)

Statistics

Views

Total Views
813
Views on SlideShare
813
Embed Views
0

Actions

Likes
1
Downloads
14
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • today end of a cycle\nnext week: genetic algorithm\nthen web programming\nend of the year exam: bring in your ideas\nplay customer + coder\ncustomer phase with me, then iterative development.\n
  • we go to real world\ngood news : no exercise to do\nbad news : you must understand the whole project\nThis project is something like a semester project\nabstract class => a little more in OOP\n\n
  • \n
  • \n
  • \n
  • \n
  • check out more on wikipedia\n
  • check out more on wikipedia\n
  • check out more on wikipedia\n
  • check out more on wikipedia\n
  • bishops, rooks,\nqueens + knights etc...\n
  • back to the roots\n
  • \n
  • modulo rotation, reflexion\n92 solution in the total\n
  • no known formula to compute the number of solution based on n\nquite some literature\n
  • no known formula to compute the number of solution based on n\nquite some literature\n
  • no known formula to compute the number of solution based on n\nquite some literature\n
  • no known formula to compute the number of solution based on n\nquite some literature\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • go with aimant on the board\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • for queens, positions could only been one column, but let’s not over-engineer our chessboard from start\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • most attentive of you will notice that isPieceConflict is defined only into ChessBoardWithQueens.groovy\nAnd will notice that some methods are not (yet) needed (clone(), countConflicts() etc.\nQ: how do you know your code works?\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • Q: how do you know your code works?\n
  • \n
  • \n
  • \n
  • divide and conquer\nmust not call itself indefinitely\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • time can also be measured taken into consideration the number of lines written, not just computing time\nThink of building a taxonomy subtree\n walking through a deep tree means remembering all the precedent status\n
  • time can also be measured taken into consideration the number of lines written, not just computing time\nThink of building a taxonomy subtree\n walking through a deep tree means remembering all the precedent status\n
  • time can also be measured taken into consideration the number of lines written, not just computing time\nThink of building a taxonomy subtree\n walking through a deep tree means remembering all the precedent status\n
  • time can also be measured taken into consideration the number of lines written, not just computing time\nThink of building a taxonomy subtree\n walking through a deep tree means remembering all the precedent status\n
  • We know the finality => we can write a dedicated solution\nbut another approach exists\n
  • \n
  • \n
  • \n
  • motto: the fittest survive and transfer its genes\n random new genes can be incorporated into the population\n
  • motto: the fittest survive and transfer its genes\n random new genes can be incorporated into the population\n
  • motto: the fittest survive and transfer its genes\n random new genes can be incorporated into the population\n
  • motto: the fittest survive and transfer its genes\n random new genes can be incorporated into the population\n
  • motto: the fittest survive and transfer its genes\n random new genes can be incorporated into the population\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • a gene factory which can generate gene related to our problem\nthose genes can mutate, crossover, compute there fitness, being randomly built\n\n
  • local minima => never get out\n
  • different pools => each explore a specificity\nmix to avoid consanguinity....\n
  • different pools => each explore a specificity\nmix to avoid consanguinity....\n
  • different pools => each explore a specificity\nmix to avoid consanguinity....\n
  • if you know the finality, darwinism is not the correct path...\n
  • if you know the finality, darwinism is not the correct path...\n
  • if you know the finality, darwinism is not the correct path...\n
  • if you know the finality, darwinism is not the correct path...\n
  • if you know the finality, darwinism is not the correct path...\n
  • \n
  • 32 knights, or 14 bishops, 16 kings or 8 rooks,\n
  • \n
  • not good...\n
  • not good...\n
  • not good...\nnote the missing {} and\n
  • not good...\nnote the missing {} and\n
  • not good...\nnote the missing {} and\n
  • Test all with ChessBoardWithQueensTest\nonly pieces conflict with ChessBoardWithKnightsTests\n
  • In practice: think agile!!! refactor when the knights come on the table!\nGA: much slower for the queens, but so much faster for the knights...\n
  • In practice: think agile!!! refactor when the knights come on the table!\nGA: much slower for the queens, but so much faster for the knights...\n
  • \n
  • \n
  • \n
  • \n
  • \n

groovy & grails - lecture 8 groovy & grails - lecture 8 Presentation Transcript

  • Groovy: Efficiency Oriented ProgrammingLecture 8Master Proteomics & Bioinformatics - University of GenevaAlexandre Masselot - summer 2011
  • Contents‣ Eclipse tips‣ 8 queens on a chess board‣ Genetic algorithm‣ Abstract class (a little bit more about inheritance)
  • Eclipse tips‣ Outline view in the right column - get a list of your field and method of the current class
  • Eclipse tips‣ Outline view in the right column - get a list of your field and method of the current class‣ Help > Key assist - get a list of all the possible shortcuts
  • Eclipse tips‣ Outline view in the right column - get a list of your field and method of the current class‣ Help > Key assist - get a list of all the possible shortcuts
  • 8 queens puzzle‣ Problem - put 8 queens on a chess board, - none is able to capture another (columns, rows and diagonal)
  • 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848
  • 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848‣ Mathematicians (including Gauss) worked on the problem (and generalization to n-queens)
  • 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848‣ Mathematicians (including Gauss) worked on the problem (and generalization to n-queens)‣ Franz Nauck proposed the first solutions (1850)
  • 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848‣ Mathematicians (including Gauss) worked on the problem (and generalization to n-queens)‣ Franz Nauck proposed the first solutions (1850)‣ Computer scientists joined the party: Edsger Dijkstra (1972) used the problem to illustrate depth-first backtracking algorithm
  • As usually, sexy problems divergen-queens, n×n chessboard with kings, knights... 6
  • 8 queens on a 8×8 chessboard: how many solutions? 7
  • 8
  • 8
  • 8 queens: some combinatorial considerations‣ Number of possible positions of 8 queens on a 8x8 chess board (no constraints): - 64 choose 8= = 4,426,165,368
  • 8 queens: some combinatorial considerations‣ Number of possible positions of 8 queens on a 8x8 chess board (no constraints): - 64 choose 8= = 4,426,165,368‣ Number of solution to the 8 queens puzzle: - 92, and reducing symmetries: 12 distinct
  • 8 queens: some combinatorial considerations‣ Number of possible positions of 8 queens on a 8x8 chess board (no constraints): - 64 choose 8= = 4,426,165,368‣ Number of solution to the 8 queens puzzle: - 92, and reducing symmetries: 12 distinct‣ extend to any n queens, on a n x n board
  • 8 queens: some combinatorial considerations‣ Number of possible positions of 8 queens on a 8x8 chess board (no constraints): - 64 choose 8= = 4,426,165,368‣ Number of solution to the 8 queens puzzle: - 92, and reducing symmetries: 12 distinct‣ extend to any n queens, on a n x n board n 1 2 3 4 5 6 7 8 9 10 distinct 1 0 0 2 2 1 6 12 46 92 unique 1 0 0 1 10 4 40 92 352 724 http://en.wikipedia.org/wiki/Eight_queens_puzzle
  • Goals for today ‣ Write code to find solutions
  • Goals for today ‣ Write code to find solutions ‣ Brute force
  • Goals for today ‣ Write code to find solutions ‣ Brute force ‣ Genetic programming (evolving random approach)
  • Goals for today ‣ Write code to find solutions ‣ Brute force ‣ Genetic programming (evolving random approach) ‣ generalize the problem to kings
  • Goals for today ‣ Write code to find solutions ‣ Brute force ‣ Genetic programming (evolving random approach) ‣ generalize the problem to kings ‣ code in tp8-solutions @ dokeos
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • An algorithm for solutions
  • A solution finder code:‣ A chessboard structure: - size & max number of pieces - add/remove pieces - count how many pieces are on the board - check if two pieces are conflicting
  • A solution finder code:‣ A chessboard structure: - size & max number of pieces - add/remove pieces - count how many pieces are on the board - check if two pieces are conflicting‣ A mechanism to explore one by one all solutions - mimic the brute force previous example
  • A code synopsis: board fields
  • A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8
  • A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8 /// maximum number of pieces on the board int maxPieces=0
  • A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8 /// maximum number of pieces on the board int maxPieces=0 /** list of list of 2 integers each of them representing a piece on the board (between 0 and (size-1)) */ List piecesPositions = []
  • A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8 /// maximum number of pieces on the board int maxPieces=0 /** list of list of 2 integers each of them representing a piece on the board (between 0 and (size-1)) */ List piecesPositions = []
  • A code synopsis: board methods
  • A code synopsis: board methods /// how many pieces on the board int countPieces(){...}
  • A code synopsis: board methods /// how many pieces on the board int countPieces(){...} /// synopsis: board << [0, 3] void leftShift(List<Integer> pos){...}
  • A code synopsis: board methods /// how many pieces on the board int countPieces(){...} /// synopsis: board << [0, 3] void leftShift(List<Integer> pos){...} /// remove last introduced piece List<Integer> removeLastPiece(){...}
  • A code synopsis: board methods /// how many pieces on the board int countPieces(){...} /// synopsis: board << [0, 3] void leftShift(List<Integer> pos){...} /// remove last introduced piece List<Integer> removeLastPiece(){...} /// are two pieces positions in conflict? boolean isPieceConflict(List<Integer> pA, List<Integer> pB){...}
  • A code synopsis: a recursive algorithm
  • A code synopsis: a recursive algorithm‣ Exploring means - placing a new piece at the next non-conflicting position - if all pieces are on the board, flag as a solution - exploring deeper
  • A code synopsis: a recursive algorithm‣ Exploring means - placing a new piece at the next non-conflicting position - if all pieces are on the board, flag as a solution - exploring deeper‣ The recursion means calling the same explore method deeper until and end is reached (e.g. all pieces are on the board)
  • A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
  • A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
  • A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
  • A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
  • A code synopsis: a recursive algorithm‣ Implementing the displayed algorithm Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
  • A codesynopsis: a a recursive algorithmA code synopsis: recursive algorithm‣ Implementing the displayed algorithm Implementing the displayed algorithm explore: if (all pieces are on the board){ !! one solution !! return } pos ← next position after last piece while (pos is on the board){ add a piece on the board at pos if (no conflict){ explore() } remove last piece pos ← next position }
  • So we only need to code two functionalities a) increment position; b) explore 17
  • A code synopsis: incrementing a position‣ Incrementing a piece position means
  • A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column
  • A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column - If end of line is reached: increment row and goto first column
  • A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column - If end of line is reached: increment row and goto first column - Return null is end of the board is reached
  • A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column - If end of line is reached: increment row and goto first column - Return null is end of the board is reached - Return [0,0] if starting position is null
  • A code synopsis: incrementing a position
  • A code synopsis: incrementing a position‣ Groovy code:
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0)
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */ List<Integer> incrementPiecePosition(int boardSize, List<Integer> p){ return [p[0], p[1]+1] }
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */ List<Integer> incrementPiecePosition(int boardSize, List<Integer> p){ if(p[1] == (boardSize - 1) ){ return [p[0]+1, 0] } return [p[0], p[1]+1] }
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */ List<Integer> incrementPiecePosition(int boardSize, List<Integer> p){ if(p[1] == (boardSize - 1) ){ if(p[0] == (boardSize -1) ) return null return [p[0]+1, 0] } return [p[0], p[1]+1] }
  • A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible then the first (and second is set to 0) returns null if end of board is reached returns [0,0] if a null position is to be incremented */ List<Integer> incrementPiecePosition(int boardSize, List<Integer> p){ if(p==null) return [0,0] if(p[1] == (boardSize - 1) ){ if(p[0] == (boardSize -1) ) return null return [p[0]+1, 0] } return [p[0], p[1]+1] }
  • 8 queens: a recursive algorithm (cont’d)def explore(board){ //walk through all possible position until it is not possible anymore toincrement while(p = incrementPiecePosition(board.size, p)){ //put the current piece on the board to give it a try board<<p //remove the piece before training another position board.removeLastPiece() }}
  • 8 queens: a recursive algorithm (cont’d)def explore(board){ //walk through all possible position until it is not possible anymore toincrement while(p = incrementPiecePosition(board.size, p)){ //put the current piece on the board to give it a try board<<p if(!board.countConflicts()){ // if it can be added without conflict try exploration deeper // (with one nore piece) explore(board) } //remove the piece before training another position board.removeLastPiece() }}
  • 8 queens: a recursive algorithm (cont’d)def explore(board){ //lets take the last piece as starting point or null if the board is empty def p=board.countPieces()?board.piecesPositions[-1]:null //walk through all possible position until it is not possible anymore toincrement while(p = incrementPiecePosition(board.size, p)){ //put the current piece on the board to give it a try board<<p if(!board.countConflicts()){ // if it can be added without conflict try exploration deeper // (with one nore piece) explore(board) } //remove the piece before training another position board.removeLastPiece() }}
  • 8 queens: a recursive algorithm (cont’d)def explore(board){ if((! board.countConflicts()) && (board.countPieces() == board.maxPieces)){ println "A working setup :n$board" return } //lets take the last piece as starting point or null if the board is empty def p=board.countPieces()?board.piecesPositions[-1]:null //walk through all possible position until it is not possible anymore toincrement while(p = incrementPiecePosition(board.size, p)){ //put the current piece on the board to give it a try board<<p if(!board.countConflicts()){ // if it can be added without conflict try exploration deeper // (with one nore piece) explore(board) } //remove the piece before training another position board.removeLastPiece() }}
  • A recursive function calls itself 21
  • 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)
  • 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)‣ See scripts/recursiveChessExploration.groovy
  • 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)‣ See scripts/recursiveChessExploration.groovy
  • 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)‣ See scripts/recursiveChessExploration.groovy
  • 8 queens: a recursive algorithm (cont’d)‣ Initialization contains: - defining a empty board with correct size - launching the first call to the recursive explore functionChessBoard board=[size:8, maxPieces:8]explore(board)‣ See scripts/recursiveChessExploration.groovy
  • Recursion: the limits
  • Recursion: the limits‣ Recursive method is concise
  • Recursion: the limits‣ Recursive method is concise‣ But it requires - time (method call) - memory (deep tree!)
  • Recursion: the limits‣ Recursive method is concise‣ But it requires - time (method call) - memory (deep tree!)‣ In practice, faster methods exist - walking through solution staying at the same stack level
  • Recursion: the limits‣ Recursive method is concise‣ But it requires - time (method call) - memory (deep tree!)‣ In practice, faster methods exist - walking through solution staying at the same stack level‣ Dedicated solutions if often better - In the case of the queens problems, knowing the pieces move can greatly help to write a dedicated algorithm (one per row, one per column...)
  • Creationism or Darwinism? 24
  • Genetic Algorithm: an introduction‣ A problem ⇒ a fitness function
  • Genetic Algorithm: an introduction‣ A problem ⇒ a fitness function‣ A candidate solution ⇒ a score given by the fitness function
  • Genetic Algorithm: an introduction‣ A problem ⇒ a fitness function‣ A candidate solution ⇒ a score given by the fitness function‣ The higher the fit, the fittest the candidate
  • Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection
  • Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene
  • Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene‣ population ⇔ set of genes
  • Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene‣ population ⇔ set of genes‣ Start : initialize a random population
  • Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene‣ population ⇔ set of genes‣ Start : initialize a random population‣ One generation - fittest genes are selected - cross-over between those genes - random mutation
  • GA for the 8 queens problem
  • GA for the 8 queens problem‣ Gene ⇔ 8 positions
  • GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()
  • GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()‣ Cross-over ⇔ mixing pieces of two boards
  • GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()‣ Cross-over ⇔ mixing pieces of two boards‣ Mutation ⇔ moving randomly one piece
  • A GA in practice (Evolution.groovy)class Evolution { int nbGenes=200 double mutationRate = 0.1 int nbKeepBest = 50 int nbAddRandom = 10 Random randomGenerator = new Random() def geneFactory List genePool...}
  • A GA in practice (Evolution.groovy) def nextGeneration(){ //select a subset of the best gene + mutate them according to a rate List reproPool=selectBest().toList().unique{it} //keep the repro pool in the best genePool=reproPool }
  • A GA in practice (Evolution.groovy) def nextGeneration(){ //select a subset of the best gene + mutate them according to a rate List reproPool=selectBest().toList().unique{it} //keep the repro pool in the best genePool=reproPool //finally mutate genes with the given rate genePool.each {gene -> if(randomGenerator.nextDouble() < mutationRate) gene.mutate() } }
  • A GA in practice (Evolution.groovy) def nextGeneration(){ //select a subset of the best gene + mutate them according to a rate List reproPool=selectBest().toList().unique{it} //keep the repro pool in the best genePool=reproPool //from the fittest reproPool, rebuild the total population by crossover (1..<((nbGenes-genePool.size())/2) ).each{ def geneA = reproPool[randomGenerator.nextInt(nbKeepBest)].clone() def geneB = reproPool[randomGenerator.nextInt(nbKeepBest)].clone() geneA.crossOver(geneB) genePool << geneA genePool << geneB } //finally mutate genes with the given rate genePool.each {gene -> if(randomGenerator.nextDouble() < mutationRate) gene.mutate() } }
  • A GA in practice (Evolution.groovy) def nextGeneration(){ //select a subset of the best gene + mutate them according to a rate List reproPool=selectBest().toList().unique{it} //keep the repro pool in the best genePool=reproPool //add a few random to the pool buildRandom(nbAddRandom).each{ genePool << it } //from the fittest reproPool, rebuild the total population by crossover (1..<((nbGenes-genePool.size())/2) ).each{ def geneA = reproPool[randomGenerator.nextInt(nbKeepBest)].clone() def geneB = reproPool[randomGenerator.nextInt(nbKeepBest)].clone() geneA.crossOver(geneB) genePool << geneA genePool << geneB } //finally mutate genes with the given rate genePool.each {gene -> if(randomGenerator.nextDouble() < mutationRate) gene.mutate() } }
  • Evolution.groovy = problem agnostic 30
  • 31
  • GA: more evolution
  • GA: more evolution‣ Mutation rate can be time dependent (decrease over time...)
  • GA: more evolution‣ Mutation rate can be time dependent (decrease over time...)‣ Different population pools (different parameters), long term cross-over
  • GA: more evolution‣ Mutation rate can be time dependent (decrease over time...)‣ Different population pools (different parameters), long term cross-over‣ Regular introduction of new random genes
  • Genetic algorithm: a solution for everything?
  • Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process
  • Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters
  • Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters‣ For a given problem: a dedicated solution always better (when possible)
  • Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters‣ For a given problem: a dedicated solution always better (when possible)‣ For the queens problems, the recursive method is much faster
  • Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters‣ For a given problem: a dedicated solution always better (when possible)‣ For the queens problems, the recursive method is much faster‣ For 32 knights: GA is much faster (not all solutions!)
  • 32 Knights on the board 34
  • Board with knights
  • Board with knights‣ ChessBoard.groovy:boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ //same row or same column if((pA[0] == pB [0]) || (pA[1] == pB[1])) return true //first diagonal if((pA[0] - pA [1]) == (pB[0] - pB[1])) return true //second diagonal if((pA[0] + pA [1]) == (pB[0] + pB[1])) return true return false }
  • Shall we redefine all the previous methods from the ChessBoard with queens? DRY! 36
  • A generic ChessBoard : abstract class
  • A generic ChessBoard : abstract class‣ ChessBoard.groovy:abstract class ChessBoard{ ... all other methods/fields are the same ... abstract boolean isPieceConflict(List<Integer> pA, List<Integer> pB);}
  • Queen specialization
  • Queen specialization
  • Queen specialization‣ Then a implementation class class ChessBoardWithQueens extends ChessBoard{ //only method boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ //same row or same column if((pA[0] == pB [0]) || (pA[1] == pB[1])) return true //first diagonal if((pA[0] - pA [1]) == (pB[0] - pB[1])) return true //second diagonal if((pA[0] + pA [1]) == (pB[0] + pB[1])) return true return false }
  • Knight specialization
  • Knight specialization‣ ChessBoardWithKnights.groovy:class ChessBoardWithKnights extends ChessBoard{ //only method boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ if( (Math.abs(pA[0]-pB[0])==2) && (Math.abs(pA[1]-pB[1])==1) ) return true if( (Math.abs(pA[1]-pB[1])==2) && (Math.abs(pA[0]-pB[0])==1) ) return true return false }
  • And from the exploration script
  • And from the exploration script‣ In main script: //ChessBoardWithQueens board=[size:8, maxPieces:8] ChessBoardWithKnights board=[size:8, maxPieces:32] explore(board)
  • And from the exploration script‣ In main script: //ChessBoardWithQueens board=[size:8, maxPieces:8] ChessBoardWithKnights board=[size:8, maxPieces:32] explore(board)‣ Nothing more...
  • Do not forget unit tests! 41
  • abstract class testing‣ Not possible to instantiate new ChessBoard()
  • abstract class testing‣ Not possible to instantiate new ChessBoard()‣ Create a fake ChessBoard class for test class ChessBoardTest extends GroovyTestCase { class ChessBoardDummy extends ChessBoard{ boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ return ( (pA[0]==pB[0]) && (pA[1]==pB[1]) ) } } ... }
  • abstract class testing‣ Not possible to instantiate new ChessBoard()‣ Create a fake ChessBoard class for test class ChessBoardTest extends GroovyTestCase { class ChessBoardDummy extends ChessBoard{ boolean isPieceConflict(List<Integer> pA, List<Integer> pB){ return ( (pA[0]==pB[0]) && (pA[1]==pB[1]) ) } } ... }‣ Then all tests are with instances ChessBoardDummy board=[size:4, maxPieces:3]
  • abstract class testing (cont’d)
  • abstract class testing (cont’d)‣ ChessBoardWithQueens only test for pieces conflict class ChessBoardWithQueensTest extends GroovyTestCase { public void testPieceConflict(){ ChessBoardWithQueens board=[size:4, maxPieces:3] //same spot assert board.isPieceConflict([0, 0], [0, 0]) //same row assert board.isPieceConflict([0, 2], [0, 0]) //same column assert board.isPieceConflict([2, 0], [0, 0]) ... }