Lecture 31: Graph Search & Game 10:00 AM, Nov 16, 2018

Similar documents
(Provisional) Lecture 32: Estimated Value, Minimax, Functional Data 10:00 AM, Nov 20, 2017

The Design Recipe Fall 2017

The Design Recipe Fall 2018

CIS 120 Midterm I February 16, 2015 SOLUTIONS

Homework 3: Recursion Due: 11:59 PM, Sep 25, 2018

Graphs. Directed graphs. Readings: Section 28

Program Graph. Lecture 25: Parallelism & Concurrency. Performance. What does it mean?

Graphs. Readings: Section 28. CS 135 Fall : Graphs 1

Lab 10: OCaml sequences, comparators, stable sorting 12:00 PM, Nov 12, 2017

CS 135 Winter 2018 Tutorial 7: Accumulative Recursion and Binary Trees. CS 135 Winter 2018 Tutorial 7: Accumulative Recursion and Binary Trees 1

Unit 7. 'while' Loops

Types, Expressions, and States

(Provisional) Lecture 08: List recursion and recursive diagrams 10:00 AM, Sep 22, 2017

Sample Exam; Solutions

Lecture 8: Iterators and More Mutation

Homework 8: Matrices Due: 11:59 PM, Oct 30, 2018

CIS 120 Midterm I October 2, Name (printed): Username (login id):

Case by Case. Chapter 3

Abstraction Functions and Representation Invariants

Homework 12: Tail Recursion and Analysis Due: 11:59 PM, Dec 4, 2018

Lecture 5: Implementing Lists, Version 1

SML Style Guide. Last Revised: 31st August 2011

(Provisional) Lecture 20: OCaml Fun!

Lecture 23: Parallelism. To Use Library. Getting Good Results. CS 62 Fall 2016 Kim Bruce & Peter Mawhorter

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #17. Loops: Break Statement

CIS 120 Midterm II November 8, Name (printed): Pennkey (login id):

(Provisional) Lecture 22: Rackette Overview, Binary Tree Analysis 10:00 AM, Oct 27, 2017

Lecture 3: Recursion; Structural Induction

Exam Datastrukturer. DIT960 / DIT961, VT-18 Göteborgs Universitet, CSE

CS 135 Fall 2018 Final Exam Review. CS 135 Fall 2018 Final Exam Review 1

Reference Cells. Example

CS 3410 Ch 7 Recursion

Loop structures and booleans

CS201 - Assignment 3, Part 2 Due: Wednesday March 5, at the beginning of class

Programming Languages and Techniques (CIS120)

Lecture 27: (PROVISIONAL) Insertion Sort, Selection Sort, and Merge Sort 10:00 AM, Nov 8, 2017

Lab 7: OCaml 12:00 PM, Oct 22, 2017

(Refer Slide Time: 01.26)

Balanced Trees. Prof. Clarkson Fall Today s music: Get the Balance Right by Depeche Mode

Module 9: Binary trees

Lecture 16: HashTables 10:00 AM, Mar 2, 2018

CS 104 (Spring 2014) Final Exam 05/09/2014

Lecture Programming in C++ PART 1. By Assistant Professor Dr. Ali Kattan

Spring 2012 Homework 10

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #06 Loops: Operators

CMSC 341 Lecture 10 Binary Search Trees

Modular Programming. Prof. Clarkson Fall Today s music: "Giorgio By Moroder" by Daft Punk

CS 11 Ocaml track: lecture 4. Today: modules

CSE 373 Final Exam 3/14/06 Sample Solution

Lecture 23: Priority Queues, Part 2 10:00 AM, Mar 19, 2018

Lecture 22: Garbage Collection 10:00 AM, Mar 16, 2018

16 Multiple Inheritance and Extending ADTs

CS 1110: Introduction to Computing Using Python Loop Invariants

Lecture 12: Dynamic Programming Part 1 10:00 AM, Feb 21, 2018

CS Lecture 6: Map and Fold. Prof. Clarkson Spring Today s music: Selections from the soundtrack to 2001: A Space Odyssey

! Two questions when we design an OO system : ! Our Initial goal: learn to design and implement simple objects.

Tracking Rumors. Suppose that we want to track gossip in a rumor mill

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

CMSC 330, Fall 2013, Practice Problems 3

1 Splay trees. 2 Implementation of splay. CS134b Homework #1 January 8, 2001 Due January 15, 2001

(Refer Slide Time 3:31)

Balanced Trees. Nate Foster Spring 2018

Lecture 24 Notes Search in Graphs

CS 115 Lecture 8. Selection: the if statement. Neil Moore

