sawine@9: \documentclass[a4paper, 10pt, pagesize, smallheadings]{article} sawine@9: \usepackage{graphicx} sawine@9: %\usepackage[latin1]{inputenc} sawine@9: \usepackage{amsmath, amsthm, amssymb} sawine@9: \usepackage{typearea} sawine@9: \usepackage{algorithm} sawine@9: \usepackage{algorithmic} sawine@9: \usepackage{fullpage} sawine@9: \usepackage{mathtools} sawine@9: \usepackage[all]{xy} sawine@9: \usepackage{tikz} sawine@9: \usepackage{tikz-qtree} sawine@9: \usetikzlibrary{decorations.pathmorphing} % noisy shapes sawine@9: \usetikzlibrary{fit} % fitting shapes to coordinates sawine@9: \usetikzlibrary{backgrounds} % drawin sawine@9: \usetikzlibrary{shapes,snakes} sawine@9: \addtolength{\voffset}{-20pt} sawine@13: \title{CSP Exercise 04 Solution} sawine@9: \author{Eugen Sawin} sawine@9: \renewcommand{\familydefault}{\sfdefault} sawine@9: \newcommand{\R}{\mathcal{R}} sawine@13: \newcommand{\N}{\mathbb{N}} sawine@14: \newcommand{\C}{\mathcal{C}} sawine@16: \newcommand{\bo}{\mathcal{O}} sawine@9: sawine@9: %\include{pythonlisting} sawine@9: sawine@9: \pagestyle{empty} sawine@9: \begin{document} sawine@9: \maketitle sawine@16: % sawine@13: \section*{Exercise 4.1} sawine@13: (a) The zebra problem is the constraint network $N=\langle V,D,C\rangle$ with sawine@9: \begin{align*} sawine@13: V=&(english,spanish,ukrainian,norwegian,japanese,\\ sawine@13: &red,green,ivory,yellow,blue\\ sawine@13: &dog,snail,fox,horse,zebra\\ sawine@13: &coffee,tea,milk,juice,water\\ sawine@13: &oldgold,kools,chesterfield,lucky,parliament)\\ sawine@13: D=&(D_v)_{v\in V}\text{ where } D_v=\left\{\begin{array}{l l} sawine@17: \{1\}, & \text{if }v = norwegian\\ sawine@17: \{3\}, & \text{if }v = milk\\ sawine@17: \{1, 2, 3, 4, 5\}, & \text{otherwise}\\ sawine@13: \end{array} \right.\\ sawine@13: R_{eq}=&\{(a,a)\mid a\in \N\}\\ sawine@13: R_{next}=&\{(a,b)\mid a,b\in\N, |a-b| = 1\}\\ sawine@13: R_{rightof}=&\{(a+1,a)\mid a\in \N\}\\ sawine@13: C=&\{R_{v_1, v_2\in\{english,spanish,ukrainian,norwegian,japanese\}}=(D_{v_1}\times D_{v_j})\setminus R_{eq},\\ sawine@13: &R_{v_1, v_2\in\{red,green,ivory,yellow,blue\}}=(D_{v_1}\times D_{v_j})\setminus R_{eq},\\ sawine@13: &R_{v_1, v_2\in\{dog,snail,fox,horse,zebra\}}=(D_{v_1}\times D_{v_j})\setminus R_{eq},\\ sawine@13: &R_{v_1, v_2\in\{coffee,tea,milk,juice,water\}}=(D_{v_1}\times D_{v_j})\setminus R_{eq},\\ sawine@13: &R_{v_1, v_2\in\{oldgold,kools,chesterfield,lucky,parliament\}}=(D_{v_1}\times D_{v_j})\setminus R_{eq},\\ sawine@13: &R_{english, red}=(D_{english}\times D_{red}) \cap R_{eq},\\ sawine@13: &R_{spanish, dog}=(D_{spanish}\times D_{dog}) \cap R_{eq},\\ sawine@13: &R_{coffee, green}=(D_{coffee}\times D_{green}) \cap R_{eq},\\ sawine@13: &R_{ukrainian, tea}=(D_{ukrainian}\times D_{tea}) \cap R_{eq},\\ sawine@13: &R_{oldgold, snail}=(D_{oldgold}\times D_{snail}) \cap R_{eq},\\ sawine@13: &R_{kool, yellow}=(D_{kool}\times D_{yellow}) \cap R_{eq},\\ sawine@13: &R_{lucky, juice}=(D_{lucky}\times D_{juice}) \cap R_{eq},\\ sawine@13: &R_{japanese, parliament}=(D_{japanese}\times D_{parliament}) \cap R_{eq},\\ sawine@13: &R_{chesterfield, fox}=(D_{chesterfield}\times D_{fox}) \cap R_{next},\\ sawine@13: &R_{yellow, horse}=(D_{yellow}\times D_{horse}) \cap R_{next},\\ sawine@13: &R_{norwegian, blue}=(D_{norwegian}\times D_{blue}) \cap R_{next},\\ sawine@13: &R_{green, ivory}=(D_{green}\times D_{ivory}) \cap R_{rightof}\} sawine@9: \end{align*} sawine@13: To answer the questions, the Norwegian drinks water and the Japanese owns the zebra. I have added the corresponding problem file in XCSP2.1 format to my project repository \emph{(xcsp2\_examples/zebra.xml)}.\\\\ sawine@13: (b) See figure 1 (names are abbreviated). sawine@9: \begin{figure}[h] sawine@9: \centering sawine@9: \tikzstyle{var}=[circle, sawine@9: draw=black!100, sawine@9: fill=black!0] sawine@9: \begin{tikzpicture}[>=latex,text height=1.5ex,text depth=0.25ex] sawine@13: \matrix[row sep=1.1cm,column sep=0.7cm] { sawine@13: \node(eng)[var]{$eng$}; &\node(spa)[var]{$spa$}; &\node(ukr)[var]{$ukr$}; &\node(nor)[var]{$nor$}; &\node(jap)[var]{$jap$};\\ sawine@13: \node(red)[var]{$red$}; &\node(gre)[var]{$gre$}; &\node(ivo)[var]{$ivo$}; &\node(yel)[var]{$yel$}; &\node(blu)[var]{$blu$};\\ sawine@13: \node(dog)[var]{$dog$}; &\node(sna)[var]{$sna$}; &\node(fox)[var]{$fox$}; &\node(hor)[var]{$hor$}; &\node(zeb)[var]{$zeb$};\\ sawine@13: \node(cof)[var]{$cof$}; &\node(tea)[var]{$tea$}; &\node(mil)[var]{$mil$}; &\node(jui)[var]{$jui$}; &\node(wat)[var]{$wat$};\\ sawine@13: \node(old)[var]{$old$}; &\node(koo)[var]{$koo$}; &\node(che)[var]{$che$}; &\node(luc)[var]{$luc$}; &\node(par)[var]{$par$};\\ sawine@9: }; sawine@9: \path[-] sawine@13: (eng) edge (red) sawine@13: (spa) edge[bend right=60] (dog) sawine@13: (cof) edge (gre) sawine@13: (ukr) edge (tea) sawine@13: (old) edge (sna) sawine@13: (koo) edge (yel) sawine@13: (luc) edge (jui) sawine@13: (jap) edge[bend left] (par) sawine@13: (che) edge[bend left] (fox) sawine@13: (yel) edge (hor) sawine@13: (nor) edge (blu) sawine@13: (gre) edge (ivo) sawine@13: sawine@13: (eng) edge (spa) sawine@13: (eng) edge[bend left] (ukr) sawine@13: (eng) edge[bend left] (nor) sawine@13: (eng) edge[bend left] (jap) sawine@13: (spa) edge (ukr) sawine@13: (spa) edge[bend right] (nor) sawine@13: (spa) edge[bend right] (jap) sawine@13: (ukr) edge (nor) sawine@13: (ukr) edge[bend left] (jap) sawine@13: (nor) edge (jap) sawine@13: sawine@13: (red) edge (gre) sawine@13: (red) edge[bend left] (ivo) sawine@13: (red) edge[bend left] (yel) sawine@13: (red) edge[bend left] (blu) sawine@13: (gre) edge (ivo) sawine@13: (gre) edge[bend right] (yel) sawine@13: (gre) edge[bend right] (blu) sawine@13: (ivo) edge (yel) sawine@13: (ivo) edge[bend left] (blu) sawine@13: (yel) edge (blu) sawine@13: sawine@13: (dog) edge (sna) sawine@13: (dog) edge[bend left] (fox) sawine@13: (dog) edge[bend left] (hor) sawine@13: (dog) edge[bend left] (zeb) sawine@13: (sna) edge (fox) sawine@13: (sna) edge[bend right] (hor) sawine@13: (sna) edge[bend right] (zeb) sawine@13: (fox) edge (hor) sawine@13: (fox) edge[bend left] (zeb) sawine@13: (hor) edge (zeb) sawine@13: sawine@13: (cof) edge (tea) sawine@13: (cof) edge[bend left] (mil) sawine@13: (cof) edge[bend left] (jui) sawine@13: (cof) edge[bend left] (wat) sawine@13: (tea) edge (mil) sawine@13: (tea) edge[bend right] (jui) sawine@13: (tea) edge[bend right] (wat) sawine@13: (mil) edge (jui) sawine@13: (mil) edge[bend left] (wat) sawine@13: (jui) edge (wat) sawine@13: sawine@13: (old) edge (koo) sawine@13: (old) edge[bend left] (che) sawine@13: (old) edge[bend left] (luc) sawine@13: (old) edge[bend left] (par) sawine@13: (koo) edge (che) sawine@13: (koo) edge[bend right] (luc) sawine@13: (koo) edge[bend right] (par) sawine@13: (che) edge (luc) sawine@13: (che) edge[bend left] (par) sawine@13: (luc) edge (par) sawine@9: ; sawine@9: \end{tikzpicture} sawine@13: \caption{(3.1b) primal constraint graph of $N$} sawine@9: \end{figure}\\ sawine@15: (c) No, $N$ is not arc-consistent. We provide the arc-consistent constraint network $N'=\langle V, D', C\rangle$ with sawine@13: \begin{align*} sawine@15: D'_{v}=\left\{ sawine@13: \begin{array}{l l} sawine@17: \{1\}, & \text{if }v = norwegian\\ sawine@17: \{3\}, & \text{if }v = milk\\ sawine@17: \{2\}, & \text{if }v = blue\\ sawine@17: \{3,4\}, & \text{if }v = ivory\\ sawine@17: \{4,5\}, & \text{if }v \in \{coffee,green\}\\ sawine@17: \{2,3,4\}, & \text{if }v = horse\\ sawine@17: \{3,4,5\}, & \text{if }v \in \{english,red\}\\ sawine@17: \{2,4,5\}, & \text{if }v \in \{ukrainian,tea\}\\ sawine@17: \{2,3,4,5\}, & \text{if }v \in \{spanish,japanese,dog,parliament\}\\ sawine@17: \{1,2,4,5\}, & \text{if }v \in \{juice,water,lucky\}\\ sawine@17: \{1,3,4,5\}, & \text{if }v \in \{yellow,kool\}\\ sawine@17: \{1, 2, 3, 4, 5\}, & \text{otherwise}\\ sawine@13: \end{array} \right.\\ sawine@13: \end{align*} sawine@14: That makes 32 domain values less. I've spent an hour and this, where my solver spent 1.5ms on this task. I'm glad we have the power to build machines for doing such tedious work instead of doing it by hand. sawine@14: sawine@14: \section*{Exercise 4.2} sawine@14: (a) We show that $Sol(\C) = Sol(\C')$ by contradiction. sawine@14: sawine@14: Let $\C=\langle V,D,C\rangle$ and $\C'=\langle V,D',C\rangle$. By definition each variable assignment $a(v_i)$ must be in its variable domain $D_i$, i.e., $a(v_i)\in D_i$. Therefore, a reduction of domains can only yield a network with less solutions. Since AC3 reduces domains, there can not be more solutions for $\C'$, i.e., $Sol(\C') \subseteq Sol(\C)$. sawine@14: sawine@15: Assume that solution $a\in Sol(\C)$ is lost after the domain reduction by AC3, i.e., $a\notin Sol(\C')$. WLOG it follows that at some iteration of AC3 the value $a(v_i)$ was removed from the domain $D_i'$, so it holds $a(v_i)\notin D_i'$. By the definition of the revise function of AC3, it holds that $D_i'\leftarrow D_i\cap\pi_i(R_{ij} \bowtie D_j)$. Since $a(v_i)$ is in $D_i$ but not in $D_i'$, it follows that $a(v_i)\notin\pi_i(R_{ij}\bowtie D_j) \implies (a(v_i),a(v_j))\notin(R_{ij}\bowtie D_j)$. sawine@15: sawine@15: The join $R_{ij}\bowtie D_j$ represents the set of all consistent assignments of variable $v_j$ over the relation $R_{ij}$. With $(a(v_i),a(v_j))\notin (R_{ij}\bowtie D_j)$ it follows that variable assignments $(a(v_i),a(v_j))$ are not consistent with the constraint over $R_{ij}$. It contradicts with our assumption that $a\in Sol(\C)$, because a solution must satisfy all constraints of the network. We have shown that there is no solution $a\in Sol(\C)$, such that $a\notin Sol(\C')$. \qed\\\\ sawine@15: % sawine@15: (b) To show that AC3 produces an arc-consistent network $\C'$ we consider three cases. The first case is trivial, given an arc-consistent network the revise function does not remove any domain values and therefore does not modify the network. sawine@15: sawine@15: Let $\C$ be a network with some not arc-consistent $R_{ij}$, i.e., there is some assignment a with $a(v_i)\in D_i$, $a(v_j)\in D_j$ and $(a(v_i),a(v_j))\notin (R_{ij}\bowtie D_j)$. Initially, AC3 does revise all variable pairs $(v_i,v_j)$ and $(v_j,v_i)$ with $(v_i,v_j)$ in some constraint's scope ($R_{ij}$). It follows that AC3 does revise $(v_i,v_j)$ in respect of $R_{ij}$ in some iteration and reduces $D_i'\leftarrow D_i\cap\pi_i(R_{ij}\bowtie D_j)$. Because $(a(v_i),a(v_j))\notin (R_{ij}\bowtie D_j)$ implies $a(v_i)\notin\pi_i(R_{ij}\bowtie D_j)$, it holds that $a(v_i)\notin D_i'$. This reduces the initial arc-inconsitency of $v_i$ relative to $v_j$. sawine@15: sawine@15: By the domain value reduction, AC3 can introduce new not arc-consistent constraints. Let $a(v_i)\in D_i$ be a value, that was removed by the revise function for constraint $R_{ij}$. Since the revise function changed $D_i$, AC3 will again revise all variable pairs $(v_k,v_i)$ with $k\neq i,k\neq j$ for all constraints $R_{ki}$. This removes all inconsistent values for all domains $D_k$,i.e., all $a(v_k)\in D_k$ with $a(v_k)\notin\pi_k(R_{ki}\bowtie D_i)$ are removed from $D_k$. All other constraints $R_{lm}$ with $m\neq i$ are not directly affected by the reduced domain $D_i$ and can therefore not become not arc-consistent by the revisal of $(v_i,v_j)$. sawine@15: sawine@15: We have shown, that all initial not arc-consistent constraints are made arc-consistent and the same holds for all newly introduced inconsistencies by the domain reduction. It follows that all remaining domains of $\C'$ form an arc-consistent network. \qed\\\\ sawine@15: % sawine@16: (c) All trivial assignments with complexity of $\bo(1)$ are left out of this analysis. Further it is assumed that set containment can be tested in $\bo(1)$, while is is only true for fully expanded sets with exponential space requirements. We can, however, archieve $\bo(1)^*$ using hash tables and amortized analysis in linear space. The natural tree-based approach yields $\bo(\log n)$. For the queue, we assume a stack is used with $\bo(1)$ insertion and removal (last inserted value). Let $n$ be the number of variables, all domains have size $\leq k$ and $e$ is the number of constraints. sawine@16: sawine@16: The initialisation of the counters consists of an iteration over all constraints $R_{ij}$ and values $a_i\in D_i$, $a_j\in D_j$, this takes $\Theta(e\cdot k^2)$ time. sawine@16: sawine@16: Next we initialise the set $S[v_j,a_j]$ with the supported tuples, adjust the counters and move unsupported tuples into $Q$ for each constraint $R_{ij}$ and values $a_i\in D_i$, $a_j\in D_j$, again this takes $\Theta(e\cdot k^2)$ time. We notice that each set $S[v_j,a_j]$ and $Q$ have at most $e\cdot k$ elements, also the counter value for any variable-value pair is $\leq e\cdot k$. sawine@16: sawine@18: The while loop needs some special treatment based on the observation that $|S[v_j,a_j]|+|Q|=e\cdot k$ and others. But, due to limited time, I have to skip this part this time. sawine@9: \end{document}