Greedy Algorithms and Classes Fall 20151 Week 7

  • Slides: 29
Download presentation
Greedy Algorithms and Classes Fall 20151 Week 7 CSCI-141 Scott C. Johnson

Greedy Algorithms and Classes Fall 20151 Week 7 CSCI-141 Scott C. Johnson

Greedy Algorithms � Say we go to the bank to cash our paycheck ◦

Greedy Algorithms � Say we go to the bank to cash our paycheck ◦ We ask the teller for the fewest bills and coins as possible ◦ Moments later the teller gives us our money and we leave � In order to do this request the teller ran an algorithm

Greedy Algorithms � The teller’s algorithm ◦ Starts by choosing the highest bill/coin the

Greedy Algorithms � The teller’s algorithm ◦ Starts by choosing the highest bill/coin the teller can �Gets as many of these as possible ◦ Repeats this for each smaller bill/coin until the amount is made � In computer science we call this a greedy algorithm! ◦ Due to the fact that it chooses what it perceives is the optimal at the time of the choice

Greedy Algorithms � In this lecture we will make a greedy algorithm that: ◦

Greedy Algorithms � In this lecture we will make a greedy algorithm that: ◦ Will make change ◦ Can use different regional currency ◦ Each different kind of regional currency will be stored in a file �Each line of the file will represent a single coin denomination, containing a name and value

Greedy Algorithms � How the “Change Machine” will work ◦ Prompts the user for

Greedy Algorithms � How the “Change Machine” will work ◦ Prompts the user for the currency region ◦ Displays the coins for the region and their value ◦ It will sort the coins by value in a list �Smallest to largest ◦ Prompt the user for the amount of change to make ◦ If it is possible to make the change it will state it is possible �Otherwise it will state it is not possible ◦ If possible it will next show the resulting coins

Greedy Algorithms � Show the running program ◦ 687 using the currency for the

Greedy Algorithms � Show the running program ◦ 687 using the currency for the United States (“us”) �We can make any amount because we have a penny! ◦ Canada discontinued the penny �Therefore they cannot make 687

Greedy Algorithm � How can we represent coins in Python? ◦ Recall a coin

Greedy Algorithm � How can we represent coins in Python? ◦ Recall a coin has a name and a value ◦ The solution above showed two different types of things: �A Coin �Name as a string �Value as an integer �A Coin. Roll �Coin is an instance of some coin �Quantity of that coin as an integer

Greedy Algorithm � Can we use a list? ◦ We could have the values

Greedy Algorithm � Can we use a list? ◦ We could have the values of individual coins in a list �dollar = [“dollar-coin”, 100] �print(“Name: “, dollar[0]) �Name: dollar-coin �print(“Value: ”, dollar[1]) �Value: 100 �quarter = [“quarter”, 25] ◦ Then in another list store the count for each roll �eight. Bucks = [dollar, 8] �print(eight. Bucks) �[[‘dollar-coin’, 100], 8] �fifty. Cents = [quarter, 2] �print(fifty. Cents) �[[‘quarter’, 25], 2]

Greedy Algorithm � Then ◦ ◦ we can fill our sack Sack = []

Greedy Algorithm � Then ◦ ◦ we can fill our sack Sack = [] Sack. append(eight. Bucks) Sack. append(fifty. Cents) Sack �[[[‘dollar-coin’, 100], 8], [[‘quarter’, 25], 2 ]]

Greedy Algorithm � Or we can use a new Python item called a tuple

Greedy Algorithm � Or we can use a new Python item called a tuple ◦ A tuple is an immutable list ◦ Dollar = ( “dollar-coin”, 100) ◦ print(“Name: “, dollar[0]) �Name: dollar-coin ◦ print(“Value: “, dollar[1]) �Value: 100 � As you can see it is the same as a list, but it cannot be changed!

Greedy Algorithm � Can we use a tuple? ◦ We could have the values

Greedy Algorithm � Can we use a tuple? ◦ We could have the values of individual coins in a list �dollar = (“dollar-coin”, 100) �print(“Name: “, dollar[0]) �Name: dollar-coin �print(“Value: ”, dollar[1]) �Value: 100 �quarter = (“quarter”, 25) ◦ Then in another list store the count for each roll �eight. Bucks = (dollar, 8) �print(eight. Bucks) �((‘dollar-coin’, 100), 8) �fifty. Cents = (quarter, 2) �print(fifty. Cents) �((‘quarter’, 25), 2)