CIS 120 Midterm II November 8, 2013 SOLUTIONS

Variables. Substitution

CS2 Algorithms and Data Structures Note 10. Depth-First Search and Topological Sorting

Module 8: Binary trees

EASY

Lecture 24: Implementing Heaps 10:00 AM, Mar 21, 2018

1 Ordered Sets and Tables

Balanced Search Trees. CS 3110 Fall 2010

Spring 2012 Homework 09

COS 326 David Walker Princeton University

Lecture 35: Analysis Review & Tail Recursion 10:00 AM, Nov 28, 2018

(Refer Slide Time: 05:25)

CISC-124. Casting. // this would fail because we can t assign a double value to an int // variable

CS61B Lecture #35. [The Lecture #32 notes covered lectures #33 and #34.] Today: Enumerated types, backtracking searches, game trees.

Code Reuse: Inheritance

Computer Science 136 Spring 2004 Professor Bruce. Final Examination May 19, 2004

Metaprogramming assignment 3

CSE 341 Section 5. Winter 2018

Parallelism; Parallel Collections

CS Lecture 6: Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

CS1102: Adding Error Checking to Macros

Programming Languages and Techniques (CIS120)

Programming Languages and Techniques (CIS120)

CSC/MAT-220: Lab 6. Due: 11/26/2018

6.170 Lecture 6 Procedure specifications MIT EECS

Info 2950, Lecture 16

Implementing Mutual Exclusion. Sarah Diesburg Operating Systems CS 3430

CS Lecture 19: Loop invariants

Repetition Through Recursion

Lecture 7: Lists, Version 2 (with Mutation)

Last time: generic programming

CMSC 330: Organization of Programming Languages. Operational Semantics

CSE 341 : Programming Languages Midterm, Spring 2015

The List Datatype. CSc 372. Comparative Programming Languages. 6 : Haskell Lists. Department of Computer Science University of Arizona

Sample questions for CS111 Midterm Exam 2

Tracking Rumors. Tracking Rumors. Representing Rumor Mills. Representing Rumor Mills. Suppose that we want to track gossip in a rumor mill

Transcription:

CS Integrated Introduction to Computer Science Klein Lecture : Graph Search & Game 0:00 AM, Nov, 08 Contents Rooted-tree search DAG search Search in a graph with cycles 4 The GAME Signature Functors Rooted-tree search Start with rooted tree search Here is a graph defined by the procedure let g : int -> int list = function n -> if n < 0 then [*n-; *n; *n+] else [];; 4 8 9 0 4 8 9 Remember that a path is a sequence of vertices v,..., v k such that v is a neighbor of v, v is a neighbor of v, and so on. Our goal is to write the procedure pathp with the following spec. input: graph, source node, destination node output: is there a path in the graph from source to destination? Recall that last time we wrote the procedure successp with the following spec:

input: a procedure f, and a list output: does f return true on any element of the list? The procedure successp is supposed to stop when it finds an element on which f returns true. In the example graph, there is a path from s to some node d if there is a path from one of s s neighbors to n. What case is not covered by the above rule? Is there a situation in which there is path from s to d but it does not involve a neighbor of s? Yes, when s = d. This is the base case. let rec pathp : 'a graph * 'a * 'a -> bool = function (g, source, dest) -> if source = dest then true else successp ((function v -> pathp (g, v, dest)), (g source));; We can use boolean logic to simplify this to the following code: let rec pathp : 'a graph * 'a * 'a -> bool = function (g, source, dest) -> source = dest successp ((function v -> pathp (g, v, dest)), (g source));; Now let s modify it to return a path. We can represent a path by a list of nodes. But wait, what if there isn t a path that exists? To account for this case, we should use an option instead. find_path: input: graph, source, destination output: if there is a path p in the graph from source to destination, return Some(p). Otherwise, return None. Let s say a recursive call finds a path (and therefore returns a path option). How do we derive the output for the original call? Let s draw a recursion diagram: original input: source =, destination = recursive input: source =, destination = recursive output: Some([; ; ]) original output: Some ([;;;]) We can see from this recursion diagram that we derive the original path from the recursive path by consing. However, it is slightly more complicated because the recursive and original outputs are options. How do we get around this? You may remember from eliza that we can use pattern matching! Additionally for the base case, where the source and the destination are the same, what s the path? The answer to this is that it should be a sequence consisting of a single node, the source/destination. From this, let us write find path. let rec find_path = function (g, origin, dest) -> if origin = dest then Some([dest]) else match first_success ((function v -> find_path (g, v, dest)), g origin) with None -> None Some path -> Some (origin::path)

