<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ennio Italiano</title><link>https://ennioitaliano.github.io/</link><description>Recent content on Ennio Italiano</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 07 Sep 2026 13:41:00 +0100</lastBuildDate><atom:link href="https://ennioitaliano.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>MSc CS Thesis #09 - Building the Graph</title><link>https://ennioitaliano.github.io/posts/private/thesis/graph-building/</link><pubDate>Mon, 07 Sep 2026 13:41:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/graph-building/</guid><description>&lt;p&gt;Given an &lt;a href="../input-parsing/#getting-a-single-instance"&gt;&lt;code&gt;Instance&lt;/code&gt;&lt;/a&gt;and a &lt;a href="../program-input/#model-parameters"&gt;&lt;code&gt;Config&lt;/code&gt;&lt;/a&gt;, it&amp;rsquo;s now time to build the graph. Particularly, we will use those two objects to instantiate a &lt;code&gt;GraphBuilder&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;We will now analyze in detail what happens inside the &lt;code&gt;Build()&lt;/code&gt; method of the &lt;code&gt;GraphBuilder&lt;/code&gt; class, which has the following signature:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;tuple&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;melon&lt;span style="color:#f92672"&gt;::&lt;/span&gt;static_forward_digraph, std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; Build() &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The return type of the method is a tuple made of a &lt;code&gt;static_forward_digraph&lt;/code&gt; (a type of graph from the &lt;a href="../graph-library"&gt;MELON library&lt;/a&gt;) and a vector of &lt;code&gt;double&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>MSc CS Thesis #08 - Computing Costs</title><link>https://ennioitaliano.github.io/posts/private/thesis/cost-computation/</link><pubDate>Mon, 07 Sep 2026 11:20:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/cost-computation/</guid><description>&lt;p&gt;The cost calculation logic has been divided in three different components: &lt;code&gt;DistanceMatrix&lt;/code&gt;, &lt;code&gt;CostEvaluator&lt;/code&gt;, and &lt;code&gt;TransitionCost&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="distancematrix"&gt;&lt;code&gt;DistanceMatrix&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;DistanceMatrix&lt;/code&gt; class simply stores the number of total locations (including depots), the &lt;a href="../cost-function#travel-costs"&gt;travel cost multiplier&lt;/a&gt; ($\beta$), and a &lt;code&gt;std::vector&amp;lt;double&amp;gt;&lt;/code&gt; containing the euclidean distances between every possible pair of stations.
Particularly, the latter is computed inside &lt;code&gt;DistanceMatrix&lt;/code&gt;&amp;rsquo;s constructor body.&lt;/p&gt;
&lt;p&gt;To access a distance between two locations, the&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; DistanceMatrix&lt;span style="color:#f92672"&gt;::&lt;/span&gt;GetDistance(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; from_station_id, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; to_station_id) &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;method is exposed; inside it, the convention that location (≠ station) 0 corresponds to the depot and locations 1..N are the inner stations is enforced, and after having computed the two &amp;ldquo;real&amp;rdquo; locations corresponding to the passed stations, &lt;code&gt;distances_[loc_u * total_locations_ + loc_v]&lt;/code&gt; is returned.&lt;/p&gt;</description></item><item><title>MSc CS Thesis #07 - The Nodes</title><link>https://ennioitaliano.github.io/posts/private/thesis/nodes/</link><pubDate>Thu, 03 Sep 2026 17:43:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/nodes/</guid><description>&lt;p&gt;We need a way to represent a single node in memory. To this aim, the &lt;code&gt;Node&lt;/code&gt; struct has been created:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; station_id;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; scooter_load;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; battery_load;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This matches what we already said about each node of the graph, which is a combination of the e-scooters and fully-charged batteries load at a given station.&lt;/p&gt;
&lt;h2 id="encoding-nodes"&gt;Encoding Nodes&lt;/h2&gt;
&lt;p&gt;We are dealing with a layered graph in which we know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the number of layers: the number of stations of a given cluster;&lt;/li&gt;
&lt;li&gt;the number of nodes per layer: $(C+1)\times(B+1)$, where $C$ and $B$ are respectively the e-scooters capacity of the truck and its fully-charged batteries capacity.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hence, a &lt;code&gt;NodeCodec&lt;/code&gt; class has been created to encode (and, conversely, decode) each &lt;code&gt;Node&lt;/code&gt; into an integer number via &lt;a href="https://wikipedia.org/wiki/Mixed_radix"&gt;mixed-radix&lt;/a&gt; encoding:&lt;/p&gt;</description></item><item><title>MSc CS Thesis #06 - Parsing &amp; Loading</title><link>https://ennioitaliano.github.io/posts/private/thesis/input-parsing/</link><pubDate>Thu, 03 Sep 2026 14:33:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/input-parsing/</guid><description>&lt;h2 id="spreadsheet-to-json"&gt;Spreadsheet-to-JSON&lt;/h2&gt;
&lt;p&gt;To first parse the &lt;a href="../program-input#the-dataset"&gt;dataset spreadsheet&lt;/a&gt; and convert it to a more manageable JSON object, a Python script has been vibe-coded.
It parses all the sheets (stations, coordinates, clusters, depots,
daily demands, and SOC matrices) from datasets formatted like the one we inherited and produces a structured, clean JSON file to be used in my C++ program.&lt;/p&gt;
&lt;p&gt;The usage is very simple, since it&amp;rsquo;s enough to run this command from the terminal:&lt;/p&gt;</description></item><item><title>MSc CS Thesis #05 - Input Data</title><link>https://ennioitaliano.github.io/posts/private/thesis/program-input/</link><pubDate>Wed, 02 Sep 2026 15:01:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/program-input/</guid><description>&lt;p&gt;Now it&amp;rsquo;s time to jump into the code, starting from what will be the program&amp;rsquo;s input data.&lt;/p&gt;
&lt;h2 id="the-dataset"&gt;The Dataset&lt;/h2&gt;
&lt;p&gt;We already have a reference input dataset coming from the old Python project, containing some data about e-scooters traffic in the city of Bari, Italy.
Unfortunately, it is an Excel (&lt;code&gt;.xlsx&lt;/code&gt;) spreadsheet. But let&amp;rsquo;s analyze its structure first.&lt;/p&gt;
&lt;p&gt;The spreadsheet contains 19 different sheets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;giorni&lt;/code&gt;: list of days taken into account for the experiment;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;we&lt;/code&gt;: binary variable indicating whether a certain day is a weekday;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;id z&lt;/code&gt;: id numbers of 293 different locations;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;id z cluster zone wd&lt;/code&gt; / &lt;code&gt;id z cluster zone we&lt;/code&gt;: maps each zone/station to an equity cluster (defined in &lt;code&gt;p coeff zone wd&lt;/code&gt; / &lt;code&gt;p coeff zone we&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p coeff zone wd&lt;/code&gt; / &lt;code&gt;p coeff zone we&lt;/code&gt;: social equity clusters. Each row defines values to compute cost/penalty function for the Gini index associated with that cluster - ideal number of vehicle per cluster, and money penalty for shortage or excess;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;START conf&lt;/code&gt;: total e-scooters availability per station, for each day;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;START conf carichi 17.5&lt;/code&gt;: e-scooters with charge &amp;gt;= 17.5% per station, for each day - used as target demand;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;START conf scarichi 17.5&lt;/code&gt;: e-scooters with charge &amp;lt; 17.5% per station, for each day;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;START conf pert&lt;/code&gt; / &lt;code&gt;START conf pert carichi 17.5&lt;/code&gt; / &lt;code&gt;START conf pert scarichi 17.5&lt;/code&gt;: perturbed data starting from base (real) data to test algorithms&amp;rsquo; robustness wrt demand/state variations - used as effective state at the beginning of the truck&amp;rsquo;s tour;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;START soc matrix&lt;/code&gt; / &lt;code&gt;START soc pert matrix&lt;/code&gt;: each row defines a day, the id of a station, the id of an e-scooter and its SoC for that combination. The perturbed matrix is used to introduce a more realistic discharge level, increasing battery swap/scooters pickup operations;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;XY&lt;/code&gt;: coordinates of each of the 293 locations;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;XY DEPOTS&lt;/code&gt;: coordinates of (real) depots;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;id z cluster rilocazione&lt;/code&gt;: the 293 locations are partitioned in 3 different clusters; the mapping is done here;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;XY CLUSTER DEPOTS&lt;/code&gt;: &amp;ldquo;virtual&amp;rdquo; depot (start/end point for the truck in that zone) for each cluster, obtained by running k-medoids algorithm on each cluster.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="model-parameters"&gt;Model Parameters&lt;/h2&gt;
&lt;p&gt;Other than the dataset spreadsheet, there&amp;rsquo;s also some other configuration data, that were hardcoded in one of the Python files composing the old project. That data was about global parameters for the optimisation model and vehicles.&lt;/p&gt;</description></item><item><title>MSc CS Thesis #04 - The Library</title><link>https://ennioitaliano.github.io/posts/private/thesis/graph-library/</link><pubDate>Wed, 02 Sep 2026 10:36:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/graph-library/</guid><description>&lt;p&gt;I want to attack the shortest path problem first, given a pre-defined sequence of stations.&lt;/p&gt;
&lt;p&gt;Before jumping into the code, a PhD student working on similar problems suggested me some C++ libraries about graphs to look into. The suggested ones are graph-v3, Graaf and MELON.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/stdgraph/graph-v3"&gt;graph-v3&lt;/a&gt; is an implementation of a C++ standardization proposal. While it is generic and idiomatic C++20 (and also supports custom graph structures), standard library proposals prioritize safety, generality, and interface stability over the absolute bleeding-edge performance achievable by specialized operations research libraries.&lt;/p&gt;</description></item><item><title>MSc CS Thesis #03 - The Task</title><link>https://ennioitaliano.github.io/posts/private/thesis/task/</link><pubDate>Wed, 02 Sep 2026 10:18:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/task/</guid><description>&lt;p&gt;After having described &lt;a href="../problem"&gt;the problem&lt;/a&gt; and &lt;a href="../approach"&gt;the selected approach&lt;/a&gt; (also detailing &lt;a href="../cost-function"&gt;cost calculation&lt;/a&gt;), now it&amp;rsquo;s time to talk about what my actual task for this Master Thesis is.&lt;/p&gt;
&lt;p&gt;The already described approach was implemented by Lombardo in Python, but the other professors working with him found the results of the experiment ok but not really satisfying as expected.&lt;/p&gt;
&lt;p&gt;The doubt they now want to clarify is whether the approach is fundamentally wrong, or if it&amp;rsquo;s just an implementation problem. To find out, they gave me the task of re-implementing the system using C++, with all the memory optimizations and tricks that come with it.&lt;/p&gt;</description></item><item><title>MSc CS Thesis #02 - The Cost Function</title><link>https://ennioitaliano.github.io/posts/private/thesis/cost-function/</link><pubDate>Wed, 02 Sep 2026 08:59:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/cost-function/</guid><description>&lt;p&gt;&lt;a href="../approach"&gt;We already saw&lt;/a&gt; that we are dealing with a layered DAG, in which we&amp;rsquo;d like to find the tour with minimum cost from/to the depot. A crucial point to this aim is to clearly define how we&amp;rsquo;d like such cost to be computed.&lt;/p&gt;
&lt;p&gt;As a matter of fact, distance alone would not be that useful to us: we&amp;rsquo;d like to factor in also demand fulfillment at each station (meaning how distant we are from target demand of vehicles after the operation we did there) and deviation from social equity (trying to minimize the differences in availability between different zones, not favoring central/nice/rich neighborhoods over others).&lt;/p&gt;</description></item><item><title>MSc CS Thesis #01 - The Approach</title><link>https://ennioitaliano.github.io/posts/private/thesis/approach/</link><pubDate>Tue, 01 Sep 2026 17:43:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/approach/</guid><description>&lt;p&gt;I will not define myself a way to approach the &lt;a href="../problem"&gt;e-Vehicle Rebalancing Tour Problem&lt;/a&gt; (will be more precise later on about what exactly is my task for this master thesis).&lt;/p&gt;
&lt;p&gt;In fact, the approach has been already defined by Vincenzo Lombardo, a student from Milan who decided to model the problem using shortest paths on a specific weighted graph.&lt;/p&gt;
&lt;p&gt;Particularly, he decided to move away from mathematical programming, modeling the distribution of e-vehicles in a city as a layered directed acyclic graph (DAG), with one layer per station (intended as different stage to pickup/drop-off scooters) and each node representing the state of the truck in terms of loaded vehicles and (charged) batteries.&lt;/p&gt;</description></item><item><title>MSc CS Thesis #00 - The Problem</title><link>https://ennioitaliano.github.io/posts/private/thesis/problem/</link><pubDate>Tue, 01 Sep 2026 16:24:00 +0100</pubDate><guid>https://ennioitaliano.github.io/posts/private/thesis/problem/</guid><description>&lt;p&gt;Among different categories of bike (or scooters) sharing systems, free-floating ones are characterized by the fact that users can leave the chosen mean of transportation wherever they want, without worrying about precise placement at dedicated stations.&lt;/p&gt;
&lt;p&gt;This comes with a downside: after a day of intensive use of the system, places in which they would have been very useful and requested could be left without enough of them. At the same time, it could be that some of them are completely abandoned in front of some random user&amp;rsquo;s door from the previous day, without being used at all.&lt;/p&gt;</description></item></channel></rss>