<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.2">Jekyll</generator><link href="https://arnaudcasteigts.net/feed.xml" rel="self" type="application/atom+xml" /><link href="https://arnaudcasteigts.net/" rel="alternate" type="text/html" /><updated>2026-04-07T10:19:34+02:00</updated><id>https://arnaudcasteigts.net/feed.xml</id><title type="html">Arnaud Casteigts</title><subtitle>nothing special</subtitle><entry><title type="html">Langages formels (11X003)</title><link href="https://arnaudcasteigts.net/teaching/langages-formels/" rel="alternate" type="text/html" title="Langages formels (11X003)" /><published>2025-09-15T16:44:46+02:00</published><updated>2025-09-15T16:44:46+02:00</updated><id>https://arnaudcasteigts.net/teaching/langages</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/langages-formels/"><![CDATA[<p>Enseignant : Arnaud Casteigts<br />
Assistant : Alexandre-Quentin Berger et Margaux Marseloo<br />
Monitrices : Naziha Beghdadi et Elie Bussod</p>

<h1 id="autres-pages-du-cours">Autres pages du cours</h1>
<ul>
  <li>sur <a href="https://moodle.unige.ch/course/view.php?id=5946">moodle</a> (supports, informations, modalités d’examens, etc.)</li>
  <li>sur <a href="https://pgc.unige.ch/main/teachings/details/2025-11X003">unige</a> (informations administratives)</li>
</ul>

<h1 id="notes-de-cours">Notes de cours</h1>

<p>Les notes de cours sont déposées ici (et sur Moodle) au fur et à mesure du semestre. Les séries d’exercices ne sont que sur Moodle.</p>

<ul>
  <li>Préambule au module <a href="/files/langages-1-slides-2025.pdf">[slides]</a></li>
  <li>Cours 1 : Concepts de base <a href="/files/langages-1-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-1-quiz-2025.pdf">[quiz]</a></li>
  <li>Cours 2 : Automates finis déterministes <a href="/files/langages-2-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-2-quiz-2025.pdf">[quiz]</a> - <a href="/files/langages-2-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 3 : Non-déterminisme <a href="/files/langages-3-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-3-quiz-2025.pdf">[quiz]</a> - <a href="/files/langages-3-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 4 : Expressions régulières <a href="/files/langages-4-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-4-quiz-2025.pdf">[quiz]</a> - <a href="/files/langages-4-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 5 : Lemme de l’étoile <a href="/files/langages-5-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-5-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 6 : Grammaires formelles <a href="/files/langages-6-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-6-quiz-2025.pdf">[quiz]</a> - <a href="/files/langages-6-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 7 : Automates à pile <a href="/files/langages-7-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-7-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 8 : Équivalence AP - GHC <a href="/files/langages-8-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-8-quiz-2025.pdf">[quiz]</a> - <a href="/files/langages-8-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 9 : Lemme de l’étoile hors-contexte (et au delà) <a href="/files/langages-9-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-9-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 10 : Machines de Turing <a href="/files/langages-10-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-10-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 11 : Machines de Turing Non-déterministes (et autres) <a href="/files/langages-11-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-11-slides-2025.pdf">[personnage du jour]</a></li>
  <li>Cours 12 : Universalité et Indécidabilité <a href="/files/langages-12-cours-2025.pdf">[notes de cours]</a> - <a href="/files/langages-12-slides-2025.pdf">[personnage du jour]</a></li>
</ul>

<h1 id="pour-aller-plus-loin">Pour aller plus loin</h1>
<p>Une partie du cours s’inspire de “Introduction to the Theory of Computation (Michael Sipser)”. D’autres parties sont composées à partir de ressources variées, dont certains articles Wikipédia. Vous pouvez aussi consulter les notes de cours des années précédentes sur <a href="/teaching/langages-formels-archive/">cette page</a>.</p>]]></content><author><name></name></author><category term="Teaching" /><category term="LF" /><summary type="html"><![CDATA[Enseignant : Arnaud Casteigts Assistant : Alexandre-Quentin Berger et Margaux Marseloo Monitrices : Naziha Beghdadi et Elie Bussod]]></summary></entry><entry><title type="html">STGen: A generator of simple and proper temporal graphs</title><link href="https://arnaudcasteigts.net/blog/stgen.html" rel="alternate" type="text/html" title="STGen: A generator of simple and proper temporal graphs" /><published>2024-07-02T13:44:46+02:00</published><updated>2024-07-02T13:44:46+02:00</updated><id>https://arnaudcasteigts.net/blog/stgen</id><content type="html" xml:base="https://arnaudcasteigts.net/blog/stgen.html"><![CDATA[<p>(Last updated: July 15, 2024.)</p>

<h1 id="table-of-content">Table of content</h1>
<p><a href="#overview-of-stgen">Overview</a>  |  <a href="#how-to-use-stgen">How to use STGen</a>  |  <a href="#parallel-iterators">Parallel iterators</a>  |  <a href="#the-tgraph-class">The TGraph class</a>  |  <a href="#how-to-cite-stgen">How to cite STGen</a></p>

<h1 id="overview-of-stgen">Overview of STGen</h1>

<p>A temporal graph is <em>simple</em> if every edge has a single time label. It is <em>proper</em> if two edges incident to a same vertex have different time labels. If a graph is both proper and simple, we call it <em>happy</em>.</p>

<center>
  <img src="/assets/blog/simple-proper.png" alt="Simple and proper" />
  <p class="caption">Fig. 1. From left to right: Non-proper and non-simple; Proper and non-simple; Simple and non-proper; Simple and proper (happy).</p>
</center>

<p>STGen enumerates all happy temporal graphs, up to isomorphism. The notion of isomorphism here also considers as identical all the graphs whose <em>local ordering</em> of the edges is the same. For example, in Fig. 2, the left and middle graphs are equivalent in the sense that their temporal paths are in bijection.</p>

<center>
  <img src="/assets/blog/representative.png" alt="Representative of isomorphism types" />
  <p class="caption">Fig. 2. Canonical representatives of happy temporal graphs.</p>
</center>

<p>The graph on the right is, among all the graphs in the same equivalence class, the one that uses the lowest possible time labels. Up to standard (i.e. static) isomorphism of labeled graphs, this graph is unique, and can thus be seen as the canonical <em>representative</em> of this class of happy graphs.</p>

<p>STGen actually generates all (and only) such canonical representatives. For a fixed number of vertices n, these graphs are in finite number and can be enumerated. Unfortunately, their number still grows essentially like \({n \choose 2}!\). One may hope for manipulating graphs of order up to 7 (or perhaps 8, if complete enumeration is not required), but enumerating significant fractions of larger graphs seems out of reach.</p>

<p>To get an idea of the growth, here are the numbers of representatives on 3, 4, 5, 6, and 7 vertices:</p>

<table>
  <thead>
    <tr>
      <th>n</th>
      <th># Happy graphs (representatives)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>3</td>
      <td>4</td>
    </tr>
    <tr>
      <td>4</td>
      <td>62</td>
    </tr>
    <tr>
      <td>5</td>
      <td>15378</td>
    </tr>
    <tr>
      <td>6</td>
      <td>89769096</td>
    </tr>
    <tr>
      <td>7</td>
      <td>13725757879376</td>
    </tr>
  </tbody>
</table>

<p><br />
Number of <em>temporal cliques</em> (complete happy graphs on n vertices):</p>

<table>
  <thead>
    <tr>
      <th>n</th>
      <th># Happy cliques (representatives)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>3</td>
      <td>1</td>
    </tr>
    <tr>
      <td>4</td>
      <td>20</td>
    </tr>
    <tr>
      <td>5</td>
      <td>4524</td>
    </tr>
    <tr>
      <td>6</td>
      <td>23218501</td>
    </tr>
    <tr>
      <td>7</td>
      <td>3106952711040</td>
    </tr>
  </tbody>
</table>

<p><br />
The numbers for n=8 are unknown. Still, some properties on happy graphs of order 8 can be tested exhaustively, thanks to a branch-cutting mechanism in the generation (see below).</p>

<h1 id="the-generation-tree">The generation tree</h1>

<p>STGen relies on a generation tree, each node of which is a happy graph that contains its parent as a proper subgraph. The root of the tree is the empty graph on n vertices. The set of successors of a graph corresponds to all the possible ways to add the next time label to this graph, up to isomorphism (see Figure 2), while remaining a valid representative – among other things, this implies that edge can receive label t <em>only if</em> it is adjacent to an edge having label t-1 (contiguity lemma).</p>

<center>
  <img src="/assets/blog/generation.png" width="90%" alt="Simple and proper" />
  <p class="caption">Fig. 3. (Top of) the generation tree for n=4.</p>
</center>

<p>This monotonous assignment of time labels is what guarantees that isomorphism types are separated forever down the tree (green separation lines on the Figure). Indeed, if two graphs are different at a certain stage, then their successors will always remain separated due to the already assigned labels.</p>

<p>Interestingly, the same property also guarantees that once a graph becomes <em>rigid</em>, i.e., it has no non-trivial automorphisms, then none of its successors will be symmetric again. Thus, there is an irrevocable boundary in the generation tree between symmetric graphs (in the top of the tree) and rigid graphs (below the boundary) – see the red line in Figure 3.</p>

<p>In both cases, each successor is characterized by a unique set of independent new edges (a matching in the complement graph) to which the next label is assigned. (Why a matching? because happy graphs are proper!) When the graph is symmetric, STGen ensures that no two such matchings are equivalent up to automorphisms (in the parent graph), which guarantees unicity among the successors. For rigid graphs, this property is ensured without caring about automorphisms, making the generation very fast.</p>

<h1 id="how-to-use-stgen">How to use STGen</h1>

<h2 id="installation">Installation</h2>

<p>You can download STGen as a single <a href="/files/stgen-with-example.zip">zip file</a> or clone it from its <a href="https://github.com/acasteigts/STGen">github repository</a>. The folder contains a minimal working example (in the <code class="language-plaintext highlighter-rouge">main.cpp</code> file) described next. You need to have a reasonably recent C++ compiler (e.g. at least g++-11). If you want to use the parallel iterators, you also need to have a TBB implementation installed in your system (e.g. <code class="language-plaintext highlighter-rouge">sudo apt install libtbb12</code> or <code class="language-plaintext highlighter-rouge">sudo apt install libtbb2</code> depending on your version of C++, as well as <code class="language-plaintext highlighter-rouge">sudo apt install libtbb-dev</code>). The suggested compilation line, also present in the Makefile, is:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>g++ <span class="nt">-O3</span> main.cpp <span class="nt">-o</span> main <span class="nt">-ltbb</span> <span class="nt">-march</span><span class="o">=</span>native
</code></pre></div></div>
<p>The last two arguments are optional: <code class="language-plaintext highlighter-rouge">-ltbb</code> if you want STGen to use parallelism, <code class="language-plaintext highlighter-rouge">-march=native</code> for better performance (but less portability).</p>

<h2 id="basic-examples">Basic examples</h2>
<p>Using STGen is pretty straightforward. You must declare a <code class="language-plaintext highlighter-rouge">TGraphIterator</code>, giving as template parameter the desired number of vertices and as argument a user-defined function to which STGen will pass every generated graph.
Here is a complete example that simply counts the number of happy graphs on 6 vertices:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">"stgen/stgen.h"</span><span class="cp">
</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">N</span> <span class="o">=</span> <span class="mi">6</span><span class="p">;</span>

<span class="k">using</span> <span class="k">namespace</span> <span class="n">stgen</span><span class="p">;</span>

