Principles of Computing (Part 2) -- week 3 (Tree, Lambda, Minimax)
来源:互联网 发布:java的replace方法 编辑:程序博客网 时间:2024/06/08 05:08
lambda:
Anonymous functions are simplified forms of function definitions.
- they do not have a name.
- the parameter list is not in parentheses.
- the function body is just a single expression, which is implicitly returned.
This simplicity is convenient especially when the function is simply passed as an argument, as in the last example above.
Example:
data = [1, 3, 6, 9, 18] # square elements in a list by lambda data3 = map(lambda x: x ** 2, data) # filter the even number data4 = filter(lambda val: val % 2 == 0, data)
Tree
A rooted tree is a hierarchical data structure with applications in many areas of computer science. These applications include searching, sorting, modeling biological processes (such as genealogy), and representing hierarchical programming constructs such as arithmetic expressions.
This distinction between leaf nodes and internal nodes allows us to specify simple recursive definitions for several important structural quantities associated with trees.
- The number of nodes in a tree satisfies:
If the root node of the tree is a leaf: return 1 else: return 1 + the sum of the number of nodes for each subtree
- The number of leaves in a tree satisfies:
If the root node of the tree is a leaf: return 1 else: return the sum of the number of leaves for each subtree
- The height of a tree is the length of the longest sequence of edges from the root to a leaf. The height can be computed recursively via:
If the root node of the tree is a leaf: return 0 else: return 1 + the maximum of the heights of the subtrees
In the case of binary trees, the two subtrees of a node are usually referred to as the left subtree and the right subtree. For binary trees, there are three common types of tree traversals:
- Pre-order traversals - process root, process left subtree, process right subtree
- Post-order traversals - process left subtree, process right subtree, process root
- In-order traversals - process left subtree, process root, process right subtree
ArithmeticExpression class implement uses In-order traversals
Mini Project – TicTacToe with Minimax
- Use Minimax to return the best move
- Use Memo_dict to record the score the boards, reduce iteration
- Use equivalent_boards by mirror & rotation to optimize
- Use opt_empty_cell to reduce the empty cell search list
""" Mini-max Tic-Tac-Toe Player """ import poc_ttt_gui import poc_ttt_provided as provided # Set timeout, as mini-max can take a long time import codeskulptor codeskulptor.set_timeout(600) import math import random # SCORING VALUES - DO NOT MODIFY SCORES = {provided.PLAYERX: 1, provided.DRAW: 0, provided.PLAYERO: -1} # helper function def transpose_board(board): """ return the transposed board """ dim = board.get_dim() tboard = provided.TTTBoard(dim) for row in range(dim): for col in range(dim): if board.square(row, col) != provided.EMPTY: tboard.move(col, row, board.square(row, col)) return tboard def x_mirror_board(board): """ return the board mirrored by x """ dim = board.get_dim() xboard = provided.TTTBoard(dim) for row in range(dim): for col in range(dim): if board.square(row, col) != provided.EMPTY: xrow = dim - row - 1 xboard.move(xrow, col, board.square(row, col)) return xboard def y_mirror_board(board): """ return the board mirrored by y """ dim = board.get_dim() yboard = provided.TTTBoard(dim) for row in range(dim): for col in range(dim): if board.square(row, col) != provided.EMPTY: ycol = dim - col - 1 yboard.move(row, ycol, board.square(row, col)) return yboard def rotate_board(board, retation = 90): """ retate the board by 0, 90, 180, 270 degree """ dim = board.get_dim() rboard = provided.TTTBoard(dim) valid_rotation_list = [0, 90, 180, 270] if retation not in valid_rotation_list: return "Invalid retation", retation for row in range(dim): for col in range(dim): if retation == 90: rboard.move(dim - col - 1, row, board.square(row, col)) elif retation == 180: rboard.move(dim - row - 1, dim - col - 1, board.square(row, col)) elif retation == 270: rboard.move(col, dim - row - 1, board.square(row, col)) else: rboard.move(row, col, board.square(row, col)) return rboard def all_equivalent_board(board): """ return all the equivalent boards """ all_boards = [] rotation_list = [0, 90, 180, 270] for rotation in rotation_list: rboard = rotate_board(board, rotation) tboard = transpose_board(rboard) all_boards.append(rboard) all_boards.append(tboard) return all_boards def opt_empty_cell(board): """ reduce the empty cell according to the board """ dim = board.get_dim() all_empty_cells = board.get_empty_squares() xboard = x_mirror_board(board) if str(board) == str(xboard): xrow = int(math.ceil(dim / 2.0)) for row in range(xrow, dim): for col in range(dim): cell = (row, col) if cell in all_empty_cells: all_empty_cells.remove(cell) yboard = y_mirror_board(board) if str(board) == str(yboard): ycol = int(math.ceil(dim / 2.0)) for row in range(dim): for col in range(ycol, dim): cell = (row, col) if cell in all_empty_cells: all_empty_cells.remove(cell) tboard = transpose_board(board) if str(board) == str(tboard): xrow = int(math.floor(dim / 2.0)) ycol = int(math.ceil(dim / 2.0)) for row in range(xrow, dim): for col in range(ycol): if row != col: cell = (row, col) if cell in all_empty_cells: all_empty_cells.remove(cell) return all_empty_cells def mm_move_helper(board, player, memo_dict): """ helper function for mm_move for not corrupt origial structure """ if (str(board)) in memo_dict.keys(): return memo_dict[(str(board))] # DFS the tree until game finishes if board.check_win() == None: cell_dict = {} # score the next moves # for cell in board.get_empty_squares(): for cell in opt_empty_cell(board): board_clone = board.clone() board_clone.move(cell[0], cell[1], player) move = mm_move_helper(board_clone, provided.switch_player(player), memo_dict) # stop DFS search as long as the best solution is found if move[0] * SCORES[player] == 1: # memo the result all_boards = all_equivalent_board(board) for a_board in all_boards: memo_dict[str(a_board)] = (move[0], cell) return move[0], cell if move[0] * SCORES[player] not in cell_dict.keys(): cell_dict[move[0] * SCORES[player]] = cell # return the best score and move max_score = max(cell_dict.keys()) best_score = max_score * SCORES[player] best_move = cell_dict[max_score] else: # Score the board when game finishes best_score = SCORES[board.check_win()] best_move = (-1, -1) # memo the result all_boards = all_equivalent_board(board) for a_board in all_boards: memo_dict[str(a_board)] = (best_score, best_move) return best_score, best_move def mm_move(board, player): """ Make a move on the board. Returns a tuple with two elements. The first element is the score of the given board and the second element is the desired move as a tuple, (row, col). memo_dict is a dictionary that stores previously computed results """ return mm_move_helper(board, player, {}) def move_wrapper(board, player, trials): """ Wrapper to allow the use of the same infrastructure that was used for Monte Carlo Tic-Tac-Toe. """ move = mm_move(board, player) assert move[1] != (-1, -1), "returned illegal move (-1, -1)" return move[1] # Test game with the console or the GUI. # Uncomment whichever you prefer. # Both should be commented out when you submit for # testing to save time. #provided.play_game(move_wrapper, 1, False) poc_ttt_gui.run_gui(3, provided.PLAYERX, move_wrapper, 1, False)
- Principles of Computing (Part 2) -- week 3 (Tree, Lambda, Minimax)
- Principles of Computing (Part 2) -- week 1
- Principles of Computing (Part 2) week 2 -- Recursion
- Principles of Computing (Part 1) -- Week 5 Mini-projects: Cookie Clicker Simulator
- The principles of service-orientation part 3 of 6: Service abstraction and reuse [by Thomas Erl]
- Principle of Computing (Python)学习笔记(7) DFS Search + Tic Tac Toe use MiniMax Stratedy
- Principle of Computing(2)
- Part 4 The Principles of Java Application Performance Tuning
- The principles of service-orientation part 2 of 6: Service contracts and loose coupling [by Thomas Erl]
- Stanford Algorithms: Design and Analysis, Part 2[week 3]
- Princeton Algorithms: Part 2 [week 3: Maxflow and Mincut]
- Princeton Algorithms: Part 2 [week 3: Radix Sorts]
- Princeton Algorithms: Part 1 [week 1:Analysis of Algorithms]
- Coursera Algorithms, Part 1 Week 1: Analysis of Algorithm
- The principles of service-orientation part 1 of 6: Introduction to service-orientation [by Thomas Erl]
- The principles of service-orientation part 4 of 6: Service discoverability and composition [by Thomas Erl]
- Principles of Economics---Microoeconomic(Mankiw)Chapter 2
- Princeton Algorithms: Part 1 [week 3:Mergesort]
- HttpURLConnection使用注意事项
- hibernate里联合主键composite-id映射
- 利用ViewHolder优化自定义Adapter的典型写法
- 获得客户端真实IP的方法
- nyoj题目455:黑色帽子
- Principles of Computing (Part 2) -- week 3 (Tree, Lambda, Minimax)
- 常用Apache Commons工具类备忘
- scala yield和文件的操作
- nyoj题目276:比较字母大小
- COPY Netty系列之Netty可靠性分析
- STM32F10X启动代码注释
- COPY Netty系列之Netty并发编程分析
- django开发环境搭建(参考流程)
- CSS制作斜角上有背景图片的Div层