Greedy Algorithm � Then we can fill our sack ◦ Sack = ( eight.

Greedy Algorithm � Then we can fill our sack ◦ Sack = ( eight. Bucks, fifty. Cents) ◦ print(Sack) �[[[‘dollar-coin’, 100], 8], [[‘quarter’, 25], 2 ]] ◦ Sack[1] = ( dollar, 6) �Traceback (most recent call last): File ”<stdin>”, line 12, in <module> Type. Error: ‘tuple’ object does not support item assignment.

Greedy Algorithm � Another choice is a Named. Tuple ◦ You must import collections

Greedy Algorithm � Another choice is a Named. Tuple ◦ You must import collections to use it ◦ Coin = collections. namedtuple(“Coin”, [‘name’, ‘value’]) ◦ Coin(‘dime’, 10) �Coin(name=‘dime’, value=10) ◦ ten. Cents = Coin(‘dime’, 10) ◦ ten. Cents. name �‘dime’ ◦ ten. Cents. name = ‘d’ �Traceback (most recent call last): File ”<stdin>”, line 1, in <module> Attribute. Error: can’t set attribute. ◦ Coin(10, ‘dime’) �Coin(name=10, value=‘dime’)

Greedy Algorithms � Issues with lists, tuples, and nametuples 1. Feels unnatural to use

Greedy Algorithms � Issues with lists, tuples, and nametuples 1. Feels unnatural to use numeric indices when accessing the parts of an instance, what if you forget the number? 2. We cannot tell the difference between instances of different structures that have the same number iof parts 1. x = [‘BMW’, 1972] can be mistaken for a y = [‘dollar’, 100]… how do we tell which is a car and which is a coin? 3. Named. Tuple does over come this issue, but it has its own issues 1. What is someone swaps the two named parts values when creating it?

Greedy Algorithms � Classes: A name slot approach ◦ We can make our own

Greedy Algorithms � Classes: A name slot approach ◦ We can make our own unique types via classes ◦ Lets us make our own, user defined types ◦ Classes solve the issue of naming parts and distinguishing from other kinds of objects ◦ A class declares a type, a new kind of structure �This allows us to specify names for parts rather than numbers

Greedy Algorithms � Example class: ◦ Class Coin(): __slots__ = (‘name’, ‘value’) ◦ The

Greedy Algorithms � Example class: ◦ Class Coin(): __slots__ = (‘name’, ‘value’) ◦ The slots hold the names of all the parts �They are make via a tuple of strings ◦ To create a Coin one. Buck = Coin() one. Buck. name = ‘dollar’ one. Buck. value = 100 one. Buck. garbage = 1 Attribute. Error: ‘Coin’ has no attribute ‘garbage’

Greedy Algorithms � Issues with classes 1. The slots of a class can hold

Greedy Algorithms � Issues with classes 1. The slots of a class can hold any value �dime = Coin() dime. value = ‘dime’ amount = dime. value + 4 �Type. Error: unsupported operand type(s) for *: ‘str’ and ‘int’ 2. No easy way to print an object using the default print statement �dollar = Coin() dollar. name = ‘dollar’ dollar. value = 100 print(dollar) �< main. Coin object at 0 x 10067 a 6 c 8>

Greedy Algorithms � rit_lib: typed, Named Slot Approach ◦ Developed by the RIT CS

Greedy Algorithms � rit_lib: typed, Named Slot Approach ◦ Developed by the RIT CS dept ◦ Addresses the issues mentioned before ◦ Use: �from rit_lib import * class Coin( struct ): _slots = ( ( str, ‘name’ ), ( int, ‘value’ ) )

Greedy Algorithms � Steps to use the rit_lib approach: ◦ Import the rit_lib module.

Greedy Algorithms � Steps to use the rit_lib approach: ◦ Import the rit_lib module. �It is not part of the standard Python library �Add “from rit_lib import *” �Avoids having to write rit_lib over and over ◦ Add struct inside the parentheses on the line that begins the class definition �This means that the class inherits from the rit_lib struct �A class that inherits will get the implementations of all the functions for displaying instances of the class ◦ Specify the types and names of each of the slots using the _slots keyword �Not the same as __slots__ for the new class

Greedy Algorithms � Using the rit_lib method we can avoid lots of steps ◦

Greedy Algorithms � Using the rit_lib method we can avoid lots of steps ◦ We can create and initialize the item in one step � Called constructing an instance � We pass in the values in the order that the _slots items were added � Example ◦ one. Buck = Coin(‘dollar’, 100) buck = Coin() Type. Error: Constructor Coin() expected 2 arguments but got 0 print( one. Buck ) Coin( name: ‘dollar’, value: 100) print( one. Buck. value ) 100 one. Buck. value = 99 one. Buck. value = ‘dollar’ Type. Error: Type of quantity should be int, not str print( one. Buck ) Coin( name: ‘dollar’, value: 100)

Greedy Algorithms � We know we can represent a coin with rit_lib ◦ What

Greedy Algorithms � We know we can represent a coin with rit_lib ◦ What about a Coin. Roll? � Recall � a Coin. Roll represents a number of coins from rit_lib import * class Coin. Roll( struct ): _slots = ( ( Coin, ‘Coin’), ( int, ‘qty’) ) one. Buck = Coin( ‘; dollar’, 100) six. Bucks = Coin. Roll( one. Buck, 6) print( six. Bucks ) Coin. Roll ( coin: Coin( name: ‘dollar’, value: 100), qty: 6 )

Greedy Algorithms � Now we know how to represent Coins and Coin. Rolls using

Greedy Algorithms � Now we know how to represent Coins and Coin. Rolls using rit_lib ◦ We will use that for our problem

Greedy Algorithms � High 1. 2. 3. 4. 5. Level Pseudocode for the Algorithm:

Greedy Algorithms � High 1. 2. 3. 4. 5. Level Pseudocode for the Algorithm: Enter loop and print a banner Prompt for a currency file Tell the exchange to read the file Tell the exchange to print the currency information Enter an inner loop to: 1. Prompt user for an amount to change, break out if nothing or less than 1 was entered 2. Ask the exchange to handle the request’ 3. Report the results of the request 4. Continue the loop 6. Thank the user and end the program

Greedy Algorithm � Implementation ◦ change. py �The main module responsible for creating the

Greedy Algorithm � Implementation ◦ change. py �The main module responsible for creating the exchange and interacting with the user ◦ exchange. py �This is the “change machine”. �Creates the coins and coinrolls �Reads the file to get the info �Makes the change from the coins and rolls if possible �Reports the results � To the code!

Greedy Algorithm � Time Complexity ◦ What is the time complexity? � Since we

Greedy Algorithm � Time Complexity ◦ What is the time complexity? � Since we use an insertion sort to sort the coins O(n 2) for the sort � handle. Request runs N times where N is the number of unique coin types, O(N) � The cost of displaying the result is a loop thru all coins and rolls, O(n) � Therefore overall we have O(n 2) + O(n) + O(N) == O(n 2)

Greedy Algorithm � Testing ◦ We have seen cases where: �Change can be always

Greedy Algorithm � Testing ◦ We have seen cases where: �Change can be always made with fewest amount of coins (US) �Change cannot always be made (Canada) ◦ Is there a case where this machine will fail to make coins even though it is possible? ◦ Lets look at the fictional country of Gormandy �Coins: grabby 9, glutton 11, trieski 3 �Lets try to make change for 18… �We can do this with 2 grabby… �Lets run our machine and see what happens…

Greedy Algorithms � The machine failed to make change!!! ◦ Why? ? ? �

Greedy Algorithms � The machine failed to make change!!! ◦ Why? ? ? � Recall ◦ ◦ � If the algorithm is greedy… If first takes glutton, gets one, leaving 7 Next it tries grabby, and takes none, leaving 7 Next it trieski, and takes 2, leaving 1 It fails because there are no ways to make 1 the algorithm was not greedy and choose not to use the glutton it would have made change with the grabby.

Greedy Algorithms � There is another case to consider… ◦ It makes change but

Greedy Algorithms � There is another case to consider… ◦ It makes change but not the fewest number of coins ◦ This can happen when making change in madmax for 10! ◦ Coins: spark-plug 1, gasoline 7, battery 5 ◦ Recall it is greedy: �First takes 1 gasoline, leaving 3 �Next it takes no battery, leaving 3 �Finally it takes 3 spark-plug, leaving 0 �It makes the change in 4 coins… �But could have done it in 2 if it took two battery

Greedy Algorithms � What you need to know ◦ Takes largest first, then works

Greedy Algorithms � What you need to know ◦ Takes largest first, then works down ◦ It is often simple and sometime optimal ◦ There is no guarantee it will be able to produce and optimal result �or any result at all!