<span class="kt">bool</span> <span class="nf">count_all</span><span class="p">(</span><span class="k">const</span> <span class="n">TGraph</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;&amp;</span> <span class="n">g</span><span class="p">,</span> <span class="kt">int64_t</span><span class="o">&amp;</span> <span class="n">nb</span><span class="p">){</span>
    <span class="n">nb</span><span class="o">++</span><span class="p">;</span> <span class="c1">// count this graph</span>
    <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="c1">// generate the successors</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="n">main</span><span class="p">(){</span>
    <span class="n">TGraphIterator</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">iter</span><span class="p">(</span><span class="n">count_all</span><span class="p">);</span>
    <span class="kt">int64_t</span> <span class="n">nb</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="n">execute</span><span class="p">();</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">nb</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">time</span> ./main 
89769096

real	0m2,647s
</code></pre></div></div>

<p>In this case, we implemented a basic function called <code class="language-plaintext highlighter-rouge">count_all()</code> (it could have any name) that consists of counting every graph and doing nothing else. More generally, the arguments of this function are the graph being visited (<code class="language-plaintext highlighter-rouge">const TGraph&lt;N&gt;&amp; g</code>) and a number (<code class="language-plaintext highlighter-rouge">int64_t&amp; nb</code>) that can be incremented or not depending on what we want to count (you can ignore it, if you don’t want to count anything). Your return value must indicate to STGen whether it should generate the successors of that graph (<code class="language-plaintext highlighter-rouge">true</code>) or cut this branch of the tree (<code class="language-plaintext highlighter-rouge">false</code>). Cutting branches is crucial if you manipulate happy graphs on more than 6 vertices.</p>

<p>Here is another example that counts all happy <em>cliques</em>:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">"stgen/stgen.h"</span><span class="cp">
</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">N</span> <span class="o">=</span> <span class="mi">6</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">M</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="o">*</span><span class="p">(</span><span class="n">N</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span>

<span class="k">using</span> <span class="k">namespace</span> <span class="n">stgen</span><span class="p">;</span>

<span class="kt">bool</span> <span class="nf">count_cliques</span><span class="p">(</span><span class="k">const</span> <span class="n">TGraph</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;&amp;</span> <span class="n">g</span><span class="p">,</span> <span class="kt">int64_t</span><span class="o">&amp;</span> <span class="n">nb</span><span class="p">){</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">g</span><span class="p">.</span><span class="n">nb_edges</span> <span class="o">==</span> <span class="n">M</span><span class="p">){</span>
        <span class="n">nb</span><span class="o">++</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="n">main</span><span class="p">(){</span>
    <span class="n">TGraphIterator</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">iter</span><span class="p">(</span><span class="n">count_cliques</span><span class="p">);</span>
    <span class="kt">int64_t</span> <span class="n">nb</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="n">execute</span><span class="p">();</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">nb</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">time</span> ./main 
23218501

real	0m2,541s
</code></pre></div></div>

<p>Let’s say we now want all the cliques whose lifetime (i.e. maximum label) is at most 8. The corresponding function could be as follows:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">bool</span> <span class="nf">count_cliques_lifetime_at_most_8</span><span class="p">(</span><span class="k">const</span> <span class="n">TGraph</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;&amp;</span> <span class="n">g</span><span class="p">,</span> <span class="kt">int64_t</span><span class="o">&amp;</span> <span class="n">nb</span><span class="p">){</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">g</span><span class="p">.</span><span class="n">lifetime</span> <span class="o">&gt;</span> <span class="mi">8</span><span class="p">){</span>
        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="c1">// cut the subtree</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">g</span><span class="p">.</span><span class="n">nb_edges</span> <span class="o">==</span> <span class="n">M</span><span class="p">){</span>
            <span class="n">nb</span><span class="o">++</span><span class="p">;</span> <span class="c1">// or do anything else here on those cliques</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="n">main</span><span class="p">(){</span>
    <span class="n">TGraphIterator</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">iter</span><span class="p">(</span><span class="n">count_cliques_lifetime_at_most_8</span><span class="p">);</span>
    <span class="kt">int64_t</span> <span class="n">nb</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="n">execute</span><span class="p">();</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">nb</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">time</span> ./main 
134764

real	0m0,533s
</code></pre></div></div>

<p>As we can see here, the generation is faster, because all the graphs whose lifetime exceed 8 have been cut off (together with their subtrees).</p>

<h1 id="parallel-iterators">Parallel iterators</h1>

<p>STGen offers two parallel iterators, depending on your needs: <code class="language-plaintext highlighter-rouge">TGraphParIterator</code> (basic) and <code class="language-plaintext highlighter-rouge">TGraphBatchIterator</code> (advanced). Both are similar in terms of performance, their differ only in their simplicity (versus scaling abilities). The basic version is appropriate if you are targetting graphs of up to 7 vertices and intend to run the experiment in one shot on a single computer. In contrast, the batch iterator allows you to split the work into several batches to be executed independently on several computers (possibly at different times), which is often necessary if you target graphs of 8 or more vertices. It may also be more appropriate for some experiments on 7 vertices, if your computation is heavy and/or does not cut many branches.</p>

<h2 id="the-tgraphpariterator-iterator">The <code class="language-plaintext highlighter-rouge">TGraphParIterator</code> iterator</h2>

<p>This iterator is used exactly in the same way as the standard <code class="language-plaintext highlighter-rouge">TGraphIterator</code>. Simply replace the type in the declaration. For example,</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span>
    <span class="n">TGraphParIterator</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">iter</span><span class="p">(</span><span class="n">count_cliques_lifetime_at_most_8</span><span class="p">);</span>
    <span class="kt">int64_t</span> <span class="n">nb</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="n">execute</span><span class="p">();</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">nb</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">time</span> ./main 
134764

real	0m0,150s
</code></pre></div></div>
<p>Using this iterator gives a much faster execution (here, on my 6-core computer). You need not worry about race conditions for the function parameters. In particular, the <code class="language-plaintext highlighter-rouge">nb</code> variable is local to each subtree and never shared among threads.</p>

<p>You probably do not need to understand how this iterator works internally. But since you are curious: First, the top of the tree (part above the red line in Figure 3) is processed on a single cpu, storing the boundary graphs (first graphs to be rigid) in a collection. Then, the subtrees of each of these graphs are processed in parallel and independently, exploiting whichever cpu is available on your computer (summing up the resulting <code class="language-plaintext highlighter-rouge">nb</code> variables in a map reduce fashion). Note that, up to 7 vertices, the top of the tree is computed almost instantaneously, but this is not the case for 8 vertices.</p>

<h2 id="the-tgraphbatchiterator-iterator">The <code class="language-plaintext highlighter-rouge">TGraphBatchIterator</code> iterator</h2>

<p>An experiment on graphs of 8 or more vertices is likely to be impractical on a single computer, even if it has many cores. The batch iterator makes it possible to split the work into a collection of batches, each of which can be executed independently and at different times.</p>

<p>Technically, the work is split according to a two-level hierarchy. First, a small subset of the top of the tree is generated using a single thread. Each graph along the resulting boundary (this time, higher than the red line in Figure 3) is seen as a separate batch, with a unique batch number. Every batch can then be executed independently, by specifying the batch number. The execution of an individual batch follows the same mechanism as the basic parallel iterator: the top of the batch is executed on a single thread until some depth is reached, then the graphs along this second boundary (and their subtrees) are explored in parallel.</p>

<p>This behavior is mostly transparent to the user. What you need to know is that the number of batches is automatically determined by STGen (you do not control it). It is computed upon creation of the iterator and you can access it as follows:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="n">TGraphBatchIterator</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">iter</span><span class="p">(</span><span class="n">my_function</span><span class="p">);</span>
    <span class="kt">int</span> <span class="n">nb_batches</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="n">number_of_batches</span><span class="p">();</span>
</code></pre></div></div>

<p>You can then execute a given batch as follows:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="kt">int64_t</span> <span class="n">nb</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">BATCH_NUM</span><span class="p">);</span>
</code></pre></div></div>
<p>where <code class="language-plaintext highlighter-rouge">BATCH_NUM</code> is the batch that you want to execute (between <code class="language-plaintext highlighter-rouge">0</code> and <code class="language-plaintext highlighter-rouge">nb_batches-1</code>).</p>

<p>It is your job to sum up the resulting numbers if you want to count something over the entire experiment. For the sake of example, here is a program that executes all the batches on a single computer, it is unlikely that you want to use the batch iterator in this way (unless you want to monitor the progress and/or be able to resume execution after an interruption):</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span>
    <span class="n">TGraphBatchIterator</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">iter</span><span class="p">(</span><span class="n">my_function</span><span class="p">);</span>
    <span class="kt">int</span> <span class="n">nb_batches</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="n">number_of_batches</span><span class="p">();</span>
    <span class="kt">int64_t</span> <span class="n">nb</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">nb_batches</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"processing batch "</span> <span class="o">&lt;&lt;</span> <span class="n">i</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
        <span class="n">nb</span> <span class="o">+=</span> <span class="n">iter</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">nb</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Here is the outcome for <code class="language-plaintext highlighter-rouge">N=6</code> with the <code class="language-plaintext highlighter-rouge">count_all()</code> function:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./main 
processing batch 0
processing batch 1
...
processing batch 2243
processing batch 2244
89769096
</code></pre></div></div>

<p>So, here, the work was split into 2245 batches. Note that the very top of the tree (the part higher than the batches) may itself result in some increments of the <code class="language-plaintext highlighter-rouge">nb</code> variable in your function. For convenience, this quantity is added to the result of the first batch, so that the sum of all the batches corresponds indeed to the entire tree.</p>

<h1 id="the-tgraph-class">The <code class="language-plaintext highlighter-rouge">TGraph</code> class</h1>

<p>STGen is shipped with a default type of temporal graph, which is very basic. It is given in the <code class="language-plaintext highlighter-rouge">tgraph.hpp</code> file, and provides the following members:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span><span class="o">&lt;</span><span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="kt">int</span> <span class="n">M</span><span class="o">=</span><span class="p">(</span><span class="n">N</span><span class="o">*</span><span class="p">(</span><span class="n">N</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)&gt;</span>
<span class="k">struct</span> <span class="nc">TGraph</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">bitset</span><span class="o">&lt;</span><span class="n">M</span><span class="o">&gt;</span> <span class="n">edges</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">bitset</span><span class="o">&lt;</span><span class="n">M</span><span class="o">&gt;</span> <span class="n">max_edges</span><span class="p">;</span>
    <span class="n">TEdge</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">tedges</span><span class="p">[</span><span class="n">M</span><span class="p">];</span>
    <span class="kt">int</span> <span class="n">nb_edges</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">lifetime</span><span class="p">;</span>

    <span class="p">...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>For performance reasons, this class is templated with parameters <code class="language-plaintext highlighter-rouge">N</code> and <code class="language-plaintext highlighter-rouge">M</code>, where <code class="language-plaintext highlighter-rouge">N</code> is the number of vertices that the user specifies when an iterator is created (as in the examples above). The value of <code class="language-plaintext highlighter-rouge">M</code> is automatically instantiated to \({N \choose 2}\), the maximum number of edges in a graph of that size. The <code class="language-plaintext highlighter-rouge">edges</code> member is a bitset that indicates which edge is present in the footprint (edges without time information), ordered lexicographically by the corresponding pairs of vertices. The <code class="language-plaintext highlighter-rouge">max_edges</code> member is a bitset that indicates which of these edges currently hold maximum time labels, ordered similarly. <strong>These two members are required for generation, you should not touch them</strong>. The other three members are provided for your manipulations in the user function: <code class="language-plaintext highlighter-rouge">tedges</code> is an array containing <code class="language-plaintext highlighter-rouge">M</code> triplets (u,v,t). Among them, only the first <code class="language-plaintext highlighter-rouge">nb_edges</code> entries are meaningful. Here, the ordering is done according to <em>time</em> (not lexicography). Thus, if you iterate over the first <code class="language-plaintext highlighter-rouge">nb_edges</code> entries of the <code class="language-plaintext highlighter-rouge">tedges</code> array, concretely, you are iterating over all the time edges of the temporal graph in chronological order. Finally, the maximum time label among these edges is stored in the <code class="language-plaintext highlighter-rouge">lifetime</code> member.</p>

<p>Apart from its constructors, this class only provides a single member function <code class="language-plaintext highlighter-rouge">is_tc()</code>, which allows you to test if the given graph is temporally connected, and a function that overrides the <code class="language-plaintext highlighter-rouge">&lt;&lt;</code> operator for printing the edges using <code class="language-plaintext highlighter-rouge">cout &lt;&lt; my_graph</code>. The code of the <code class="language-plaintext highlighter-rouge">is_tc()</code> function is as follows:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="kt">bool</span> <span class="n">is_tc</span><span class="p">()</span> <span class="k">const</span><span class="p">{</span>
        <span class="n">bitset</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">predecessors</span><span class="p">[</span><span class="n">N</span><span class="p">];</span>
        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">predecessors</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">set</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">nb_edges</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span>
            <span class="n">TEdge</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">e</span> <span class="o">=</span> <span class="n">tedges</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
            <span class="n">predecessors</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">u</span><span class="p">]</span> <span class="o">|=</span> <span class="n">predecessors</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">v</span><span class="p">];</span>
            <span class="n">predecessors</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">predecessors</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">u</span><span class="p">];</span>
        <span class="p">}</span>
        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span>
            <span class="k">if</span> <span class="p">(</span><span class="o">!</span> <span class="n">predecessors</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">all</span><span class="p">()){</span>
                <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
    <span class="p">}</span>
</code></pre></div></div>

<h2 id="using-your-own-tgraph-class">Using your own <code class="language-plaintext highlighter-rouge">TGraph</code> class</h2>

<p>It is perfectly possible (and even encouraged) to enrich the <code class="language-plaintext highlighter-rouge">TGraph</code> class by adding further member variables and functions to this class according to your needs. So long as you do not touch the <code class="language-plaintext highlighter-rouge">edges</code> and <code class="language-plaintext highlighter-rouge">max_edges</code> member variables (nor their processing in the constructors), STGen will continue to work just fine and deliver to the user function your custom type of graph. If you want to do so, simply replace the <code class="language-plaintext highlighter-rouge">tgraph.hpp</code> file in the directory with your own version, whose type must also be called <code class="language-plaintext highlighter-rouge">TGraph</code> – this is a bit artisanal, but simple.</p>

<p>In way of an example, there is another file in the directory called <code class="language-plaintext highlighter-rouge">tgraph_min</code>, which corresponds to the bare minimum that STGen needs. If your goal is only to count the number of happy graphs (or happy cliques), this class is sufficient and will result in significant performance gain compared to the default <code class="language-plaintext highlighter-rouge">TGraph</code> version presented above (mostly, because the <code class="language-plaintext highlighter-rouge">tedges</code> array is not required for generation). Note that you can still test if a graph <code class="language-plaintext highlighter-rouge">g</code> is a clique using <code class="language-plaintext highlighter-rouge">g.edges.all()</code> instead of <code class="language-plaintext highlighter-rouge">g.nb_edges == M</code> in the above examples, or more generally, count the number of edges with <code class="language-plaintext highlighter-rouge">g.edges.count()</code> (just a bit slower).</p>

<p>Other versions of the <code class="language-plaintext highlighter-rouge">TGraph</code> class exist, which are not public yet. These classes will be made public later, together with a blog post dedicated to specific experiments.</p>

<h1 id="how-to-cite-stgen">How to cite STGen</h1>

<p>If you are using STGen in your experiments, please cite it as follows:</p>

<div class="language-bibtex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">@misc</span><span class="p">{</span><span class="nl">stgen</span><span class="p">,</span>
  <span class="na">author</span> <span class="p">=</span> <span class="s">{Arnaud Casteigts}</span><span class="p">,</span>
  <span class="na">title</span> <span class="p">=</span> <span class="s">{Efficient generation of simple and proper temporal graphs up to isomorphism}</span><span class="p">,</span>
  <span class="na">note</span> <span class="p">=</span> <span class="s">{\texttt{https://arnaudcasteigts.net/blog/stgen.html}}</span><span class="p">,</span>
  <span class="na">year</span> <span class="p">=</span> <span class="m">2024</span><span class="p">,</span>
<span class="p">}</span>
</code></pre></div></div>
<p>(replace <code class="language-plaintext highlighter-rouge">\texttt</code> with <code class="language-plaintext highlighter-rouge">\url</code> if you are using the url package)</p>

<p>A paper with the same title will eventually appear, more focused on the theoretical aspects of the generation. Part of its content is cover in <a href="https://www.youtube.com/watch?v=pgRBl--JJVc">this talk</a> presented at the AATG workshop of ICALP 2020.</p>

<h1 id="other-versions-of-stgen">Other versions of STGen</h1>

<p>There exist other versions of STGen, in Java, Python, Julia, and Rust. Most of them are outdated and/or have poorer performance. The Rust version is perhaps the second-best (and less outdated) after the official C++ version presented here. If you don’t like C++, feel free to contact me to talk about the other versions.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[(Last updated: July 15, 2024.)]]></summary></entry><entry><title type="html">Temporal graphs - selected chapters (14X060)</title><link href="https://arnaudcasteigts.net/teaching/temporal-graphs/" rel="alternate" type="text/html" title="Temporal graphs - selected chapters (14X060)" /><published>2024-04-01T16:44:46+02:00</published><updated>2024-04-01T16:44:46+02:00</updated><id>https://arnaudcasteigts.net/teaching/temporal-graphs</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/temporal-graphs/"><![CDATA[<p>Teacher: Arnaud Casteigts<br /></p>

<p>This short course is part of the “selected chapter” series for Masters students. Checkout the general web pages for the rest of the series:</p>
<ul>
  <li>on <a href="https://moodle.unige.ch/course/view.php?id=6641">moodle</a></li>
  <li>on <a href="https://pgc.unige.ch/main/teachings/details/2024-14X060">unige</a> (administrative information)</li>
</ul>

<h1 id="course-notes">Course notes</h1>

<ul>
  <li>1- Recaps of graph theory: <a href="/files/tgraphs-1-cours.pdf">[notes + exercises]</a></li>
  <li>2- Basic definitions on temporal graphs: <a href="/files/tgraphs-2-cours.pdf">[notes + exercises]</a></li>
  <li>3- Some facts about temporal graphs: <a href="/files/tgraphs-3-cours.pdf">[notes + exercises]</a></li>
</ul>]]></content><author><name></name></author><category term="Teaching" /><category term="LF" /><summary type="html"><![CDATA[Teacher: Arnaud Casteigts]]></summary></entry><entry><title type="html">Calculabilité et Complexité (11X008)</title><link href="https://arnaudcasteigts.net/teaching/calculabilite-complexite/" rel="alternate" type="text/html" title="Calculabilité et Complexité (11X008)" /><published>2024-02-01T15:44:46+01:00</published><updated>2024-02-01T15:44:46+01:00</updated><id>https://arnaudcasteigts.net/teaching/complexite</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/calculabilite-complexite/"><![CDATA[<p>Enseignant : Arnaud Casteigts<br />
Assistants : Matteo de Francesco et Margaux Marseloo<br />
Monitrice : Elie Bussod et Naziha Beghdadi<br />
Préambule : <a href="/files/complexite-preambule.pdf">[slides]</a></p>

<h1 id="pages-du-cours">Pages du cours</h1>
<ul>
  <li>sur <a href="https://moodle.unige.ch/course/view.php?id=6664">moodle</a> (supports, informations, modalités d’examens, etc.)</li>
  <li>sur <a href="https://pgc.unige.ch/main/teachings/details/2025-11X008">unige</a> (informations administratives)</li>
  <li>années <a href="/teaching/calculabilite-complexite-archive/">précédentes</a> (attention : contenu potentiellement différent)</li>
</ul>

<h1 id="notes-de-cours">Notes de cours</h1>

<ul>
  <li>Introduction du module : <a href="/files/complexite-1-slides.pdf">[slides]</a></li>
  <li>Cours 1 : Problèmes &amp; Machines <a href="/files/complexite-1-cours.pdf">[notes de cours]</a></li>
  <li>Cours 2 : Simulation et opération sur les langages <a href="/files/complexite-2-cours.pdf">[notes de cours]</a></li>
  <li>Cours 3 : Réductions entre langages <a href="/files/complexite-3-cours.pdf">[notes de cours]</a> <a href="/files/complexite-3-slides.pdf">[Church]</a></li>
  <li>Cours 4 : Théorème de Rice, Degrés de Turing, Diagonalisation <a href="/files/complexite-4-cours.pdf">[notes de cours]</a></li>
  <li>Cours 5 : Notations asymptotiques &amp; classes de complexité <a href="/files/complexite-5-cours.pdf">[notes de cours]</a></li>
  <li>Cours 6 : Relation entre classes : <a href="/files/complexite-6-cours.pdf">[notes]</a> - <a href="/files/complexite-6-slides.pdf">[Hartmanis, Stearns, Williams]</a></li>
  <li>Cours 7 : Non-déterminisme <a href="/files/complexite-7-cours.pdf">[notes de cours]</a></li>
</ul>

<h1 id="pour-aller-plus-loin">Pour aller plus loin</h1>
<p>Une partie du cours s’inspire de “Introduction to the Theory of Computation (Michael Sipser)”. Une autre s’inspire de “Computational Complexity (Sanjeev Arora et Boaz Barak)”. D’autres parties sont composées à partir de ressources variées, dont certains articles Wikipédia.</p>

<p>Enfin, le livre “Quantum Computing Since Democritus (Scott Aaronson)” est une mine d’information qui recroise une bonne partie du cours (et explore beaucoup d’autres sujets). Sa lecture est exigeante, mais elle en vaut la peine !</p>]]></content><author><name></name></author><category term="Teaching" /><category term="LF" /><summary type="html"><![CDATA[Enseignant : Arnaud Casteigts Assistants : Matteo de Francesco et Margaux Marseloo Monitrice : Elie Bussod et Naziha Beghdadi Préambule : [slides]]]></summary></entry><entry><title type="html">Graph Algorithms (14X061)</title><link href="https://arnaudcasteigts.net/teaching/graphalgo-archive/" rel="alternate" type="text/html" title="Graph Algorithms (14X061)" /><published>2024-02-01T15:44:46+01:00</published><updated>2024-02-01T15:44:46+01:00</updated><id>https://arnaudcasteigts.net/teaching/graphalgo-archive</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/graphalgo-archive/"><![CDATA[<h1 id="spring-2025">Spring 2025</h1>

