Your SlideShare is downloading. ×

groovy & grails - lecture 8

752

Published on

Eclipse tips …

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

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
752
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
18
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]) ... }

    ×