DAG search What if the graph is not a tree? Consider this graph on the vertices {,,,,,,8}. let dag = function -> [;] -> [;;] -> [;8] -> [] -> [] ->[9] 8 -> [9] 8 9 Let s say we search for a path from to 9. # find_path(dag,, 9);; - : int list option = Some [; ; ; 9] Okay, first note that there are multiple paths from to 9. Why did the procedure return that one? The reason is because it s the first one that succeeded in the order explored. The neighbor of is explored before the neighbor of. What if we tried to find a -to-8 path? The algorithm will explore the paths [;;], [;;], [;;], [;;;9], [;;8]. Note that it considers two paths to. Should this worry us? Let s consider a modified diamond graph:

4 8 9 0 Let s say we search for a -to- path. The algorithm will first explore paths [;;4;;;8;0], [;;4;;;9;0], [;;4;;;8;0], [;;4;;;9;0], [;;4;;;8;0], [;;4;;;9;0], [;;4;;;8;0], [;;4;;;9;0]. And that s only three levels of diamonds. The time required s up being exponential in the number of levels of diamonds. Bad! But it gets worse. This graph is directed we don t allow travel in both directions and it has no directed cycle. (A cycle is essentially a path that starts and s at the same node.) It is called a directed acyclic graph, abbreviated DAG. 4

Search in a graph with cycles Consider this graph 8 9 On this graph, the algorithm will never finish. We need to augment the algorithm so that it does not re-visit vertices. To get around this, we can use a set! The signature for sets is as follows: module type SET = sig type 'a set (* outputs an empty set *) val empty: 'a set (* outputs a set with the new element added to the old set *) val insert: 'a set * 'a -> 'a set (* outputs true if set contains given element, false otherwise *) val containsp: 'a set * 'a -> bool The algorithm will maintain a set, visited, and insert into it as it goes. Before visiting the neighbor of the current node, it will verify that the neighbor is not in the set visited. let rec dfs_helper : 'a Set.set * 'a -> 'a list option Is this worth it? Each invocation is much more expensive but this saves the algorithm from being exponential or infinite. It is definitely worth it especially once we use a set representation for which the per-operation time is O(log n) or O(). 4 The GAME Signature Here is a simplified version of the GAME signature

module type GAME = sig type which_player = P P type status = Win of which_player Draw Ongoing of which_player type state type move val initial_state : state val legal_moves : state -> move list val game_status : state -> status val next_state : state -> move -> state The types state and move are abstract. This means we can write programs that use states and moves without the programs knowing the details of these types which means those programs can be reused for different realizations of GAME. Functors Just as OCaml has procedures that take values and output values, OCaml has functors, which take modules and output modules. These are not inted to be used during the running of a program. Instead, these are used to create programs. As an example, consider the zero-sum game of perfect information, NIM. Initially, there is a pile of matches. To move, a player removes any number of matches from the pile. The losing player is the one who removes the final match. Let s say we want to create a module for Nim. However, we want someone to be able to take in a value for the initial number of matches in each pile. To do this, we can use a functor that looks like the following: module Nim = functor (I: sig val initial: int ) -> struct type which_player = P P type status = Win of which_player Draw Ongoing of which_player type state =... type move = int let initial_state =... I.initial... let legal_moves =... let other_player =... let game_status =... let next_state =... This way, we can create a game of Nim with any number of matches in the pile. For instance, if we wanted to create a game with matches, we could say

module NimGame = Nim(struct let initial = ) In addition to the initial game module, there is a HumanPlayer module and a Referee module, both of which are defined using functors. The signatures for both of these can be found of the lecture slides. To put each of these pieces together, the Referee must take in a GAME as well as two PLAYERs. Thus, we can initiate a game using the Referee signature between two HumanPlayers as follows: module Referee = functor (Game : GAME) (Player : PLAYER) (Player : PLAYER) struct module CurrentGame = Game let play_game () = function... module Ref = Referee (NimGame) (HumanPlayer(NimGame)) (HumanPlayer(NimGame)) Ref.play_game() However, with the above code, because each player takes in a game as well, it would be possible for you to input two players which were meant for separate games, which would result in errors. To fix this, we can change the module for Referee to the following: module Referee = functor (Game : GAME) (Player : PLAYER with module PlayerGame = Game) (Player : PLAYER with module PlayerGame = Game) struct module CurrentGame = Game let play_game () = function... Please let us know if you find any mistakes, inconsistencies, or confusing language in this or any other CS document by filling out the anonymous feedback form: http://cs.brown.edu/ courses/csci00/feedback.