<p>Teacher: Arnaud Casteigts<br />
Assistant: Matteo De Francesco<br />
Overview: <a href="/files/graphalgo-preamble.pdf">[slides]</a></p>

<ol>
  <li>Basics of Graph Theory: <a href="/files/graphalgo-1-2025.pdf">[lecture notes]</a></li>
  <li>Traversals, Connectivity, Shortest paths: <a href="/files/graphalgo-2-2025.pdf">[lecture notes]</a></li>
  <li>Minimum Spanning Trees (and Matroid): <a href="/files/graphalgo-3-2025.pdf">[lecture notes]</a></li>
  <li>Basics of Computational Complexity: <a href="/files/graphalgo-4-2025.pdf">[lecture notes]</a> - <a href="/files/graphalgo-4-slides-2025.pdf">[slides]</a></li>
  <li>Graph coloring: <a href="/files/graphalgo-5-slides-2025.pdf">[slides]</a></li>
  <li>Maximum matchings: <a href="/files/graphalgo-6-2025.pdf">[lecture notes]</a></li>
  <li>Approximation algorithms: <a href="/files/graphalgo-7-2025.pdf">[lecture notes]</a></li>
  <li>Random Walks (and Markov chains): <a href="/files/graphalgo-8-slides-2025.pdf">[slides]</a></li>
  <li>Distributed algorithms: <a href="/files/graphalgo-9-slides-2025.pdf">[slides]</a></li>
  <li>Basic concepts of Temporal Graphs: <a href="/files/graphalgo-10-2025.pdf">[lecture notes]</a></li>
  <li>Temporal components and temporal spanners: <a href="/files/graphalgo-11-2025.pdf">[lecture notes]</a></li>
</ol>

<h2 id="mini-class-projects">Mini-class projects</h2>

<h3 id="monday-19th-may-2025">Monday 19th May, 2025</h3>
<p>Morning session (11am):</p>
<ul>
  <li>Shcherbakov: Reconstruction conjecture</li>
  <li>Sutter: A* and related algorithms</li>
  <li>Salane and Thakur: The max-flow min-cut theorem</li>
  <li>Rahman: Auction algorithms for bipartite matching</li>
  <li>Goldfarb: Dynamic Graph algorithms</li>
</ul>

<p>Afternoon session (2pm):</p>
<ul>
  <li>Zebad and Gassilewski: Kuratowski’s and Wagner’s theorem</li>
  <li>Arm: Distributed algorithms in the LOCAL model</li>
  <li>Selvam and Amehunke: Interval graphs (and who killed the Duke of Densmore)</li>
  <li>Zarola and Bolotina: The max-flow min-cut theorem</li>
</ul>

<h3 id="monday-26th-may-2025">Monday 26th May, 2025</h3>
<p>Morning session (11am):</p>
<ul>
  <li>Horvath and Folly-Dogba: Eulers formula</li>
  <li>Mishra and Agarwal: Community detection</li>
  <li>Gay: Quantum random walks on graphs</li>
  <li>Diallo and Nada-Abi: Graph Spanners</li>
  <li>Akoumba: Geometric Routing</li>
