Greedy algorithms

Communication 1

Video of previous lectures:

  1. Introduction to the course (alternative link)

  2. Introduction to Computational Thinking (alternative link)

  3. Algorithms (alternative link)

  4. Laboratory 1 (alternative link)

  5. Computability (alternative link)

  6. Programming languages (alternative link)

  7. Organising information - ordered structures (alternative link)

  8. Laboratory 2 (alternative link)

  9. Brute-force algorithms (alternative link)

  10. Laboratory 3 (alternative link)

  11. Organising information - unordered structures (alternative link)

  12. Recursion (alternative link)

  13. Laboratory 4 (alternative link)

  14. Laboratory 5 (alternative link)

  15. Divide and conquer algorithms (alternative link)

  16. Laboratory 6 (alternative link)

  17. Dynamic programming algorithms (alternative link)

  18. Organising information: trees (alternative link)

  19. Backtracking algorithms (alternative link)

  20. Organising information: graphs (alternative link)

Communication 2

All the exam sessions are uploaded on AlmaEsami

You have to subscribe to the session you want to attend

Any question about the previous lecture?

Historic hero: Evelyn Berezin

She was a physicist and entrepreneur

She started to work in a company that produced digital computers, and then she founded her own company: Redactron Corporation

In this new company, she started to work on computer systems to simplify the work of secretaries

The main product was Data Secretary, the very first word processor in history

Greedy algorithms

At every stage of execution of a particular algorithm when we are seeking for possible candidates for constructing the solution to a computational problem, this approach makes always the choice that is optimal (i.e. the best one) in that particular moment

It is easy to come up with a greedy algorithm for a problem

An example

Computational problem: to give the change of a certain amount of euros in coins

A possible greedy approach:

  1. Consider the coins to choose for the change as ordered in a decrescent way, from the highest value (i.e. 2 euros) to the lowest one (i.e. 1 cent)

  2. For each kind of value, add in the candidate set of the solution as much coins of that value as possible until their sum is lesser than the remaining of the change to give

  3. Return the selected coins for the change

It cannot be used always

Sometimes the solution found, while it provides a correct solution to the problem, is just suboptimal - i.e. it is not the best one for solving the problem

For instance, if you are driving from Florence to Bologna, and, at a certain crossroad you find two signs indicating two different routes to get to Bologna

  1. left route: get to Bologna by travelling for 42 kilometers

  2. right route: get to Bologna by travelling for 56 kilometers

Greedy approach: go to left (1)

It cannot predict the existence of traffic in the left route

Characteristics of greedy

Greedy choice property: at a certain step, we can choose the best candidate for improving the set of candidates bringing to a solution - this chioce can be somehow driven by all the previous choices

The problem has an optimal substructure, i.e. optimal solution to a computational problem can be built by considering the optimal solutions to its subproblems

Line wrap

Computational problem: break a text into lines such that it will fit in the available width of a page

Ancillary methods

<string>.split(<string_separator>)

It returns a list of strings where each string in the list represents a word (or a token)

Example: "a b c".split(" ") returns the list ["a", "b", "c"]

<string_separator>.join(<list_of_strings>)

It returns a string composed by all the strings in the list separated by <string_separator>

Example: " ".join(["a", "b", "c"]) returns the string "a b c"

Line wrap: the algorithm

def line_wrap(text, line_width):
    result = []
    space_left = line_width
    line = []

    for word in text.split(" "):
        word_len = len(word)
        if word_len + 1 > space_left:
            result.append(" ".join(line))
            line = [word]
            space_left = line_width - word_len
        else:
            line.append(word)
            space_left = space_left - (word_len + 1)

    result.append(" ".join(line))
    return "\n".join(result)

END Greedy algorithms