Mathematical thinking is crucial in all areas of computer science: algorithms, bioinformatics, computer graphics, data science, machine learning, etc. In this course, we will learn the most important tools used in discrete mathematics: induction, recursion, logic, invariants, examples, optimality. We will use these tools to answer typical programming questions like: How can we be certain a solution exists? Am I sure my program computes the optimal answer? Do each of these objects meet the given requirements?
In the course, we use a try-this-before-we-explain-everything approach: you will be solving many interactive (and mobile friendly) puzzles that were carefully designed to allow you to invent many of the important ideas and concepts yourself.
Prerequisites:
1. We assume only basic math (e.g., we expect you to know what is a square or how to add fractions), common sense and curiosity.
2. Basic programming knowledge is necessary as some quizzes require programming in Python.
Do you have technical problems? Write to us: coursera@hse.ru

KL

The course is excellent and most stuff is being taught in a nicely presented way. The main disappointment is 15-puzzle, because it's too difficult to understand without proper material.

DG

Jun 30, 2018

Filled StarFilled StarFilled StarFilled StarFilled Star

Love the quality of thought that goes into each lesson. The professors speak with acute clarity and really demonstrate and empathy for the student to truly understand the topics!

レッスンから

How to Find an Example?

How can we be certain that an object with certain requirements exist? One way to show this, is to go through all objects and check whether at least one of them meets the requirements. However, in many cases, the search space is enormous. A computer may help, but some reasoning that narrows the search space is important both for computer search and for "bare hands" work. In this module, we will learn various techniques for showing that an object exists and that an object is optimal among all other objects. As usual, we'll practice solving many interactive puzzles. We'll show also some computer programs that help us to construct an example.

講師

Alexander S. Kulikov

Visiting Professor

Michael Levin

Lecturer

Vladimir Podolskii

Associate Professor

字幕

Now, when you know what backtracking is, you will have a chance of using this powerful method to solve another challenging puzzle which is called 16 Diagonals. The goal in this puzzle is to place many diagonals into a square grid such that no two diagonals have a common point, or in other words, they do not touch each other. So we start with a very simple version of this puzzle. In this case we are given a three by three grid and our goal is to place six diagonals in this grid. It is not very difficult for this case, so you see one solution here on this slide. And this is another solution, where again, we have six diagonals, and no two have any common point. Now let's gradually increase the size. Let's consider a four by four board. Now, the question is to place ten diagonals. It is already not so simple, but here you are. This is a situation where there are 10 diagonals. And now we come to a challenge. In this case we are given a five by five grid, and our goal is to place 16 diagonals. You may want to first, place such 16 diagonals by hand and you will find out that it is not so easy. So instead of trying to do this by hand you may also want to implement a backtracking procedure. This is your exercise, actually. And this is a suggestion for you. So, to implement that backtracking program for solving this puzzle, you may want to do the following: So consider your five by five grid. So this is 25 cells, which are initially empty, or, to be more formal, let's assume that initially we have minus one in all these cells. Minus one indicates that we haven't yet decided what to put into all these cells. And then we start processing all these cells one by one. Say you start from the first row and you first consider all the first row and the second row, and the third one and so on. So for each cell, for the current cell you do the following: You consider all possibilities for this cell. Either it has a diagonal which goes from this corner to this corner, or you consider a diagonal which goes from this corner to this corner, or you consider a case where there is no diagonal in this case. So for example, you may store just an array of 25 cells where, in each cell you store either minus one, which means that you haven't yet decided what to put into this cell, or, for example zero, which corresponds to the fact that there is no diagonal in this case, or one if there is a diagonal that went from this corner to this corner, or two if there is a diagonal going from this corner to this corner. Finally, when you place a new diagonal, when you fill in a new cell, if you place a new diagonal into this cell, you need to check whether it produces any conflict, whether it touches any other diagonal. And this should be implemented very carefully. And if it doesn't touch, then you continue trying to extend it. If it touches, you stop immediately and you backtrack. OK? Well good luck implementing this program.