</ul>

<p>Afternoon session (2pm):</p>
<ul>
  <li>Maggiorano: Cycle detection for train schedule applications</li>
  <li>Gong and Fang: Graph Isomorphism</li>
  <li>Yang and Bian: Hamiltonian paths</li>
</ul>]]></content><author><name></name></author><category term="Teaching" /><category term="LF" /><summary type="html"><![CDATA[Spring 2025]]></summary></entry><entry><title type="html">Graph Algorithms (14X061)</title><link href="https://arnaudcasteigts.net/teaching/graphalgo/" rel="alternate" type="text/html" title="Graph Algorithms (14X061)" /><published>2024-02-01T15:44:46+01:00</published><updated>2024-02-01T15:44:46+01:00</updated><id>https://arnaudcasteigts.net/teaching/graphalgo</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/graphalgo/"><![CDATA[<p>Enseignant : Arnaud Casteigts<br />
Assistants : Himika Das<br /></p>

<p>Every Monday, room 301 (Battelle campus) - 11am (course) - 2pm (exercises).</p>

<h1 id="other-pages-for-this-class">Other pages for this class</h1>
<ul>
  <li><a href="https://moodle.unige.ch/enrol/index.php?id=18500">Moodle</a> (all documents + communications)</li>
  <li><a href="https://pgc.unige.ch/main/teachings/details/2025-14X061">Unige</a> (administrative page)</li>
  <li><a href="https://arnaudcasteigts.net/teaching/graphalgo-archive/">Previous years</a> (may differ from this year)</li>
</ul>

<h1 id="lecture-notes">Lecture notes</h1>

<p>This section will be updated after each class.</p>

<ul>
  <li>Preambule: <a href="/files/graphalgo-preamble.pdf">[slides]</a></li>
</ul>

<ol>
  <li>Basics of graph theory: <a href="/files/graphalgo-1.pdf">[lecture notes]</a></li>
  <li>Basic algorithms: <a href="/files/graphalgo-2.pdf">[lecture notes]</a></li>
  <li>Minimum Spanning Trees (and Matroid): <a href="/files/graphalgo-3.pdf">[lecture notes]</a></li>
  <li>Computational complexity: <a href="/files/graphalgo-4-slides.pdf">[slides]</a> - <a href="/files/graphalgo-4.pdf">[lecture notes]</a></li>
  <li>Graph coloring: <a href="/files/graphalgo-5-slides.pdf">[slides]</a></li>
  <li>Maximum Matching: <a href="/files/graphalgo-6.pdf">[lecture notes]</a></li>
  <li>Approximation algorithms: <a href="/files/graphalgo-7.pdf">[lecture notes]</a></li>
</ol>

<h1 id="mini-class-projects-in-may-2026">Mini-class projects (in May 2026)</h1>

<p>Slides with list of topics: <a href="/files/graphalgo-miniclass.pdf">[slides]</a></p>

<p><em>Objective:</em> give a mini-class on a particular topic. Using slides is strongly recommended, possibly with hybrid content on the whiteboard.</p>

<p><em>Timing:</em> 10 to 15 minutes + 5 minutes of questions.</p>

<p><em>Grading:</em> 1/4 of the final grade (exam 3/4)</p>

<p><em>Typical plan</em>:</p>

<ol>
  <li>Broader context and overview of known results on this topic (3 to 5 min)</li>
  <li>Presentation of a particular algorithm or theorem (5 to 8 min)</li>
  <li>If applicable, main challenges or conjectures (∼3 min)</li>
  <li>Questions</li>
</ol>

<p><a href="/files/assigned_project_2026.txt">[Assignment of the topics for each group]</a></p>

<!-- **You are required to attend all the talks**. An evaluation form will have to be filled by each participant for all the talks. -->]]></content><author><name></name></author><category term="Teaching" /><category term="LF" /><summary type="html"><![CDATA[Enseignant : Arnaud Casteigts Assistants : Himika Das]]></summary></entry><entry><title type="html">Algorithmique (12X003)</title><link href="https://arnaudcasteigts.net/teaching/algorithmique/" rel="alternate" type="text/html" title="Algorithmique (12X003)" /><published>2023-10-15T16:44:46+02:00</published><updated>2023-10-15T16:44:46+02:00</updated><id>https://arnaudcasteigts.net/teaching/algorithmique</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/algorithmique/"><![CDATA[<p>Enseignants : Arnaud Casteigts et Franck Raynaud<br />
Assistant : Brian Pulfer<br />
Monitrice : Théo von Düring et Antoine Maendly</p>

<p>Les mercredis après-midi à Battelle (Amphi D) - cours à 14h, exercices à 16h.</p>

<h1 id="pages-du-cours">Pages du cours</h1>
<ul>
  <li>sur <a href="https://pgc.unige.ch/main/teachings/details/2025-12X001">unige</a> (informations administratives)</li>
  <li>sur <a href="https://moodle.unige.ch/course/view.php?id=2661">moodle</a> (ressources pédagogiques)</li>
</ul>

<h1 id="notes-de-cours">Notes de cours</h1>
<p>Les supports seront déposés sur cette page après chaque cours (ainsi que sur Moodle).</p>

<ul>
  <li>Rappels de complexité algorithmique <a href="/files/rappels-complexite.pdf">[slides]</a></li>
  <li>Algorithmes gloutons (I) <a href="/files/algo-glouton-1.pdf">[notes de cours]</a></li>
  <li>Algorithmes gloutons (II) <a href="/files/algo-glouton-2.pdf">[notes de cours]</a></li>
  <li>Programmation dynamique (I) <a href="/files/algo-prog-dynamique-1.pdf">[notes de cours]</a></li>
  <li>Programmation dynamique (II) <a href="/files/algo-prog-dynamique-2.pdf">[notes de cours]</a></li>
  <li>Algorithmes d’approximation (I) <a href="/files/algo-approx-1.pdf">[notes de cours]</a></li>
  <li>Algorithmes d’approximation (II) <a href="/files/algo-approx-2.pdf">[notes de cours]</a></li>
</ul>

<h1 id="pour-aller-plus-loin">Pour aller plus loin</h1>

<p>Le contenu de ce cours est assez standard et peut être trouvé via de nombreuses ressources sur Internet. Le livre “Introduction à l’algorithmique” (Cormen, Leiserson, Rivest) couvre également une partie significative du contenu, entre autres sujets.</p>]]></content><author><name></name></author><category term="Teaching" /><category term="Algo" /><summary type="html"><![CDATA[Enseignants : Arnaud Casteigts et Franck Raynaud Assistant : Brian Pulfer Monitrice : Théo von Düring et Antoine Maendly]]></summary></entry><entry><title type="html">Calculabilité et Complexité (11X008) - Archives</title><link href="https://arnaudcasteigts.net/teaching/calculabilite-complexite-archive/" rel="alternate" type="text/html" title="Calculabilité et Complexité (11X008) - Archives" /><published>2023-09-15T16:44:46+02:00</published><updated>2023-09-15T16:44:46+02:00</updated><id>https://arnaudcasteigts.net/teaching/complexite-archive</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/calculabilite-complexite-archive/"><![CDATA[<p>Cette page contient les ressources pédagogiques du cours de Complexité et Calculabilité des années précédentes. Pour l’année actuelle, ça se passe <a href="/teaching/calculabilite-complexite/">sur cette page</a>.</p>

<h1 id="printemps-2024">Printemps 2024</h1>
<p>Enseignant : Arnaud Casteigts<br />
Assistants : Alexandre-Quentin Berger et Matteo De Francesco<br />
Monitrice : Léa Heiniger</p>

<ul>
  <li>Préambule : <a href="/files/complexite-preambule-2024.pdf">[slides]</a></li>
  <li>Cours 1 : Survol du module : <a href="/files/complexite-1-slides-2024.pdf">[slides]</a>
(pb d’enregistrements, pas de vidéo :-/)</li>
  <li>Cours 2 : Rappels de langages formels : <a href="/files/complexite-2-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 3 : Décidable, reconnaissable, simulation : <a href="/files/complexite-3-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 4 : Diagonalisation et indécidabilité : <a href="/files/complexite-4-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 5 : Théorème de Rice (et degrés de Turing) : <a href="/files/complexite-5-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 6 : Introduction à la complexité algorithmique (A. Berger) : <a href="/files/complexite-6-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 7 : Classes de complexité basiques : <a href="/files/complexite-7-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 8 : Relations connues; non-déterminisme; théorème de Savitch : <a href="/files/complexite-8-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 9 : Classe NP : <a href="/files/complexite-9-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 10 : NP-complétude : <a href="/files/complexite-10-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 11 : Exemples de réductions : <a href="/files/complexite-11-cours-2024.pdf">[notes de cours]</a></li>
  <li>Cours 12 : Théorème de Cook-Levin : <a href="/files/complexite-12-cours-2024.pdf">[notes de cours]</a></li>
</ul>

<h1 id="printemps-2025">Printemps 2025</h1>
<p>Enseignant : Arnaud Casteigts<br />
Assistants : Alexandre-Quentin Berger et Matteo De Francesco<br />
Monitrice : Naziha Beghdadi et Elie Bussod</p>

<ul>
  <li>Préambule : <a href="/files/complexite-preambule-2025.pdf">[slides]</a></li>
  <li>Cours 1 : Survol du module : <a href="/files/complexite-1-slides-2025.pdf">[slides]</a></li>
</ul>

<p>Calculabilité :</p>

<ul>
  <li>Cours 2 : Problèmes, Machine, Simulation : <a href="/files/complexite-2-cours-2025.pdf">[notes]</a> - <a href="/files/complexite-2-slides-2025.pdf">[Alonzo Church]</a></li>
  <li>Cours 3 : Propriétés de clôture et réductions : <a href="/files/complexite-3-cours-2025.pdf">[notes]</a></li>
  <li>Cours 4 : Théorème de Rice, Diagonalisation, Non-reconnaissabilité : <a href="/files/complexite-4-cours-2025.pdf">[notes]</a></li>
</ul>

<p>Complexité :</p>

<ul>
  <li>Cours 5 : Notations asymptotiques &amp; classes de complexité : <a href="/files/complexite-5-cours-2025.pdf">[notes]</a></li>
  <li>Cours 6 : Relation entre classes : <a href="/files/complexite-6-cours-2025.pdf">[notes]</a> - <a href="/files/complexite-6-slides-2025.pdf">[Hartmanis, Stearns, Williams]</a></li>
  <li>Cours 7 : Non-déterminisme : <a href="/files/complexite-7-cours-2025.pdf">[notes]</a></li>
  <li>Cours 8 : Classe NP : <a href="/files/complexite-8-cours-2025.pdf">[notes]</a></li>
  <li>Cours 9 : Réductions polynomiales : <a href="/files/complexite-9-cours-2025.pdf">[notes]</a></li>
  <li>Cours 10 : NP-complétude : <a href="/files/complexite-10-cours-2025.pdf">[notes]</a></li>
  <li>Cours 11 : Theorème de Cook-Levin : <a href="/files/complexite-11-cours-2025.pdf">[notes]</a></li>
</ul>]]></content><author><name></name></author><category term="Teaching" /><category term="LF" /><summary type="html"><![CDATA[Cette page contient les ressources pédagogiques du cours de Complexité et Calculabilité des années précédentes. Pour l’année actuelle, ça se passe sur cette page.]]></summary></entry><entry><title type="html">Langages formels (11X003) - Archives</title><link href="https://arnaudcasteigts.net/teaching/langages-formels-archive/" rel="alternate" type="text/html" title="Langages formels (11X003) - Archives" /><published>2023-09-15T16:44:46+02:00</published><updated>2023-09-15T16:44:46+02:00</updated><id>https://arnaudcasteigts.net/teaching/langages-archive</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/langages-formels-archive/"><![CDATA[<p>Cette page contient les ressources pédagogiques du cours de Langages Formels des années précédentes. Pour l’année actuelle, ça se passe <a href="/teaching/langages-formels/">sur cette page</a>.</p>

<h1 id="automne-2024">Automne 2024</h1>
<p>Enseignant : Arnaud Casteigts<br />
Assistant : Alexandre-Quentin Berger et Matteo De Francesco<br />
Monitrices : Léa Heiniger et Aylin Tekkoyun</p>

