diff --git a/notebooks/7_constraint_satisfaction_problems/images/1.png b/notebooks/7_constraint_satisfaction_problems/images/1.png new file mode 100644 index 00000000..250b0d8f Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/1.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/10.png b/notebooks/7_constraint_satisfaction_problems/images/10.png new file mode 100644 index 00000000..d5406a95 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/10.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/11.png b/notebooks/7_constraint_satisfaction_problems/images/11.png new file mode 100644 index 00000000..8bc3c467 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/11.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/12.png b/notebooks/7_constraint_satisfaction_problems/images/12.png new file mode 100644 index 00000000..7b46b5b0 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/12.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/13.png b/notebooks/7_constraint_satisfaction_problems/images/13.png new file mode 100644 index 00000000..bee9cb1e Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/13.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/14.png b/notebooks/7_constraint_satisfaction_problems/images/14.png new file mode 100644 index 00000000..eff8a174 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/14.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/2.png b/notebooks/7_constraint_satisfaction_problems/images/2.png new file mode 100644 index 00000000..b31689ca Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/2.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/3.png b/notebooks/7_constraint_satisfaction_problems/images/3.png new file mode 100644 index 00000000..4539397d Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/3.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/4.png b/notebooks/7_constraint_satisfaction_problems/images/4.png new file mode 100644 index 00000000..56e28b2b Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/4.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/5.png b/notebooks/7_constraint_satisfaction_problems/images/5.png new file mode 100644 index 00000000..e67aff2a Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/5.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/6.png b/notebooks/7_constraint_satisfaction_problems/images/6.png new file mode 100644 index 00000000..cea1395d Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/6.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/7.png b/notebooks/7_constraint_satisfaction_problems/images/7.png new file mode 100644 index 00000000..7f69adc2 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/7.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/8.png b/notebooks/7_constraint_satisfaction_problems/images/8.png new file mode 100644 index 00000000..8f22aa54 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/8.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/9.png b/notebooks/7_constraint_satisfaction_problems/images/9.png new file mode 100644 index 00000000..59d60e2d Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/9.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/AC3.png b/notebooks/7_constraint_satisfaction_problems/images/AC3.png new file mode 100644 index 00000000..63ae37d3 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/AC3.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/AC3lim.png b/notebooks/7_constraint_satisfaction_problems/images/AC3lim.png new file mode 100644 index 00000000..4f21a041 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/AC3lim.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/ForwardChecking.png b/notebooks/7_constraint_satisfaction_problems/images/ForwardChecking.png new file mode 100644 index 00000000..6498a02e Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/ForwardChecking.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/component.png b/notebooks/7_constraint_satisfaction_problems/images/component.png new file mode 100644 index 00000000..155d1ea5 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/component.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/ex1.png b/notebooks/7_constraint_satisfaction_problems/images/ex1.png new file mode 100644 index 00000000..a3dc774d Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/ex1.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/modular.jpg b/notebooks/7_constraint_satisfaction_problems/images/modular.jpg new file mode 100644 index 00000000..3424afbd Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/modular.jpg differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/prog.gif b/notebooks/7_constraint_satisfaction_problems/images/prog.gif new file mode 100644 index 00000000..72167c24 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/prog.gif differ diff --git a/notebooks/7_constraint_satisfaction_problems/images/sorted.png b/notebooks/7_constraint_satisfaction_problems/images/sorted.png new file mode 100644 index 00000000..99b91a60 Binary files /dev/null and b/notebooks/7_constraint_satisfaction_problems/images/sorted.png differ diff --git a/notebooks/7_constraint_satisfaction_problems/index.md b/notebooks/7_constraint_satisfaction_problems/index.md new file mode 100644 index 00000000..2af44e6d --- /dev/null +++ b/notebooks/7_constraint_satisfaction_problems/index.md @@ -0,0 +1,341 @@ +Constraint Satisfaction +============== +- [Constraint Satisfaction](#constraint-satisfaction) +- [Introduction](#introduction) +- [Examples](#examples) + - [Map-Coloring](#map-coloring) + - [Constraint Graph](#constraint-graph) + - [N-Queens](#n-queens) + - [Real World CSPs](#real-world-csps) +- [CSP Varieties](#csp-varieties) +- [Constraint Varieties](#constraint-varieties) +- [Converting n-ary CSP to binary CSP](#converting-n-ary-csp-to-binary-csp) +- [Standard Search Formulation (incremental)](#standard-search-formulation-incremental) +- [Backtracking Search](#backtracking-search) +- [Improving Backtrack](#improving-backtrack) + - [The Minimum Remaining Value (MRV)](#the-minimum-remaining-value-mrv) + - [Degree Heuristic](#degree-heuristic) + - [Least Constraining Value](#least-constraining-value) + - [Forward Checking](#forward-checking) + - [Constraint Propagation
](#constraint-propagation-div-idcp) + - [Arc consistency (AC3)
](#arc-consistency-ac3-div-idac3) + - [Extending to cases which have n-ary constraints
](#extending-to-cases-which-have-n-ary-constraints-div-idext) + - [Arc-Consistency limitations
](#arc-consistency-limitations-div-idacl) + - [k-Consistency
](#k-consistency-div-idkc) + - [Strong k-Consistency
](#strong-k-consistency-div-idskc) + - [Using problem structure
](#using-problem-structure-div-idps) +- [Summary](#summary) +- [References](#references) +# Introduction + +Try to the answer this problem: + +We want to find two countries that the language of one of them is Hungarian and the name of other one starts with the letter "A". + +You can see that answering this problem differs from other search problems. Here, at first you consider some **constraints** and instead of search whole countries, you search **locally** and only for the countries that may satisfy the constraints. + +**Constraint Satisfaction Problems** (CSPs) are problems like the one we saw earlier that rather than searching on all search states, we only search for particular states that satisfy constraints. This help us to use more efficient algorithms for search problems. + +**Constraint Satisfaction** is a technique that tries to solve a problem under certain constraints. A problem is solved when there is a solution which satisfy all constraints. + +In CSPs, we have some variables that we should declare some values from domain , and some constraints that need to be satisfy. + +# Examples +## Map-Coloring + +![Forward checking limits](images/1.png?raw=true) + +In this problem, we want to color all regions of Australia with three colors in a way which two adjacent regions must not have same colors. + +**Variables**: Western Australia, Northern Territory, South Australia, Queensland, New South Wales, Victoria, Tasmania + +**Domains**: + +**Constraints**: two adjacent regions must have two different colors. + +**Solution(s)**: all assignments with satisfying all constraints. + +For example: + + +![Forward checking limits](images/2.png?raw=true|width=60) + +But why we try to formulate a problem as a CSP format? One reason is that CSPs yields a natural representation for a wide variety of problems; so if we already have a CSP-solving system, it is easier to solve a problem using that rather than design a custom solution using another search technique. Also CSP solvers are generally faster than normal search algorithms. In map coloring for example, if we assign , for five neighbors only colors of green and red are available. Without CSP technique, we must consider assignments for five neighbors but by using CSP format, we never have to consider blue as a value, therefore we have only assignments. A 87% reduction! + +## Constraint Graph + +For binary CSPs, we use constraint graph. Binary CSP is a problem that each constraint relates to at most two variables. (For example in map coloring, in every step we are looking at 2 regions that can’t have same color.) The nodes of graph correspond to variables and a link connected to two nodes is a constraint that those variables participate in the constraint + +![Forward checking limits](images/3.png?raw=true) + +## N-Queens +Another famous Constraint Satisfaction Problem is N-Queens. In this problem, we want to put n-queens on a chess board in a way that no queen is able to treat another. In other words, there must be exactly one queen in each row or column or dimeter. All tiles of the board have either one queen or none. CSP formulation for this problem is as follow: + +**Variablex:** which represents a queen in row i and column j. + +**Domains:** \{0, 1\} + +**Constraint:** + + + + + + + + + + + +The variables, , represents a queen in row i and column j. The domain is binary because for every tile we can show if there is a queen or there is not. + +This problem is not a binary CSP because of the last constraint. We have every other constraint in the last one. + +![Forward checking limits](images/5.png?raw=true) + +The picture above shows a solved 8-Queens. + +## Real World CSPs +What we see so far, were some famous CSPs that may not deal with them in real world. Some real world CSPs are: + +- Assignment problems: e.g., Who teaches what class +- Timetabling problems: e.g., Which class is offered when and where? + - Hardware configuration +- Transportation scheduling + - Factory scheduling + - Circuit layout +- Fault diagnosis +- And… +Usually real-world problems involve real-valued variables. + +# CSP Varieties +Base on variables, we can classify CSPs into two parts: Discrete variables and Continuous variables. Discrete variables can also divide into two parts of Finite domain and Infinite domain. Our main focus is on discrete variables specially finite domain ones. +- Discrete variables: + - Finite domains: + - Size complete assignments. + - e.g., Boolean CSPs, incl. Boolean satisfiability (NP-complete). + - Infinite domains (integers, strings, etc.) + - e.g., job scheduling, variables are start/end days for each job. + - need a constraint langage, e.g., StartJob1 + 5 ≤ StartJob3. + - Linear constraints solvable, nonlinear undecidable. +- Continuous Variables: + - e.g., start / end times for Hubble Telescope observations. + - linear constraints solvable in poly time by LP methods. + +# Constraint Varieties +Based on constraints, we have different kinds of constraints. +- Unary: Constraints involve a single variable. +e.g., SA ≠ green +- Binary: Constraints involve pairs of variables. +e.g., SA ≠ WA +- High-Order: Constraints involve 3 or more variables. +e.g., cryptarithmetic column constraints +- Preferences: Soft constraints. +e.g., red is better than green. +Often represents by a cost for each variable assignment. +It is not a Constraint Satisfaction Problem, it is called Constrained Optimization Problem (COP). + +# Converting n-ary CSP to binary CSP +Is it possible to convert every n-ary problem (not binary constraints) to a binary CSP? + +Dual constraint graph is a graph which its vertices are not variables but constraints. The vertices are connected to each other if they have a variable in common. In other words, the arc between two constraints check if the common variables take the same value in both constraints. + +Consider n-ary CSP problem: + +**Variable:** + +**Domain:** + +**Constraint:** + + +Dual form of this problem with new constraint( be consistent in is as follow: + +![Forward checking limits](images/ex1.png?raw=true) + +# Standard Search Formulation (incremental) + +Now we want to come up with a general standard solution based on search technique then try to improve it and make it special for CSP. The first approach is a simple approach, partial state formulation in search. In this approach, states are defined by the values assigned so far. + +**Initial state:** the empty assignment, {} + +**Successor function:** assign a value to an unassigned variable that does not conflict with current assignment. If there is no legal assignment, then failure is output of function. + +**Goal state:** when the current assignment is complete. + +Note that for all CSPs, this formulation is the same. +We want to assign values to all n variables; therefore, the solution –if there is any- must be in depth n. So it’s reasonable to use DFS (Depth First Search) algorithm. + +In the initial state, we can choose n variables to assign with d, size of domain. So at the initial state, we will have nd branch factors, maximum successors of a node. Appling the same method to each one in the first layer, each node in depth 1 has + branch factors, so the maximum number of leaves is . + +# Backtracking Search +With backtracking, we can reduce the number of leaves. If we consider one order of assignment and continue that, we will get to solution because the variable assignments are commutative. + +E.g., the assignments , + is the same as . With this trick, each node needs to assign to only a single variable and reduce the number of leaves to . + +Depth-first search for CSPs with single variable assignments is called backtracking. The name is chosen because when the algorithm fails to assign a variable, it will go to previous depth and starts searching again. + +Backtracking search is the basic uniformed algorithm for CSPs and can solve n-queens for . + +```python +def Backtracking-Search(csp): + return Recursive-Backtracking ({}, csp) + +def Recursive-Backtracking(assignment, csp): + if assignment is complete: + return assignment + var = Select-Unassigned-Variable(Variables[csp], assignment, csp) + for value in Order-Domain-Values(var, assignment, csp): + if value is consistent with assignment given Constraints[csp]: + add {var = value} to assignment + result = Recursive-Backtracking(assignment, csp) + if result ≠ failure: + return result + remove {var = value} from assignment + return failure +``` + +Backtracking search tries to find acceptable values for all variables recursively. Returns solution if it finds any, otherwise if the last assignment is leading to conflict, it removes that value for that variable and try other values. If no value is accepted, it backtracks to the previous assignment and changes that. + +![backtrack gif](images/prog.gif?raw=true) + +# Improving Backtrack +Now we want to improve backtracking. These are four methods and ideas that help us to gain speed in backtracking search: +- Which variable should be assigned next? +- In what order should its values be tried? +- Can we detect inevitable failure early? +- Can we take advantage of problem structure? + +For each we will give an answer Let’s start from the first question. + +## The Minimum Remaining Value (MRV) +For the first question we introduce The Minimum Remaining Value (MRV). +This heuristic tells us which variable should be the next variable to be assigned. In each assignment, the possible values for the next assignment may be reduced due to the problem’s assignments. In map coloring, after coloring the first state, the neighbors cannot have the same value. If we assign randomly in each state, we might reach to a point where a variable becomes so limited that it can’t have any values. + +![MRV](images/10.png?raw=true) + +If we don’t use MRV and choose a variable randomly, at the last step in the picture, we may color the north-west region, there will be no available values for the southern region and we have to backtrack. Clearly, we don’t need to backtrack if we use MRV. + +## Degree Heuristic +At a tie-breaker situation in MRV, we may use Degree heuristic. Degree heuristic prioritize the variable with the most constraints on remaining variables. Like at the beginning of the problem, when there is no colored state. + +![MRV](images/11.png?raw=true) + +## Least Constraining Value +For the second question, we may use least constraining value. In this approach, for a given variable, it chooses the least constraining value: the one that rules out the fewest values in the remaining variables. + +![MRV](images/12.png?raw=true) + +In the above situation, if we assign the north west region with blue value, we will have no available value for the southern region but assigning it to red value, it allows to have an available value for the southern region and we can avoid failure. + +Note that in the previous heuristics, we try to find a dead end sooner but in the last one, we are doing the opposite. This contradictory is because in MRV and degree heuristic, we are choosing a variable to be assigned but in the least constraining value, we are choosing a value. Each variable has to assigned to a value in our search and we fail to assign a variable, we will get to failure inevitably. But there is no such obligation for values. In other words, a value can unassigned and not be use in a solution. + +Combining these heuristics, makes 1000 queens feasible. + +## Forward Checking + +Now we want to see if we can detect failure sooner. The idea is to keep track of remaining legal values for unassigned variables. It terminates search when there is no available value for any variable. + +![Forward checking limits](images/14.png?raw=true) + +In each state, we show the possible values for each variables. The first table is the first state. Then after two steps and choosing the variables WA and Q, the updated table will become the last table. + +## Constraint Propagation
+ +Forward checking method, detects failures in only one level higher than ordinary MRV. As a result, in many cases it fails to detect failures. + +![Forward checking limits](images/ForwardChecking.png?raw=true) + +For instance, In this example NT and SA can't be blue at the same time but Forward Checking doesn't detect that. + +Constraint Propagation method can detect failure when in a higher height. In order to explain this algorithm, we must first define **consistency** for an edge. + + edge is consistent iff for every value x in Domain of X, there exists some allowed (does not violate any constraint) y in Domain of Y. + +By making every edge consistent (if possible), Constraint Propagation causes many of non-allowed states (which violate constraints) not to appear in search. + +Consider coloring example. Suppose in allowed domain of X, Y, which are neighbors, remains {g, b, r},{g} respectively. In this situation, edge is not consistent because if we attribute value g to X, there remains no allowed option for Y. However If we **delete** g from domain of X, we can make this edge consistent. But we have to note that all edges which X exists as the destination, may become inconsistent. So for example if become inconsistent, one or more member of Domain of Z will be deleted and by continuing this process (spreading consistency over all edges) we can have a new *equivalent problem* which there exists *less members* in Domain of the variables and by deleting many states, we can save time. + +## Arc consistency (AC3)
+ + +One algorithm which is based on this concept is **AC-3**. (AC-3 Description) + +![Forward checking limits](images/AC3.png?raw=true) + + +This algorithm can reduce *search algorithms* time، +However, It takes time to only execute this algorithm alone. + + It takes time to execute Remove-Inconsistent-Value function and each edge may calls this function times and because there is edges it can lead to execution time overall. One solution is to execute AC-3 algorithm limited times. However, this trade-off still remains. + +## Extending to cases which have n-ary constraints
+ +To check consistency of a constraint in a n-ary case we have two options. One of them is to convert these constraints to binary constraints via the previous method or via performing intelligent methods. + +Another option is to divide variables into two categories via different methods (we can actually do this in different ways) and each time consider a member of the first category and check if there is a member in the second category which satisfies constraints or not. Then we can say this constraint is consistent. +As it seems the second method is more complex and leads to a combinatory problem. The first method is more efficient. + +## Arc-Consistency limitations
+ +Although this method makes algorithms more efficient, in many cases it **can’t** detect early failures. + +![AC3 limits](images/AC3lim.png?raw=true) + +For example, in this case all edges are consistent but it's obvious that we can't assign values to all nodes. + +One way to confront these problems is to use *“Strong k-Consistency”* concept. In order to define this concept, we must first define k-Consistency. + +## k-Consistency
+ + For each k nodes, any consistent assignment to k-1 can be extended to the k th node. We must note that checking some k-Consistencies which k is large, will have a high complexity. However, in our previous example if we check k = 2, we will see that we can detect failure. + +## Strong k-Consistency
+ +Includes 1-Consistency, …, k-Consistency. + +We must note that one **can’t** achieve (k-1)-Consistency from k-Consistency. That’s due to the fact that in order to have k-Consistency, it’s necessary to have k-1 consistent nodes (to expand to k) and if there is no k-1 consistent nodes, due to vacuous truth (in logic), we will have k-Consistency and obviously it’s possible that we don’t have (k-1)-Consistency. + +However, checking Strong k-Consistency **is not** an easy job(!) and has a high complexity. To the extent that Strong n-Consistency is equal to solving the problem without backtracking. That’s because we can choose any assignment to a variable and by 2-Consistency get to 2 variables. Then by 3-Consistency get to 3 variables and all the way up to n variables which is equivalent to finding the solution. + +## Using problem structure
+ +one of the ways we can use the problem structure is to see whether constraint graph has separated connected component or not. If it has connected components, then we can solve the problem by finding solution for each of components independently. + +![connected component](images/component.png?raw=true) + +Of course, in real problems we will not see cases like the previous example very often. But one of the cases which often occurs is when there is a modular structure in the graph. With some considerations, we can solve the problem for each module independently and achieve a better time complexity. + +**Modular Structure**: +in some subgraphs there are some dense connections which have sparse connections with other subgraphs, as in figure below: + +![connected component](images/modular.jpg?raw=true) + +Another way to use the problem structure is to see whether constraint graph is in tree form or not. If it is in tree form, we can solve the problem in which is way better than time complexity of a general case problem which is . To solve the problem, we first choose a node as the root of the graph and then we sort nodes from the highest to deepest, as in figure below: + +![connected component](images/sorted.png?raw=true) + +Then we delete all inconsistent values from node n to node 2. (In AC-3 language, we call Remove-Inconsistent function for node n to node 2). Because all edges are consistent, we can assign a value to (root) and then for each we will assign a value in order not to become inconsistent with respect to just its father. *Due to Arc-Consistency*, that’s possible. + +In cases which are almost tree form, there is a minimum cutset which includes a few members. In these cases, we can use *Conditioning method*. In this method, we first assign values to variables of the cutset in different ways. Then we solve the problem for other variables (which form a tree). If we consider c as the size of the cutset, this method includes value assignments and then solving problem for the remaining tree which we know it has time complexity. Hence, this method has + time complexity which is good for small c. + +# Summary +- CSPs are kind of problem with a set of variable/value pairs that represent a state. +These pairs represent the conditions of solution by a set of constraints on variables. +- Backtracking search is a form of depth first search that is commonly used for solving CSPs. +- Variable ordering and value selection heuristics help to improve backtracking. The minimum remaining variable and degree heuristics are methods for ordering variables and least constraining value heuristics decides which value should be try first. +- Forward checking is used to detect inevitable failure before we reach it. +- Tree-structured problems can be solved in linear time. +- Custset conditioning can make a general CSP structure to a tree-structured one. It is very efficient for small cutsets. +- Tree decomposition technique transform the CSP into a tree of subproblems. It is very efficient if tree width of the constraint graph is small. +- Time complexity of CSP is related to the structure of its constraint graph. + +# References +https://www.tutorialandexample.com/constraint-satisfaction-problems-in-artificial-intelligence/ + +Factor Graphs 1 - Constraint Satisfaction Problems | Stanford CS221: AI (Autumn 2019) + +https://cis.temple.edu/~giorgio/cis587/readings/constraints.html \ No newline at end of file diff --git a/notebooks/7_constraint_satisfaction_problems/matadata.yml b/notebooks/7_constraint_satisfaction_problems/matadata.yml new file mode 100644 index 00000000..96e24cfa --- /dev/null +++ b/notebooks/7_constraint_satisfaction_problems/matadata.yml @@ -0,0 +1,35 @@ +title: CSP # shown on browser tab + +header: + title: Constraint Satisfaction Problems # title of your notebook + description: Problems with constraints # short description of your notebook + +authors: + label: + position: top + content: + # list of notebook authors + - name: Maziar Shamsipour # name of author + role: Author # change this if you want + contact: + # list of contact information + - link: https://github.com/tandalalam + icon: fab fa-github + - name: Amirreza Bagheri # name of author + role: Author # change this if you want + contact: + # list of contact information + - link: https://github.com/AmBadAl + icon: fab fa-github + - name: Pouya Yousefy # name of author + role: Author # change this if you want + contact: + # list of contact information + - link: https://github.com/pooyay + icon: fab fa-github + +comments: + # enable comments for your post + label: false + kind: comments + diff --git a/notebooks/index.yml b/notebooks/index.yml index 1b2133c0..219dc5a5 100644 --- a/notebooks/index.yml +++ b/notebooks/index.yml @@ -14,6 +14,8 @@ notebooks: kind: S2021, LN, Notebook - notebook: notebooks/6_search_in_continuous_space/ kind: S2021, LN, Notebook + - md: notebooks/7_constraint_satisfaction_problems/ + kind: S2021, LN, Notebook - pdf: notebooks/7_CSP/index.pdf kind: S2021, LN, PDF - notebook: notebooks/8_adversarial_search/ @@ -54,4 +56,4 @@ notebooks: kind: S2021, LN, Notebook #- notebook: notebooks/17_markov_decision_processes/ - notebook: notebooks/18_reinforcement_learning/ - kind: S2021, LN, Notebook \ No newline at end of file + kind: S2021, LN, Notebook