Your SlideShare is downloading. ×
  • Like
groovy & grails - lecture 8
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

groovy & grails - lecture 8

  • 704 views
Published

Eclipse tips …

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

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
704
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
14
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • 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

Transcript

  • 1. Groovy: Efficiency Oriented ProgrammingLecture 8Master Proteomics & Bioinformatics - University of GenevaAlexandre Masselot - summer 2011
  • 2. Contents‣ Eclipse tips‣ 8 queens on a chess board‣ Genetic algorithm‣ Abstract class (a little bit more about inheritance)
  • 3. Eclipse tips‣ Outline view in the right column - get a list of your field and method of the current class
  • 4. 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
  • 5. 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
  • 6. 8 queens puzzle‣ Problem - put 8 queens on a chess board, - none is able to capture another (columns, rows and diagonal)
  • 7. 8 queens puzzle: history‣ Chess player Max Bezzel proposed the problem in 1848
  • 8. 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)
  • 9. 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)
  • 10. 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
  • 11. As usually, sexy problems divergen-queens, n×n chessboard with kings, knights... 6
  • 12. 8 queens on a 8×8 chessboard: how many solutions? 7
  • 13. 8
  • 14. 8
  • 15. 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
  • 16. 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
  • 17. 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
  • 18. 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
  • 19. Goals for today ‣ Write code to find solutions
  • 20. Goals for today ‣ Write code to find solutions ‣ Brute force
  • 21. Goals for today ‣ Write code to find solutions ‣ Brute force ‣ Genetic programming (evolving random approach)
  • 22. Goals for today ‣ Write code to find solutions ‣ Brute force ‣ Genetic programming (evolving random approach) ‣ generalize the problem to kings
  • 23. 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
  • 24. An algorithm for solutions
  • 25. An algorithm for solutions
  • 26. An algorithm for solutions
  • 27. An algorithm for solutions
  • 28. An algorithm for solutions
  • 29. An algorithm for solutions
  • 30. An algorithm for solutions
  • 31. An algorithm for solutions
  • 32. An algorithm for solutions
  • 33. An algorithm for solutions
  • 34. An algorithm for solutions
  • 35. An algorithm for solutions
  • 36. An algorithm for solutions
  • 37. An algorithm for solutions
  • 38. An algorithm for solutions
  • 39. An algorithm for solutions
  • 40. An algorithm for solutions
  • 41. An algorithm for solutions
  • 42. An algorithm for solutions
  • 43. An algorithm for solutions
  • 44. An algorithm for solutions
  • 45. 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
  • 46. 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
  • 47. A code synopsis: board fields
  • 48. A code synopsis: board fields‣ ChessBoard.groovy/ChessBoardWithQueens.groovy /// number of rows and column for the board int size=8
  • 49. 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
  • 50. 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 = []
  • 51. 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 = []
  • 52. A code synopsis: board methods
  • 53. A code synopsis: board methods /// how many pieces on the board int countPieces(){...}
  • 54. A code synopsis: board methods /// how many pieces on the board int countPieces(){...} /// synopsis: board << [0, 3] void leftShift(List<Integer> pos){...}
  • 55. 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(){...}
  • 56. 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){...}
  • 57. A code synopsis: a recursive algorithm
  • 58. 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
  • 59. 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)
  • 60. 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 }
  • 61. 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 }
  • 62. 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 }
  • 63. 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 }
  • 64. 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 }
  • 65. 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 }
  • 66. So we only need to code two functionalities a) increment position; b) explore 17
  • 67. A code synopsis: incrementing a position‣ Incrementing a piece position means
  • 68. A code synopsis: incrementing a position‣ Incrementing a piece position means - Incrementing the column
  • 69. 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
  • 70. 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
  • 71. 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
  • 72. A code synopsis: incrementing a position
  • 73. A code synopsis: incrementing a position‣ Groovy code:
  • 74. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[
  • 75. A code synopsis: incrementing a position‣ Groovy code: /* a position is a List of 2 integer in [0, boardSize[ increment second coordinates if possible
  • 76. 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)
  • 77. 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
  • 78. 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 */
  • 79. 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] }
  • 80. 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] }
  • 81. 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] }
  • 82. 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] }
  • 83. 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() }}
  • 84. 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() }}
  • 85. 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() }}
  • 86. 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() }}
  • 87. A recursive function calls itself 21
  • 88. 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)
  • 89. 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
  • 90. 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
  • 91. 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
  • 92. 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
  • 93. Recursion: the limits
  • 94. Recursion: the limits‣ Recursive method is concise
  • 95. Recursion: the limits‣ Recursive method is concise‣ But it requires - time (method call) - memory (deep tree!)
  • 96. 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
  • 97. 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...)
  • 98. Creationism or Darwinism? 24
  • 99. Genetic Algorithm: an introduction‣ A problem ⇒ a fitness function
  • 100. Genetic Algorithm: an introduction‣ A problem ⇒ a fitness function‣ A candidate solution ⇒ a score given by the fitness function
  • 101. 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
  • 102. Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection
  • 103. Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene
  • 104. Genetic Algorithm: an introduction (cont’d)‣ Searching for a solution simulating a natural selection‣ One candidate solution ⇔ one gene‣ population ⇔ set of genes
  • 105. 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
  • 106. 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
  • 107. GA for the 8 queens problem
  • 108. GA for the 8 queens problem‣ Gene ⇔ 8 positions
  • 109. GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()
  • 110. GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()‣ Cross-over ⇔ mixing pieces of two boards
  • 111. GA for the 8 queens problem‣ Gene ⇔ 8 positions‣ Fitness ⇔ -board.countConflicts()‣ Cross-over ⇔ mixing pieces of two boards‣ Mutation ⇔ moving randomly one piece
  • 112. 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...}
  • 113. 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 }
  • 114. 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() } }
  • 115. 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() } }
  • 116. 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() } }
  • 117. Evolution.groovy = problem agnostic 30
  • 118. 31
  • 119. GA: more evolution
  • 120. GA: more evolution‣ Mutation rate can be time dependent (decrease over time...)
  • 121. GA: more evolution‣ Mutation rate can be time dependent (decrease over time...)‣ Different population pools (different parameters), long term cross-over
  • 122. 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
  • 123. Genetic algorithm: a solution for everything?
  • 124. Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process
  • 125. Genetic algorithm: a solution for everything?‣ GA looks like a magic solution to any optimization process‣ In practice, hard to tune evolution strategy & parameters
  • 126. 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)
  • 127. 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
  • 128. 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!)
  • 129. 32 Knights on the board 34
  • 130. Board with knights
  • 131. 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 }
  • 132. Shall we redefine all the previous methods from the ChessBoard with queens? DRY! 36
  • 133. A generic ChessBoard : abstract class
  • 134. 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);}
  • 135. Queen specialization
  • 136. Queen specialization
  • 137. 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 }
  • 138. Knight specialization
  • 139. 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 }
  • 140. And from the exploration script
  • 141. And from the exploration script‣ In main script: //ChessBoardWithQueens board=[size:8, maxPieces:8] ChessBoardWithKnights board=[size:8, maxPieces:32] explore(board)
  • 142. And from the exploration script‣ In main script: //ChessBoardWithQueens board=[size:8, maxPieces:8] ChessBoardWithKnights board=[size:8, maxPieces:32] explore(board)‣ Nothing more...
  • 143. Do not forget unit tests! 41
  • 144. abstract class testing‣ Not possible to instantiate new ChessBoard()
  • 145. 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]) ) } } ... }
  • 146. 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]
  • 147. abstract class testing (cont’d)
  • 148. 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]) ... }