<ul>
  <li>Cours 1 : Concepts de base : <a href="/files/langages-1-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/226292">[vidéo]</a> - <a href="/files/langages-1-slides-2024.pdf">[slides]</a></li>
  <li>Cours 2 : Automates finis (déterministes) : <a href="/files/langages-2-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/227910">[vidéo]</a> - <a href="/files/langages-2-slides-2024.pdf">[slides]</a> - <a href="/files/langages-1-quiz-2024.pdf">[quiz 1]</a></li>
  <li>Cours 3 : Non-déterminisme : <a href="/files/langages-3-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/229079">[vidéo]</a> - <a href="/files/langages-3-slides-2024.pdf">[slides]</a> - <a href="/files/langages-2-quiz-2024.pdf">[quiz 2]</a></li>
  <li>Cours 4 : Expressions régulières : <a href="/files/langages-4-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/230617">[vidéo]</a> - <a href="/files/langages-4-slides-2024.pdf">[slides]</a> - <a href="/files/langages-3-quiz-2024.pdf">[quiz 3]</a></li>
  <li>Cours 5 : Lemme de l’étoile : <a href="/files/langages-5-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/231716">[vidéo]</a> - <a href="/files/langages-5-slides-2024.pdf">[slides]</a> - <a href="/files/langages-4-quiz-2024.pdf">[quiz 4]</a></li>
  <li>Cours 6 : Grammaires formelles : <a href="/files/langages-6-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/234085">[vidéo]</a> - <a href="/files/langages-6-slides-2024.pdf">[slides]</a></li>
  <li>Cours 7 : Automates à pile : <a href="/files/langages-7-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/234883">[vidéo]</a> - <a href="/files/langages-7-slides-2024.pdf">[slides]</a> - <a href="/files/langages-6-quiz-2024.pdf">[quiz 6]</a></li>
  <li>Cours 8 : Équivalence AP - GHC : <a href="/files/langages-8-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/235746">[vidéo]</a> - <a href="/files/langages-8-slides-2024.pdf">[slides]</a></li>
  <li>Cours 9 : Lemme de l’étoile (hors-contexte) : <a href="/files/langages-9-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/237661">[vidéo]</a> - <a href="/files/langages-9-slides-2024.pdf">[slides]</a></li>
  <li>Cours 10 : Machines de Turing (déterministes) : <a href="/files/langages-A-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/238776">[vidéo]</a> - <a href="/files/langages-A-slides-2024.pdf">[slides]</a></li>
  <li>Cours 11 : Machines de Turing non déterministes (et autres) : <a href="/files/langages-B-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/239886">[vidéo]</a> - <a href="/files/langages-B-slides-2024.pdf">[slides]</a></li>
  <li>Cours 12 : Universalité et indécidabilité : <a href="/files/langages-C-cours-2024.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/240973">[vidéo]</a> - <a href="/files/langages-C-slides-2024.pdf">[slides]</a></li>
</ul>

<h1 id="automne-2023">Automne 2023</h1>
<p>Enseignant : Arnaud Casteigts<br />
Assistant : Alexandre-Quentin Berger<br />
Monitrices : Léonie Dezempte et Léa Heiniger</p>

<ul>
  <li>Préambule : <a href="/files/langages-preambule-2023.pdf">[slides]</a></li>
  <li>Personnages : <a href="/files/langages-1-slides-2023.pdf">[1]</a> - <a href="/files/langages-2-slides-2023.pdf">[2]</a> - <a href="/files/langages-3-slides-2023.pdf">[3]</a> - <a href="/files/langages-4-slides-2023.pdf">[4]</a> - <a href="/files/langages-5-slides-2023.pdf">[5]</a> - <a href="/files/langages-6-slides-2023.pdf">[6]</a> - <a href="/files/langages-7-slides-2023.pdf">[7]</a> - <a href="/files/langages-8-slides-2023.pdf">[8]</a> - <a href="/files/langages-9-slides-2023.pdf">[9]</a> - <a href="/files/langages-10-slides-2023.pdf">[10]</a> - <a href="/files/langages-11-slides-2023.pdf">[11]</a> - <a href="/files/langages-12-slides-2023.pdf">[12]</a></li>
  <li>Cours 1 : Concepts de base : <a href="/files/langages-1-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/196816">[vidéo]</a> - <a href="/files/langages-1-quiz-2023.pdf">[quiz]</a></li>
  <li>Cours 2 : Automates finis (déterministes) : <a href="/files/langages-2-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/198354">[vidéo]</a>  - <a href="/files/langages-2-quiz-2023.pdf">[quiz]</a></li>
  <li>Cours 3 : Non-déterminisme : <a href="/files/langages-3-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/199501">[vidéo]</a>  - <a href="/files/langages-3-quiz-2023.pdf">[quiz]</a></li>
  <li>Cours 4 : Expressions régulières : <a href="/files/langages-4-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/200585">[vidéo]</a>  - <a href="/files/langages-4-quiz-2023.pdf">[quiz]</a></li>
  <li>Cours 5 : Lemme de l’étoile : <a href="/files/langages-5-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/201648">[vidéo]</a></li>
  <li>Cours 6 : Grammaires formelles : <a href="/files/langages-6-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/203693">[vidéo]</a>  - <a href="/files/langages-6-quiz-2023.pdf">[quiz]</a></li>
  <li>Cours 7 : Automates à pile : <a href="/files/langages-7-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/204479">[vidéo]</a></li>
  <li>Cours 8 : Équivalence AP - GHC : <a href="/files/langages-8-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/205316">[vidéo]</a></li>
  <li>Cours 9 : Lemme de l’étoile (hors-contexte) : <a href="/files/langages-9-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/206399">[vidéo]</a></li>
  <li>Cours 10 : Machines de Turing (déterministes) : <a href="/files/langages-10-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/207487">[vidéo]</a></li>
  <li>Cours 11 : Machines de Turing (divers) : <a href="/files/langages-11-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/208563">[vidéo]</a></li>
  <li>Cours 12 : Universalité et indécidabilité : <a href="/files/langages-12-cours-2023.pdf">[notes de cours]</a> - <a href="https://mediaserver.unige.ch/play/209582">[vidéo]</a></li>
</ul>

<h1 id="réponses-à-quelques-questions-posées-en-amphi">Réponses à quelques questions posées en amphi:</h1>

<ul>
  <li>Le lemme de l’étoile donne une condition nécessaire pour être un langage régulier (vous savez cela). Est-ce aussi une condition suffisante ?</li>
</ul>

<p>→ Non, il existe des langages non-réguliers qui la satisfont malgré tout, par exemple le langage:
\(L = \{ a b^n c^n : n \geq 0 \} \cup \{ a^k w : k \neq 1 \text{ et } w \text{ commence par $a$} \}.\)</p>

<ul>
  <li>La notion d’arbre de syntaxe abstraite (abstract syntax tree, AST) est-elle la même que les arbres de dérivations ?</li>
</ul>

<p>→ Non, pas tout à fait, mais c’est très lié. Il s’agit d’une représentation simplifiée que l’on peut construire à partir des arbres de dérivations et qui facilitent leur utilisation ultérieure.</p>

<!-- - Nous avons autorisé un automate à pile à empiler plusieurs symboles d'un coup sur la pile (car cela peut toujours être simulé par un automate à pile équivalent n'ayant pas cette capacité). Qu'est-ce qui nous empêche de faire la même chose pour dépiler plusieurs symboles d'un coup et reconnaître ainsi des grammaires plus générales que les grammaires hors contexte ?

Bonne question ! :-)-->]]></content><author><name></name></author><category term="Teaching" /><category term="LF" /><summary type="html"><![CDATA[Cette page contient les ressources pédagogiques du cours de Langages Formels des années précédentes. Pour l’année actuelle, ça se passe sur cette page.]]></summary></entry><entry><title type="html">S2.02 : Exploration algorithmique d’un problème</title><link href="https://arnaudcasteigts.net/teaching/sae.html" rel="alternate" type="text/html" title="S2.02 : Exploration algorithmique d’un problème" /><published>2023-02-04T15:44:46+01:00</published><updated>2023-02-04T15:44:46+01:00</updated><id>https://arnaudcasteigts.net/teaching/sae-2.02</id><content type="html" xml:base="https://arnaudcasteigts.net/teaching/sae.html"><![CDATA[<h1 id="informations-préalables">Informations préalables</h1>

<h2 id="enseignements-ressources-">Enseignements ressources :</h2>
<ul>
  <li><strong>R2.01 Dev. objets</strong></li>
  <li><strong>R2.07 Graphes</strong></li>
  <li><strong>R2.09 Méthodes numériques</strong></li>
  <li>R2.02 Dev. d’apps avec IHM</li>
  <li>R2.03 Qualité de dev.</li>
</ul>

<p><a href="/assets/sae/sae-S2.02.pdf">Fiche dans le référentiel BUT</a></p>

<h2 id="évaluation">Évaluation</h2>

<p>Ce projet est à réaliser en binômes (tirés au sort).
L’évaluation portera sur les éléments suivants :</p>

<ul>
  <li>Livrable 1 (2 points) : une archive <code class="language-plaintext highlighter-rouge">.jar</code> exécutable de votre projet</li>
  <li>Livrable 2 (2 points) : le code source, bien structuré</li>
  <li>Livrable 3 (2 points) : javadoc et utilisation de tests unitaires
(ces derniers peuvent utiliser notamment la génération automatique de graphes en forme de grilles, comme présenté en section 10 ci-dessous)</li>
  <li>Quiz final <strong>individuel</strong> lundi 5 juin à 16h10 (14 points)</li>
</ul>

<p><strong>Important à comprendre :</strong> la majorité de votre note proviendra du quiz individuel. Ce dernier vous semblera facile si vous avez réalisé vous-même et bien compris toutes les étapes du projet. Plusieurs quiz intermédiaires sont disponibles dans cette page pour vous permettre de vous auto-évaluer au fur et à mesure. Ces derniers ne sont pas notés. Nous vous conseillons de les réaliser individuellement même lorsque vous serez en binôme.</p>

<p>Indiquez les <strong>noms du binôme</strong> dans le titre de la fenêtre. L’ensemble des fichiers à rendre peut être déposée comme une archive unique avant le <strong>SAMEDI 3 JUIN à MINUIT</strong> sur <a href="https://moodle1.u-bordeaux.fr/course/view.php?id=3560">Moodle</a> (clé d’inscription “R2.07”, si vous n’êtes pas déjà inscrit).
Cette archive contiendra : un JAR exécutable (*); un répertoire contenant la javadoc (générée à partir de votre code); et un répertoire contenant le code source (et les tests). Un seul dépôt par binôme (ou monôme, si vous êtes seul) est suffisant, en indiquant vos noms de famille dans le nom de l’archive.</p>

<p>(*) Concernant le JAR exécutable : si vous n’arrivez pas à inclure la dépendance à JBotSim directement dans votre JAR, nous acceptons aussi les configurations dans lesquelles votre JAR fonctionne lorsque JBotSim est présent dans le “classpath”. À toutes fins utiles, JBotSim peut être récupéré sous forme d’un JAR <a href="/assets/sae/jbotsim-all-1.2.0.jar">ici</a>.</p>

<!-- Les trois notes des livrables seront communes au binôme. En revanche, le quiz sera **individuel**. Il portera sur les mêmes éléments que le projet et visera à vérifier que ces éléments sont bien maîtrisés.-->

<h1 id="aperçu-du-projet">Aperçu du projet</h1>

<p>Le projet consiste à développer une application pour le calcul d’itinéraires, en Java (IDE de votre choix).</p>

<p>Dans cette application, l’utilisateur choisit un point de départ (source, sommet noir sur la Figure 1) et un point d’arrivée (destination, drapeau rouge sur la Figure 1).</p>

<center>
  <img src="/assets/sae/before.png" width="450" alt="avant" />
  <p class="caption">Figure 1. Choix d'une source et d'une destination.</p>
</center>

<p>Un algorithme est ensuite exécuté pour calculer les plus courts chemins de la source vers tous les autres sommets. Plusieurs algorithmes et variantes du problème seront considérés.</p>

<center>
  <img src="/assets/sae/during.png" width="450" alt="pendant" />
  <p class="caption">Figure 2. Calcul des chemins de la source vers tous les sommets.</p>
</center>

<p>Enfin, le chemin allant de la source à la destination est sélectionné et affiché à l’utilisateur.</p>

<center>
  <img src="/assets/sae/after.png" width="450" alt="after" />
  <p class="caption">Figure 3. Affichage du chemin de la source à la destination.</p>
</center>

<p>Lien avec les enseignements ressources :</p>
<ol>
  <li>Algorithmes de calcul de chemins (R2.07 - Graphes)</li>
  <li>Analyse de complexité algorithmique (R2.09 - Méthodes numériques)</li>
  <li>Réalisation d’une interface utilisateur (R2.02 - Dev. d’apps avec IHM)</li>
  <li>Tout cela se fait en Java (R2.01 - Dev. objets)</li>
  <li>Réalisation d’une javadoc et de tests unitaires (R2.03 - Qualité de dev.)</li>
</ol>

<p>Vous serez guidés dans la réalisation de ce projet par un certain nombre d’instructions et de quiz intermédiaires (non évalués) vous permettant de vérifier que vous êtes prêts à poursuivre.</p>

<h1 id="cest-parti-">C’est parti !</h1>

<h2 id="1-création-dun-projet-minimaliste">1) Création d’un projet minimaliste</h2>

<p>Pour manipuler et représenter nos graphes, nous allons utiliser la bibliothèque JBotSim.</p>

<p><strong>→ Travail à faire (1.1)</strong> : Suivre la page HelloWorld du <a href="https://arnaudcasteigts.net/jbotsim/?p=examples/helloworld">tutoriel de JBotSim</a> (cette page là seulement). Cela vous expliquera comment créer un projet, ajouter la dépendance à la bibliothèque JBotSim et créer un exemple minimal. Notez que le tutoriel explique comment faire cela <strong>avec IntelliJ</strong>. Si vous préférez utiliser <strong>Netbeans</strong> (par exemple), une fois votre projet créé, allez dans l’arborescence du projet, dossier “Dependencies”, faites click droit, “Add Dependency”, puis entrez les informations suivantes :</p>
<ul>
  <li>Group ID : io.jbotsim</li>
  <li>Artifact ID : jbotsim-all</li>
  <li>Version : 1.2.0</li>
</ul>

<!--
Visual Studio Code:
- Pour un projet Maven : ajouter la dépendance dans le fichier pom.xml ...
- Pour un projet auto-managé :
  * À la main : ajouter une ligne dans le fichier de configuration  ```.vscode/settings.json``` 
```json
{
    "java.project.referencedLibraries": [
        "lib/**/*.jar",
        "https://repo1.maven.org/maven2/io/jbotsim/jbotsim-all/1.2.0/jbotsim-all-1.2.0.jar"
    ]
}
```
	* Via l’interface : panneau de gauche / dépendances Java / cliquer sur + et pour ajouter des fichiers jar (le fichier settings.json sera également mis à jour).
	* Pour plus d’information, se reporter à la page : https://code.visualstudio.com/docs/java/java-project
-->
<hr />

<p><strong>Objectif</strong> : Vous devez obtenir un rendu similaire à celui de la Figure 4.</p>

<center>
  <img src="/assets/sae/helloworld.png" />
  <p class="caption">Figure 4. Exemple de graphe obtenu en cliquant à la souris.</p>
</center>

<p><strong>Remarque</strong> : Par défaut, les arêtes sont ajoutées automatiquement en fonction de la distance entre les nœuds. Il est possible de changer ce comportement pour créer des graphes différents, mais ce n’est pas nécessaire dans ce projet.</p>

<h3 id="-quiz-de-la-section-1">→ <a href="https://forms.gle/6i2SddivAdyWncF37" target="_blank">QUIZ de la section 1</a></h3>
<hr />

<h2 id="2-gestion-des-composants-graphiques">2) Gestion des composants graphiques</h2>

<p>Dans l’exemple précédent, l’objet <code class="language-plaintext highlighter-rouge">JViewer</code> gère lui-même le fenêtrage et les composants graphiques permettant de dessiner le graphe. Bien que pratique, cela donne peu de souplesse. Nous allons donc créer une autre application, dont nous gérerons nous-mêmes les composants et à laquelle nous ajouterons des boutons. La classe ci-dessous donne un exemple de code permettant de faire cela. La bibliothèque de composants utilisée est <code class="language-plaintext highlighter-rouge">swing</code> (intégrée à Java).</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">io.jbotsim.core.Topology</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">io.jbotsim.ui.JTopology</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">javax.swing.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.awt.BorderLayout</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.awt.event.ActionEvent</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.awt.event.ActionListener</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MonApplication</span> <span class="kd">implements</span> <span class="nc">ActionListener</span> <span class="o">{</span>
    <span class="nc">Topology</span> <span class="n">tp</span><span class="o">;</span> <span class="c1">// Objet qui contient le graphe</span>
    <span class="nc">JTopology</span> <span class="n">jtp</span><span class="o">;</span> <span class="c1">// Composant graphique qui affiche le graphe</span>

    <span class="kd">public</span> <span class="nf">MonApplication</span><span class="o">()</span> <span class="o">{</span>
        <span class="c1">// Création du graphe</span>
        <span class="n">tp</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Topology</span><span class="o">();</span>

        <span class="c1">// Création de l'interface graphique (ci-dessous)</span>
        <span class="n">creerInterfaceGraphique</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="kt">void</span> <span class="nf">creerInterfaceGraphique</span><span class="o">()</span> <span class="o">{</span>
        <span class="c1">// Création d'une fenêtre</span>
        <span class="nc">JFrame</span> <span class="n">window</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JFrame</span><span class="o">(</span><span class="s">"Mon application"</span><span class="o">);</span>
        <span class="n">window</span><span class="o">.</span><span class="na">setDefaultCloseOperation</span><span class="o">(</span><span class="nc">JFrame</span><span class="o">.</span><span class="na">EXIT_ON_CLOSE</span><span class="o">);</span>

        <span class="c1">// Création du composant graphique qui affiche le graphe</span>
        <span class="n">jtp</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JTopology</span><span class="o">(</span><span class="n">tp</span><span class="o">);</span>
        <span class="n">window</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">jtp</span><span class="o">);</span>

        <span class="c1">// Création d'un bouton test</span>
        <span class="nc">JButton</span> <span class="n">button</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JButton</span><span class="o">(</span><span class="s">"Test"</span><span class="o">);</span>
        <span class="n">window</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">button</span><span class="o">,</span><span class="nc">BorderLayout</span><span class="o">.</span><span class="na">NORTH</span><span class="o">);</span>

        <span class="c1">// Abonnement aux évènements du bouton (clic, etc.)</span>
        <span class="n">button</span><span class="o">.</span><span class="na">addActionListener</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>

        <span class="c1">// Finalisation</span>
        <span class="n">window</span><span class="o">.</span><span class="na">pack</span><span class="o">();</span>
        <span class="n">window</span><span class="o">.</span><span class="na">setVisible</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">actionPerformed</span><span class="o">(</span><span class="nc">ActionEvent</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">e</span><span class="o">.</span><span class="na">getActionCommand</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="s">"Test"</span><span class="o">))</span> <span class="o">{</span>
            <span class="nc">JOptionPane</span><span class="o">.</span><span class="na">showMessageDialog</span><span class="o">(</span><span class="kc">null</span><span class="o">,</span> <span class="s">"Bouton cliqué"</span><span class="o">);</span>
        <span class="o">}</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">new</span> <span class="nf">MonApplication</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p><strong>→ Travail à faire (2.1)</strong> : Copier ce code dans une classe <code class="language-plaintext highlighter-rouge">MonApplication</code>, l’exécuter et tenter de comprendre toutes les instructions. 
Vous devriez obtenir un rendu similaire à celui de la Figure 5 (lorsque le bouton est cliqué).</p>

<center>
  <img src="/assets/sae/gui-avec-bouton.png" />
  <p class="caption">Figure 5. Exemple d'application qui gère elle-même ses composants.</p>
</center>

<p><strong>→ Travail à faire (2.2)</strong> : Ajouter un second bouton <strong>en bas</strong> de la fenêtre. Lorsqu’un bouton est cliqué, affichez un message différent selon le bouton qui a été utilisé.</p>

<h3 id="-quiz-de-la-section-2">→ <a href="https://forms.gle/VuXKwFXyS8p7kAwj7" target="_blank">QUIZ de la section 2</a></h3>
<hr />

<h2 id="3-sélection-des-sommets-source-et-destination">3) Sélection des sommets source et destination</h2>

<p><strong>→ Travail à faire (3.1)</strong> : Créer deux variables de type <code class="language-plaintext highlighter-rouge">Node</code> dans votre classe, que vous appellerez <code class="language-plaintext highlighter-rouge">source</code> et <code class="language-plaintext highlighter-rouge">destination</code>. Ces variables représenteront les sommets choisis par l’utilisateur. Vous pouvez les initialiser à <code class="language-plaintext highlighter-rouge">null</code>.</p>

<p>On souhaite permettre à l’utilisateur de choisir ces sommets à la souris. JBotSim permet de sélectionner des sommets en cliquant dessus avec le <strong>bouton de la molette</strong> (ou bien ctrl+clic gauche si vous n’avez pas de molette). Pour récupérer cet évènement, il faut que votre classe implémente l’interface <code class="language-plaintext highlighter-rouge">SelectionListener</code>, qu’elle possède la méthode correspondante : <code class="language-plaintext highlighter-rouge">public void onSelection(Node selectedNode){}</code>, et que vous souscriviez à cet évènement auprès de la topologie, en appelant <code class="language-plaintext highlighter-rouge">.addSelectionListener(this)</code> à un endroit approprié.</p>

<p><strong>→ Travail à faire (3.2)</strong> : Ajouter <code class="language-plaintext highlighter-rouge">SelectionListener</code> à la liste des interfaces que votre classe implémente, ajouter la méthode correspondante et souscrivez aux évènements (notez que cela fait trois choses à faire).</p>

<p><strong>Difficultés potentielles</strong> : Selon l’IDE que vous utilisez, la méthode pourrait être automatiquement générée après avoir ajouté l’interface <code class="language-plaintext highlighter-rouge">SelectionListener</code>. Si ce n’est pas le cas, voici le code correspondant.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onSelection</span><span class="o">(</span><span class="nc">Node</span> <span class="n">selectedNode</span><span class="o">)</span> <span class="o">{</span>
    <span class="o">}</span>
</code></pre></div></div>

<p>ainsi que les imports correspondants :</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">io.jbotsim.core.Node</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">io.jbotsim.core.event.SelectionListener</span><span class="o">;</span>
</code></pre></div></div>

<p><strong>→ Travail à faire (3.3)</strong> : Implémenter le comportement suivant dans la méthode <code class="language-plaintext highlighter-rouge">onSelection</code>. Si la variable <code class="language-plaintext highlighter-rouge">source</code> vaut <code class="language-plaintext highlighter-rouge">null</code>, lui affecter le sommet que l’utilisateur vient de sélectionner (passé en paramètre); sinon, si la variable <code class="language-plaintext highlighter-rouge">destination</code> vaut <code class="language-plaintext highlighter-rouge">null</code>, lui affecter le sommet sélectionné. Si aucun des deux n’est <code class="language-plaintext highlighter-rouge">null</code>, ne rien faire.</p>

<p><strong>→ Travail à faire (3.4)</strong> : Toujours dans <code class="language-plaintext highlighter-rouge">onSelection</code>, lorsqu’un sommet  est choisi comme source ou comme destination, on peut lui donner une couleur distincte pour le visualiser. Pour cela, on peut procéder comme suit :</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="n">source</span><span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="nc">Color</span><span class="o">.</span><span class="na">black</span><span class="o">);</span>
</code></pre></div></div>

<p><strong>Difficultés potentielles</strong> : Attention, il existe différentes classes <code class="language-plaintext highlighter-rouge">Color</code>. Celle que nous utilisons ici est celle de JBotSim, veillez à ce que l’import utilisé soit bien <code class="language-plaintext highlighter-rouge">import io.jbotsim.core.Color</code> et non <code class="language-plaintext highlighter-rouge">awt.Color</code> ou <code class="language-plaintext highlighter-rouge">awt.*</code>.</p>

<p><strong>→ Travail à faire (3.5)</strong> : Faire en sorte que l’un des boutons évoqués plus haut soit utilisé pour réinitialiser la sélection des sommets, en mettant les deux variables correspondantes à <code class="language-plaintext highlighter-rouge">null</code> et en enlevant leur couleur via <code class="language-plaintext highlighter-rouge">setColor(null)</code>. Bien sûr, vous pouvez changer le libellé du bouton.</p>

<p><strong>→ Bonus (facultatif)</strong> : Plutôt que d’utiliser une couleur, changer l’icône de la destination en un drapeau rouge. Vous pouvez utiliser pour cela la méthode <code class="language-plaintext highlighter-rouge">setIcon</code> et l’une des icônes prédéfinies dans la classe <code class="language-plaintext highlighter-rouge">Icons</code> du package <code class="language-plaintext highlighter-rouge">io.jbotsim.ui.icons</code>.</p>

<p>Vous devriez obtenir un rendu semblable à celui de la Figure 6 :</p>

<center>
  <img src="/assets/sae/before.png" width="450" alt="avant" />
  <p class="caption">Figure 6. Choix d'une source et d'une destination.</p>
</center>

<p><strong>Bilan:</strong>
Nous voici désormais prêts à faire de l’algorithmique ! Avant de continuer, vérifiez que vous maîtrisez bien les concepts que nous avons couverts dans cette section, grâce au quiz.</p>

<h3 id="-quiz-de-la-section-3">→ <a href="https://forms.gle/ZHVc5wKXkCfJnd6y5" target="_blank">QUIZ de la section 3</a></h3>
<hr />

<h2 id="4-parcours-en-largeur">4) Parcours en largeur</h2>

<p>Le premier algorithme que nous allons implémenter revient à effectuer un <strong>parcours en largeur</strong> depuis le sommet source. Comme vu en cours, ce parcours définit un <em>arbre couvrant</em> qui a pour racine le sommet source et dans lequel la distance de chaque sommet à la racine est identique à ce qu’elle est dans le graphe d’origine (on considère ici comme longueur d’un chemin le nombre d’arêtes qu’il utilise). Le plus court chemin entre la source et la destination sera donc l’unique chemin qui les relie dans cet arbre.</p>

<h3 id="préparation-du-code">Préparation du code</h3>
<p><strong>→ Travail à faire (4.1)</strong> : Créer une méthode <code class="language-plaintext highlighter-rouge">ParcoursEnLargeur</code> qui prend deux paramètres : l’un de type <code class="language-plaintext highlighter-rouge">Topology</code> (le graphe) et l’autre de type <code class="language-plaintext highlighter-rouge">Node</code> (le sommet source choisi par l’utilisateur).</p>

<p>Le type de retour de cette méthode doit être une structure de données qui permette d’associer à chaque sommet (de type <code class="language-plaintext highlighter-rouge">Node</code>) son sommet parent dans l’arbre (de type <code class="language-plaintext highlighter-rouge">Node</code> également).</p>

<p><strong>→ Travail à faire (4.2)</strong> : Trouver la structure de données appropriée pour faire cela en Java. Si l’occasion s’y prête, faire valider ce choix par l’enseignant. Puis créer cette structure de données au début de la méthode, en initialisant les parents de tous les sommets à <code class="language-plaintext highlighter-rouge">null</code>, sauf le parent de la source, qui par convention sera la source elle-même.</p>

<p><strong>Aide sur l’API</strong> : Vous pouvez récupérer la liste des sommets en appelant la méthode <code class="language-plaintext highlighter-rouge">getNodes()</code> sur la topologie. Par ailleurs, en Java, on peut parcourir tous les éléments d’une collection (liste ou autre) de façon très simple, en utilisant le mot clé <code class="language-plaintext highlighter-rouge">:</code> (cherchez sur internet comme faire, si besoin).</p>

<h3 id="lalgorithme">L’algorithme</h3>

<p>Pour rappel, voici une version de l’algorithme de parcours en largeur, utilisant une file d’attente pour visiter les sommets découverts. Attention : cet algorithme est donné en pseudo-code, avec plusieurs différences importantes avec Java.</p>

<pre>
f = CréerFile()
f.enfiler(source)

<b>Tant Que</b> f est non vide, <b>Faire</b>
    s = f.défiler() // supprime également l'élément
    <b>pour tout</b> voisin v de s, <b>Faire</b>
        <b>si</b> parent[v] == null, <b>Alors</b>
            parent[v] &larr; s 
            f.enfiler(v)
</pre>

<p><strong>→ Travail à faire (4.3)</strong> : Faire tourner cet algorithme <strong>à la main</strong> sur l’exemple de la Figure 7, en prenant pour source le sommet C et en notant sur un brouillon l’évolution du contenu de la file. Si vous êtes en classe avec un enseignant, montrez-lui l’arbre couvrant qui en résulte (lorsqu’il y a plusieurs choix de voisins, prenez-les dans un ordre quelconque).</p>

<center>
  <img src="https://pixees.fr/informatiquelycee/n_site/img/nsi_term_algo_graph_1.png" width="300" alt="avant" />
  <p class="caption">Figure 7. Exemple de graphe.</p>
</center>

<h3 id="implémentation">Implémentation</h3>

<p><strong>→ Travail à faire (4.4)</strong> : Chercher les réponses aux questions suivantes :</p>
<ol>
  <li>Comment manipuler une file d’attente en Java ? (attention, en anglais une file se dit “queue” et un fichier se dit “file”…)</li>
  <li>Quels appels de méthodes remplaceront la syntaxe de <tt>parent[v] ← s</tt> dans le pseudo-code de l’algorithme, en considérant la structure de données que vous avez choisie pour mémoriser les parents ? Et en lecture ?</li>
  <li>Quelles méthodes permettent d’enfiler et de défiler un élément ? Vous avez plusieurs choix, ils sont tous bons.</li>
  <li>En Java, <code class="language-plaintext highlighter-rouge">Queue</code> est une interface, mais ce n’est pas une classe. Un exemple de classe qui implémente cette interface est <code class="language-plaintext highlighter-rouge">LinkedList</code>. Peut-on déclarer notre file de sorte à restreindre l’utilisation des méthodes aux seules méthodes de l’interface <code class="language-plaintext highlighter-rouge">Queue</code>, sans permettre l’accès aux autres méthodes de la classe <code class="language-plaintext highlighter-rouge">LinkedList</code> ?</li>
  <li>Comment récupérer la liste des voisins d’un sommet dans JBotSim ? (Indice 1 : c’est une méthode de la classe <code class="language-plaintext highlighter-rouge">Node</code>, dont la javadoc est <a href="https://arnaudcasteigts.net/jbotsim/javadoc/1.2.0/io/jbotsim/core/Node.html" target="_blank">disponible ici</a> – Indice 2 : notre graphe est bien <em>non-orienté</em> (undirected))</li>
</ol>

<p><strong>→ Travail à faire (4.5)</strong> : Implémenter l’algorithme !</p>

<p><strong>Astuce de visualisation</strong> : Pour indiquer qu’une arête entre deux sommets, disons s1 et s2, fait partie de l’arbre, on peut changer son épaisseur en écrivant par exemple <code class="language-plaintext highlighter-rouge">s1.getCommonLinkWith(s2).setWidth(4);</code> (le paramètre d’épaisseur est le nombre de pixels, par défaut 1).</p>

<p>Vous devriez obtenir un résultat semblable à celui de la Figure 8.</p>
<center>
  <img src="/assets/sae/during.png" width="450" alt="pendant" />
  <p class="caption">Figure 8. Arbre des plus courts chemins de la source vers tous les sommets.</p>
</center>

<p><strong>Remarque</strong> : Pour optimiser un peu le calcul, il est possible d’arrêter la construction de l’arbre dès que la destination a été trouvée.</p>

<p><strong>→ Travail à faire (4.6)</strong> : Mettez à jour votre méthode de réinitialisation pour supprimer le dessin de l’arbre ! Vous pouvez récupérer la liste des arêtes (de type <code class="language-plaintext highlighter-rouge">Link</code>) en appelant <code class="language-plaintext highlighter-rouge">getLinks()</code> sur la topologie.</p>

<h3 id="-quiz-de-la-section-4">→ <a href="https://forms.gle/x7n3JErrJZVe2s5f6" target="_blank">QUIZ de la section 4</a></h3>
<hr />

<h2 id="5-récupérer-le-chemin-à-partir-de-larbre">5) Récupérer le chemin à partir de l’arbre</h2>

<p>Nous avons désormais en notre possession un arbre, encodé par une structure qui associe à chaque sommet son parent. Il nous reste donc à extraire de cet arbre le chemin qui nous intéresse entre la source et la destination. Cette partie est laissée plus libre.</p>

<p><strong>→ Travail à faire (4.5)</strong> : Écrire une méthode <code class="language-plaintext highlighter-rouge">extraireChemin</code> qui prend en entrée la source, la destination, ainsi que la structure qui représente les liens de parenté. Votre méthode doit renvoyer une <strong>liste de sommets</strong> à parcourir de la source à la destination, qui correspond au plus court chemin.</p>

<p><strong>Difficulté potentielle</strong> : Il est possible que vous récupériez ces sommets dans l’ordre inverse du chemin. Il faudra donc l’inverser, ou bien gérer la récupération de façon plus subtile.</p>

<p><strong>→ Travail à faire (4.6)</strong> : Faire en sorte de n’afficher que les arêtes du chemin en gras, et d’afficher la liste des sommets à l’utilisateur (sur la sortie standard ou dans une boite de dialogue). L’identifiant de chaque sommet est unique et correspond à un nombre entre 0 et n-1, on peut le voir en passant la souris sur le sommet, et on peut le récupérer en utilisant <code class="language-plaintext highlighter-rouge">node.getID()</code>.</p>

<p>Vous devriez obtenir un rendu similaire à celui de la Figure 9.</p>

<center>
  <img src="/assets/sae/after.png" width="450" alt="after" />
  <p class="caption">Figure 9. Affichage du chemin de la source à la destination.</p>
</center>

<h3 id="-quiz-de-la-section-5">→ <a href="https://forms.gle/YCCn1Z8aaFmc8qSV7" target="_blank">QUIZ de la section 5</a></h3>
<hr />

<h2 id="6-une-variante-plus-intéressante">6) Une variante plus intéressante</h2>

<p>À partir de cette section, la façon dont vous gérez vos interactions avec l’utilisateur et votre interface graphique sont laissées libres, faites comme vous voulez.</p>

<p><strong>→ Travail à faire (4.7)</strong> : Permettre à l’utilisateur d’indiquer des sommets à éviter. Vous pouvez les représenter par une couleur différente (par exemple, rouge). Votre algorithme de parcours devra être adapté pour éviter de passer par ces obstacles-là, comme illustré à la Figure 10.</p>

<center>
  <img src="/assets/sae/obstacles.png" width="320" alt="after" />
  <p class="caption">Figure 10. Recherche de chemin contournant des obstacles.</p>
</center>

<h3 id="pas-de-quiz-pour-la-section-6">Pas de quiz pour la section 6</h3>

<hr />

<h2 id="7-graphes-pondérés">7) Graphes pondérés</h2>

<p>Dans les sections qui suivent, nous allons considérer le cas des graphes pondérés. Les graphes que nous créons sous JBotSim sont plongés dans le plan, c’est à dire que chaque sommet a des coordonnées 2D. Il est donc naturel de considérer comme poids pour les arêtes la distance euclidienne entre ses deux sommets extrémités. Dans ce contexte, trouver le plus court chemin entre la source et la destination revient à trouver un chemin dont la somme des poids (c.-à-d. la somme des longueurs d’arêtes) est aussi petite que possible.</p>

<p>Quelques éléments d’API pour plus tard:</p>

<ul>
  <li>La distance entre deux sommets <code class="language-plaintext highlighter-rouge">v1</code> et <code class="language-plaintext highlighter-rouge">v2</code> de type <code class="language-plaintext highlighter-rouge">Node</code> (voisins ou non), peut être obtenue en appelant <code class="language-plaintext highlighter-rouge">v1.distance(v2)</code>, qui renvoie un <code class="language-plaintext highlighter-rouge">double</code>. Par défaut, l’unité coïncide avec un pixel dans le rendu graphique.</li>
  <li>Ce ne sera peut-être pas nécessaire, mais si besoin, la longueur d’une arête <code class="language-plaintext highlighter-rouge">a</code> de type <code class="language-plaintext highlighter-rouge">Link</code> peut être obtenue en appelant <code class="language-plaintext highlighter-rouge">a.getLength()</code>.</li>
</ul>

<h3 id="pas-de-quiz-pour-la-section-7">Pas de quiz pour la section 7</h3>

<hr />

<h2 id="8-algorithme-a">8) Algorithme A*</h2>

<p>Le parcours en largeur vu plus haut, de même que l’algorithme de Dijkstra (que nous n’implémenterons pas), reposent tous deux sur la construction d’un arbre dont la source est la racine, et dans lequel les distances entre la source et chaque autre sommet sont minimisées (qu’il s’agisse du nombre d’arêtes, pour le premier, ou de la somme des poids, pour le second). Le défaut principal de ces algorithmes est que tous les sommets dont la distance à la source est inférieure à celle de la destination seront explorés par l’algorithme. Cela devient coûteux lorsque le graphe est grand. 
Intuitivement, l’algorithme A* évite ce problème en avançant directement vers la destination, grâce à l’utilisation d’une <em>file prioritaire</em>.</p>

<h3 id="nouvelle-structure-de-données--la-file-prioritaire-">Nouvelle structure de données : la file prioritaire !</h3>

<p>Contrairement à une file classique, la file prioritaire ne respecte pas forcément l’ordre d’insertion (elle n’est pas de type FIFO), au contraire, elle permet à des éléments nouvellement insérés de “griller la priorité” à des éléments existants en fonction d’une valeur spécifiée lors de l’insertion (la priorité).</p>

<p><strong>Exemple de fonctionnement :</strong></p>

<p>Supposons que l’on favorise les priorités les plus petites (“min priority queue”), ce qui est le cas en Java. Si l’on insère les éléments suivants : A avec priorité 12, puis B avec priorité 17, puis C avec priorité 4, et enfin D avec priorité 6, ces éléments seront défilés dans l’ordre C, puis D, puis A, et enfin B.</p>

<p><strong>→ Travail à faire (8.1)</strong> S’assurer d’avoir bien compris le principe d’une file prioritaire.</p>

<h3 id="fonctionnement-de-lalgorithme-a">Fonctionnement de l’algorithme A*</h3>

<p>Le fonctionnement de l’algorithme A* est très similaire à celui d’un parcours en largeur : lorsqu’on explore un sommet, on insère dans la file prioritaire ses voisins qui n’ont pas encore de “parent”. La différence principale est que l’on utilise une file prioritaire plutôt qu’une file classique, afin de donner la priorité aux sommets qui nous semblent les plus prometteurs (plutôt qu’à ceux qui attendent depuis le plus longtemps).</p>

<p><strong>→ Travail à faire (8.2)</strong> : Trouver un critère simple qui permette d’estimer qu’un sommet semble plus prometteur qu’un autre pour avancer vers la destination. Pour rappel : on considère ici un graphe plongé dans le plan (cf. plus haut).</p>

<p><strong>Remarque</strong> : On appelle <em>fonction d’estimation</em> la fonction qui estime la qualité d’un élément potentiel à explorer (la valeur correspondant servant de priorité). Bien entendu, les qualités de l’algorithme dépendent en grand partie de la qualité de cette estimation. <!-- Notamment, on sait que si la fonction d'estimation renvoit toujours une valeur inférieure ou égale au vrai coût, alors l'algorithme trouvera un chemin dont le nombre de sauts est minimum (notez que la somme des poids utilisés, par contre, n'est pas forcément optimale). Par ailleurs, l'algorithme s'exécutera d'autant plus rapidement que l'estimation est proche du vrai coût. --></p>

<p><strong>→ Travail à faire (8.3)</strong> : Réfléchir à la qualité de l’estimation que vous renvoyez dans différents cas de figure. Dans quels cas cette estimation est bonne, et dans quels cas elle pourrait se tromper de façon plus importante ?</p>

<p><strong>→ Question bonus (facultative)</strong> : Comment l’algorithme A* se comporte lorsque la <em>fonction d’estimation</em> renvoie toujours la même valeur ? Il pourrait être intéressant de tester cela sur un graphe de taille conséquente, afin de comparer le résultat avec l’autre fonction d’estimation. Par ailleurs, existe-t-il une fonction d’estimation qui permet de simuler un parcours en largeur ?</p>

<h3 id="-quiz-de-la-section-8">→ <a href="https://forms.gle/qkFA7iXoQhPF6vaN9">QUIZ de la section 8</a></h3>

<hr />

<h2 id="9-implémentation-reposant-sur-a">9) Implémentation reposant sur A*</h2>

<p>Voici le pseudo-code correspondant à la version A* de notre algorithme.</p>

<pre>
f = CréerFilePrioritaire()
f.enfiler(source)

<b>Tant Que</b> f est non vide, <b>Faire</b>
    s = f.défiler() // supprime également l'élément
    <b>pour tout</b> voisin v de s, <b>Faire</b>
        <b>si</b> parent[v] == null, <b>Alors</b>
            parent[v] &larr; s 
            priorité &larr; estimerQualité(v)
            f.enfiler(v, priorité)
</pre>

<p><strong>Attention :</strong> L’utilisation d’une file prioritaire en Java comporte des différences importantes avec ce code, qui feront l’objet de questions dédiées. Mais conceptuellement, ce code correspond bien à ce que nous allons faire.</p>

<h3 id="files-prioritaires-en-java">Files prioritaires en Java</h3>

<p><strong>→ Travail à faire (9.1)</strong> Trouver la classe Java standard qui correspond à une file prioritaire (elle existe !).</p>

<p>La classe que vous avez trouvée permet bien d’utiliser des priorités. Cependant, la façon de spécifier la priorité d’un élément est différente du pseudo-code ci-dessus. Plutôt que de la donner explicitement lors de l’insertion, l’ordre est automatiquement déterminé par la file, en comparant l’élément inséré avec les éléments présents via un <em>comparateur</em>.</p>

<p><strong>→ Travail à faire (9.2)</strong> Faire en sorte que l’une de vos classes implémente l’interface <code class="language-plaintext highlighter-rouge">Comparator&lt;Node&gt;</code> et créer la méthode <code class="language-plaintext highlighter-rouge">compare()</code> correspondante.</p>

<p>Le but de cette méthode est de comparer deux éléments passés en paramètres. Cette méthode sera appelée autant de fois que nécessaire lors d’une insertion, pour placer correctement le nouvel élément dans la file. Ces appels seront faits automatiquement, nous n’avons pas à nous en soucier, par contre nous devons bien fournir la méthode qui compare.</p>

<p><strong>→ Travail à faire (9.3)</strong> Faire en sorte que cette méthode compare les deux sommets passés en paramètre, en se basant sur le critère choisi à la question 8.2. La valeur de retour doit respecter la <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#compare-T-T-" target="_blank">spécification officielle</a>.</p>

<p><strong>→ Travail à faire (9.4)</strong> Implémenter l’algorithme complet ! (Spoiler alert: tout est presque déjà fait…) Attention, il faut stopper l’algorithme une fois la destination atteinte, sinon l’algorithme explorera tout le graphe.</p>

<p>Vous devriez obtenir un rendu similaire à celui des figures suivantes :</p>

<center>
  <img src="/assets/sae/astar.png" width="320" alt="after" />
	&nbsp;&nbsp;&nbsp;
  <img src="/assets/sae/astar-obstacle.png" width="320" alt="after" />
  <p class="caption">Figure 10. Recherche de chemin utilisant A*, sans obstacle (à gauche) ou avec obstacles (à droite).</p>
</center>

<p>Ces figures représentent les sommets explorés par l’algorithme au fur et à mesure et non le chemin final (même si les deux coïncident complètement dans l’exemple de gauche, et quasiment dans celui de droite). On peut vérifier qu’à chaque étape, l’algorithme choisit bien le sommet qui le rapproche le plus de la destination. Dans le cas de la figure de droite, on voit qu’une tentative a été effectuée sur un sommet qui s’est avéré être une impasse. C’est normal, l’estimation que nous utilisons pour la priorité n’anticipe pas les obstacles (ou les endroits vides). Mais globalement, on peut constater que la grande majorité du graphe n’a pas eu besoin d’être explorée, c’est la qualité principale de l’algorithme A*.</p>

<h3 id="-quiz-de-la-section-9">→ <a href="https://forms.gle/bMxcKURxhwDUpFpz6">QUIZ de la section 9</a></h3>

<hr />

<h2 id="10-génération-de-graphes">10) Génération de graphes</h2>

<p>Il n’y a pas de travail à effectuer dans cette section, nous expliquons simplement comment générer des graphes susceptibles de vous être utiles dans les sections suivantes (ou dans vos tests). Pour commencer, voici une méthode permettant de générer automatiquement une grille ayant autant de lignes que de colonnes.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    public static void genererGrille(Topology tp, int nbRows){
        int stepX = (tp.getWidth() - 100) / (nbRows - 1);
        int stepY = (tp.getHeight() - 100) / (nbRows - 1);
        if (Math.max(stepX, stepY) &gt;= 2 * Math.min(stepX, stepY)){
            String s = "les proportions de la topologie sont inadaptées";
            JOptionPane.showMessageDialog(null, s);
            return;
        }
        tp.setCommunicationRange(Math.max(stepX, stepY)+1);
        for (int i = 50; i &lt;= tp.getWidth() - 50; i += stepX){
            for (int j = 50; j &lt;= tp.getHeight() - 50; j += stepY) {
                tp.addNode(i, j, new Node());
            }
        }
    }
</code></pre></div></div>

<p>Le paramètre <code class="language-plaintext highlighter-rouge">nbRows</code> est le nombre de lignes (et de colonnes), par exemple si vous appelez <code class="language-plaintext highlighter-rouge">genererGrille(tp, 6)</code>, vous obtiendrez un graphe à $n = 36$ sommets représenté comme suit :</p>

<center>
  <img src="/assets/sae/grille.png" width="450" alt="after" />
  <p class="caption">Figure 10. Génération d'une grille.</p>
</center>

<p>Notez que les arêtes sont créées automatiquement selon la distance entre les noeuds (le seuil est calculé exprès et fixé via <code class="language-plaintext highlighter-rouge">setCommunicationRange()</code>). Si vous préférez créer vos propres graphes en spécifiant vous mêmes les arêtes, il suffit de désactiver les arêtes automatiques (<code class="language-plaintext highlighter-rouge">tp.disableWireless()</code>) et de créer vos objets de type <code class="language-plaintext highlighter-rouge">Node</code> et <code class="language-plaintext highlighter-rouge">Link</code> directement, par exemple le code</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="nc">Node</span> <span class="n">n1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Node</span><span class="o">();</span>
    <span class="nc">Node</span> <span class="n">n2</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Node</span><span class="o">();</span>
    <span class="n">tp</span><span class="o">.</span><span class="na">addNode</span><span class="o">(</span><span class="mi">100</span><span class="o">,</span> <span class="mi">100</span><span class="o">,</span> <span class="n">n1</span><span class="o">);</span>
    <span class="n">tp</span><span class="o">.</span><span class="na">addNode</span><span class="o">(</span><span class="mi">500</span><span class="o">,</span> <span class="mi">100</span><span class="o">,</span> <span class="n">n2</span><span class="o">);</span>
    <span class="n">tp</span><span class="o">.</span><span class="na">addLink</span><span class="o">(</span><span class="k">new</span> <span class="nc">Link</span><span class="o">(</span><span class="n">n1</span><span class="o">,</span> <span class="n">n2</span><span class="o">));</span>
</code></pre></div></div>

<p>crée un graphe représenté comme suit :</p>

<center>
  <img src="/assets/sae/K2.png" width="450" alt="after" />
  <p class="caption">Figure 11. Génération "manuelle" d'un graphe.</p>
</center>

<h2 id="11-complexité-algorithmique">11) Complexité algorithmique</h2>

<p>La fin de cette SAÉ s’intéressera à la <em>complexité algorithmique</em> des algorithmes considérés, c’est à dire le nombre d’opérations qu’ils nécessitent en fonction de certaines propriétés du graphe. Les séances auront lieu en salle de classe, avec vos professeurs de mathématique. Ils ne donneront peut-être pas lieu à des développements supplémentaires, mais le contenu de ces cours sera intégré au quiz final.</p>

<p>        </p>

<p>        </p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[Informations préalables]]></summary></entry></feed>