From 3a8e7b47b19fa3dcd9c843f740648510d1bf9d14 Mon Sep 17 00:00:00 2001 From: umcconnell Date: Wed, 1 May 2024 18:55:21 +0000 Subject: [PATCH] deploy: be884006638e172274ee0e111d480569868ab0b5 --- 404.html | 2 +- about/index.html | 2 +- build.txt | 4 ++-- index.html | 2 +- posts/2021-03-11-hello-internet/index.html | 2 +- posts/2021-03-13-fibonacci-rust/index.html | 2 +- posts/2021-03-30-meta-blog-basics/index.html | 2 +- posts/2021-03-31-meta-blog-advanced/index.html | 2 +- posts/2024-03-19-kleitman-winston/index.html | 2 +- posts/index.html | 2 +- posts/tags/beginner/index.html | 2 +- posts/tags/blog/index.html | 2 +- posts/tags/combinatorics/index.html | 2 +- posts/tags/fibonacci/index.html | 2 +- posts/tags/graph theory/index.html | 2 +- posts/tags/math/index.html | 2 +- posts/tags/posts/index.html | 2 +- posts/tags/programming/index.html | 2 +- posts/tags/rust/index.html | 2 +- posts/tags/webdev/index.html | 2 +- projects/index.html | 2 +- 21 files changed, 22 insertions(+), 22 deletions(-) diff --git a/404.html b/404.html index d9c13f69..c955bdf6 100644 --- a/404.html +++ b/404.html @@ -1 +1 @@ -umcconnellskip to main content

404

Page not found.

Maybe these links can help you to get back on track:

If you think this is an error, you can report an issue on Github.

\ No newline at end of file +umcconnellskip to main content

404

Page not found.

Maybe these links can help you to get back on track:

If you think this is an error, you can report an issue on Github.

\ No newline at end of file diff --git a/about/index.html b/about/index.html index e7fa4d1b..0dc5e94f 100644 --- a/about/index.html +++ b/about/index.html @@ -49,4 +49,4 @@ oEJFKo7VOZadqiYdLOQBd/dveXVsO7gJQl5KCg9wbRUzgxnkGsyfdHPDxS0jnBk= =94sS -----END PGP PUBLIC KEY BLOCK----- -

Blog

This blog is built with open-source software components. Here are some of the main ones used in this blog:

\ No newline at end of file +

Blog

This blog is built with open-source software components. Here are some of the main ones used in this blog:

\ No newline at end of file diff --git a/build.txt b/build.txt index b6bd3c23..d15a479b 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ -LAST BUILD: 2024-05-01T18:55:12.491 -COMMIT: 0fdc7a29a5a8eac459cf4bc25f87c2ee2af98521 +LAST BUILD: 2024-05-01T18:55:16.695 +COMMIT: be884006638e172274ee0e111d480569868ab0b5 ENV: production \ No newline at end of file diff --git a/index.html b/index.html index 336e0d66..51bcd45f 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -umcconnellskip to main content

👋 Hi

This is my own personal website and blog on the endless expanses of the internet. Every once in a while, I try to write about my ideas and different technical topics, mostly related to programming. Feel free to look around and explore...

All views and opinions expressed in this blog are my own.

By the way: This website is open source. All code is licensed under the MIT license, the content is available under the CC-BY-SA 4.0 license, unless stated otherwise.

Latest posts

  1. Kleitman-Winston Algorithm
  2. Meta Blog: Advanced
  3. Meta Blog: Basics
  4. Fibonacci in Rust
  5. Hello Internet
\ No newline at end of file +umcconnellskip to main content

👋 Hi

This is my own personal website and blog on the endless expanses of the internet. Every once in a while, I try to write about my ideas and different technical topics, mostly related to programming. Feel free to look around and explore...

All views and opinions expressed in this blog are my own.

By the way: This website is open source. All code is licensed under the MIT license, the content is available under the CC-BY-SA 4.0 license, unless stated otherwise.

Latest posts

  1. Kleitman-Winston Algorithm
  2. Meta Blog: Advanced
  3. Meta Blog: Basics
  4. Fibonacci in Rust
  5. Hello Internet
\ No newline at end of file diff --git a/posts/2021-03-11-hello-internet/index.html b/posts/2021-03-11-hello-internet/index.html index 98643431..d12a78d3 100644 --- a/posts/2021-03-11-hello-internet/index.html +++ b/posts/2021-03-11-hello-internet/index.html @@ -1,3 +1,3 @@ umcconnell | Hello Internetskip to main content

Hello Internet

Kicking off my blog with the mandatory "Hello World" introductory post... More posts about software, technology and science to come!

Hi!

This is the first post on my new blog, and I’m really excited. I hope to write more in the coming weeks and months, especially about technical and software-related topics. My goal is to write about current software side projects and things I’ve learned, all in the spirit of “Stay curious, keep learning”. Depending on how that works out, I’ll adapt if needed.

Outlook

A few topics I’d like to cover soon are AI, Rust and how I set up this blog, to give some ideas in case you would like to do the same. In the meantime, as this blog is entirely open source, I invite you to check out the source codeon Github, fork it, make it your own, or whatever you want.

Why?!?

I hope to learn something useful from this experience and gain some more experience building websites. Writing down ideas and summarizing problems is a good exercise, all while improving writing skills. A blog also let’s me document findings and ideas for later use or for someone else to be inspired.

And maybe I can even help solve a problem on the way or motivate to learn something new!

Feel free to comment on any post, give feedback, suggest improvements, correct me or whatever else you think is appropriate.

Cheers!

- Ulysse

\ No newline at end of file +">skip to main content

Hello Internet

Kicking off my blog with the mandatory "Hello World" introductory post... More posts about software, technology and science to come!

Hi!

This is the first post on my new blog, and I’m really excited. I hope to write more in the coming weeks and months, especially about technical and software-related topics. My goal is to write about current software side projects and things I’ve learned, all in the spirit of “Stay curious, keep learning”. Depending on how that works out, I’ll adapt if needed.

Outlook

A few topics I’d like to cover soon are AI, Rust and how I set up this blog, to give some ideas in case you would like to do the same. In the meantime, as this blog is entirely open source, I invite you to check out the source codeon Github, fork it, make it your own, or whatever you want.

Why?!?

I hope to learn something useful from this experience and gain some more experience building websites. Writing down ideas and summarizing problems is a good exercise, all while improving writing skills. A blog also let’s me document findings and ideas for later use or for someone else to be inspired.

And maybe I can even help solve a problem on the way or motivate to learn something new!

Feel free to comment on any post, give feedback, suggest improvements, correct me or whatever else you think is appropriate.

Cheers!

- Ulysse

\ No newline at end of file diff --git a/posts/2021-03-13-fibonacci-rust/index.html b/posts/2021-03-13-fibonacci-rust/index.html index 0d723f08..4b094eb8 100644 --- a/posts/2021-03-13-fibonacci-rust/index.html +++ b/posts/2021-03-13-fibonacci-rust/index.html @@ -130,4 +130,4 @@ } criterion_group!(benches, bench_fibs); -criterion_main!(benches);

This code creates a test group called Fibonacci and benchmarks the four different approaches using the same input. Run the benchmark in your terminal:

cargo bench

Once the benchmarks are done, you can view a nice HTML report in your browser by opening target/criterion/Fibonacci/report/index.html. Running on my machine gave me the following stats:

Performance plot of the different methods

You can clearly see, that the naive recursive solution is the least performant approach, as its execution time increases (exponentially, but not visible with 2 inputs) with the workload. The memoized version, in contrast, shows a great improvement, but it still incurs the performance overhead of initializing and managing the memo, making it less performant than the two last approaches.

The iterator and standard seem to be indistinguishable. On my machine, the execution of the iterator takes ~34ns for both inputs, the standard approach around ~4.5ns for both inputs.

You can find more detailed graphs and charts for every function in the corresponding target/criterion/Fibonacci/<APPROACH>/report/index.html folder.

Conclusion

We’ve implemented and benchmarked four different approaches to generating the Fibonacci sequence.

Although the recursive solution is short and concise, it is by far the least performant and can become too slow to calculate for larger inputs. The memoized solution is interesting, in that it combines the conciseness of the recursive approach with a greater speed. The standard approach, on the other hand, seems to be the fastest, but it is arguably the least elegant.

Finally, the iterator solution appears to be by far the most versatile while at the same time being very fast. Additionally, it allows the user to work with the sequence in a very convenient way, e.g. by filtering, mapping, etc.

Overall, it becomes clear that iterators are a very versatile and performant aspect of Rust, that are also worth considering in other languages such as Python or JavaScript.

The final code of this project is open source and available here: https://github.com/umcconnell/rust_fibonacci

Feedback, questions, comments or improvements are welcome!

Thanks for reading.

\ No newline at end of file +criterion_main!(benches);

This code creates a test group called Fibonacci and benchmarks the four different approaches using the same input. Run the benchmark in your terminal:

cargo bench

Once the benchmarks are done, you can view a nice HTML report in your browser by opening target/criterion/Fibonacci/report/index.html. Running on my machine gave me the following stats:

Performance plot of the different methods

You can clearly see, that the naive recursive solution is the least performant approach, as its execution time increases (exponentially, but not visible with 2 inputs) with the workload. The memoized version, in contrast, shows a great improvement, but it still incurs the performance overhead of initializing and managing the memo, making it less performant than the two last approaches.

The iterator and standard seem to be indistinguishable. On my machine, the execution of the iterator takes ~34ns for both inputs, the standard approach around ~4.5ns for both inputs.

You can find more detailed graphs and charts for every function in the corresponding target/criterion/Fibonacci/<APPROACH>/report/index.html folder.

Conclusion

We’ve implemented and benchmarked four different approaches to generating the Fibonacci sequence.

Although the recursive solution is short and concise, it is by far the least performant and can become too slow to calculate for larger inputs. The memoized solution is interesting, in that it combines the conciseness of the recursive approach with a greater speed. The standard approach, on the other hand, seems to be the fastest, but it is arguably the least elegant.

Finally, the iterator solution appears to be by far the most versatile while at the same time being very fast. Additionally, it allows the user to work with the sequence in a very convenient way, e.g. by filtering, mapping, etc.

Overall, it becomes clear that iterators are a very versatile and performant aspect of Rust, that are also worth considering in other languages such as Python or JavaScript.

The final code of this project is open source and available here: https://github.com/umcconnell/rust_fibonacci

Feedback, questions, comments or improvements are welcome!

Thanks for reading.

\ No newline at end of file diff --git a/posts/2021-03-30-meta-blog-basics/index.html b/posts/2021-03-30-meta-blog-basics/index.html index 79a8cfc4..fe053b76 100644 --- a/posts/2021-03-30-meta-blog-basics/index.html +++ b/posts/2021-03-30-meta-blog-basics/index.html @@ -17,4 +17,4 @@ This is my _brand new_ blog. **Enjoy**!

That’s it! You’re blog is ready to go online.

Publishing

After customizing the blog, we are now ready to publish our blog. We will publish the blog on Github pages. After following these steps, your page will be available at https://GH_USERNAME.github.io.

Committing

Start by committing all your customization changes to git. In the root folder of the blog, run:

git add .
 git commit -av

Creating Repositories

Next, we’ll create the Git repositories that will hold the source code of your blog and the comments to your posts.

In your web browser, navigate to github.com/newto create a new repository.

For the comments repo, enter comments as the repository name. Make sure, the repo visibility is set to “Public”, before hitting the “Create repository” button.

Repeat this step for the repo that is going to hold the blog’s source code. Enter GH_USERNAME.github.io as repo name (where GH_USERNAME is your Github username) and select the visibility “Public”. Then, create the repository.

You should see a set of instructions to publish your code. Note the instructions to “push an existing repository from the command line”. When executing these instructions in the root folder of your blog, you will need to change one command. Because you have cloned the original blog code from Github, it already has a remote git origin set. You will need to use set-url instead of add here:

git remote set-url origin https://github.com/GH_USERNAME/GH_USERNAME.github.io.git
 git branch -M main
-git push -u origin main

Github Pages

The last step is to publish your pages using Github pages. In your repository containing the blog source, navigate to the “Settings” tab. Almost at the bottom of the page, you should find a “Github pages section”.

Github Pages section in the repository settings

From the source drop-down, select the “gh-pages” branch. After hitting the save button, your site should be available online.

Video tutorial

My friend Boldizsar Zopcsak and I recorded a video tutorial about this whole procedure a little while ago. The video goes through the basics of cloning, personalizing and publishing your next blog. Feel free to have a look:

For a look at the technical details of this blog, head over to Part 2 of this series.

\ No newline at end of file +git push -u origin main

Github Pages

The last step is to publish your pages using Github pages. In your repository containing the blog source, navigate to the “Settings” tab. Almost at the bottom of the page, you should find a “Github pages section”.

Github Pages section in the repository settings

From the source drop-down, select the “gh-pages” branch. After hitting the save button, your site should be available online.

Video tutorial

My friend Boldizsar Zopcsak and I recorded a video tutorial about this whole procedure a little while ago. The video goes through the basics of cloning, personalizing and publishing your next blog. Feel free to have a look:

For a look at the technical details of this blog, head over to Part 2 of this series.

\ No newline at end of file diff --git a/posts/2021-03-31-meta-blog-advanced/index.html b/posts/2021-03-31-meta-blog-advanced/index.html index 2a23ed61..e9293b08 100644 --- a/posts/2021-03-31-meta-blog-advanced/index.html +++ b/posts/2021-03-31-meta-blog-advanced/index.html @@ -36,4 +36,4 @@ An informative message that **even** supports _Markdown_! {% endmsg %}

This produces the following:

INFO

An informative message that even supports Markdown!

The paired shortcodes available out of the box are:

KaTeX

You can also include math expressions in your post. The expressions are compiled using KaTeX, which allows you to write TeX-like expressions. All KaTeX configurations are located in config/markdown-it/katex.js.

For inline math expressions, wrap your code in single dollar signs: $math$. For example, you can easily include fractions:

A fraction $\frac{a}{b}$ includes a numerator $a$ and a denominator $b$.

This produces the following text:

A fraction ab\frac{a}{b} includes a numerator aa and a denominator bb.

For blocks of math, wrap your code in double dollar signs: $$ math $$. For example, you can display Euler’s identity:

Euler's identity:
-$$e^{i \pi} = -1$$

This results in:

Euler’s identity:

eiπ=1e^{i \pi} = -1

You can find all supported expressions and formatting options in the KaTeX docs.

Nunjucks

Nunjucksis used as the templating language for the blog.

There are several places where Nunjucks is used:

11ty

Most of the 11ty-related configuration is placed in the .eleventy.jsfile.

Note, that if you are serving this website from a subproject on Github pages, i.e. when you are not using GH_USERNAME.github.io, but rather GH_USERNAME.github.io/PROJECT/, you must change the 11ty pathPrefix field in the configuration file. The setting is commented out in this website’s configuration.

In development mode (npm run dev), Markdown posts and images in the src/posts/drafts/ folder will also be built and served. They do, however, not appear in production mode and are not tracked by git.

Icons

All icons placed in the src/assets/icons/folder will be grouped into an SVG sprite to improve loading time. The icons can then be used via the icon shortcode.

Plugins

The 11ty plugins used in this blog are:

You can find the full list of available plugins in the 11ty docs

Webpack & Babel

All JavaScript code referenced in src/assets/scripts/main.jsis transpiled to backwards compatible JavaScript using babelto support older browsers.

The code files are then bundled using webpack, with the webpack configuration file located at src/assets/scripts/scripts.11ty.js. The bundling process uses an in-memory file system to bundle the scripts in memory and return the bundled result as a reusable JS string.

Github

The site is automatically built and linted using the provided Github Actions workflows. The workflow files are located in the .github/workflows/folder.

The lint action uses Prettier to check the code for styling and formatting issues. See the VSCode section for information on the Prettier extension to automatically format your code when you save.

VSCode

For VSCode users, I recommend installing the Prettier extensionto automatically format your code and posts on save. All recommended plugins are listed in the .vscode/folder. These recommendations should be automatically suggested when first opening the project in the editor.

That was it. Thanks for reading!

\ No newline at end of file +$$e^{i \pi} = -1$$

This results in:

Euler’s identity:

eiπ=1e^{i \pi} = -1

You can find all supported expressions and formatting options in the KaTeX docs.

Nunjucks

Nunjucksis used as the templating language for the blog.

There are several places where Nunjucks is used:

11ty

Most of the 11ty-related configuration is placed in the .eleventy.jsfile.

Note, that if you are serving this website from a subproject on Github pages, i.e. when you are not using GH_USERNAME.github.io, but rather GH_USERNAME.github.io/PROJECT/, you must change the 11ty pathPrefix field in the configuration file. The setting is commented out in this website’s configuration.

In development mode (npm run dev), Markdown posts and images in the src/posts/drafts/ folder will also be built and served. They do, however, not appear in production mode and are not tracked by git.

Icons

All icons placed in the src/assets/icons/folder will be grouped into an SVG sprite to improve loading time. The icons can then be used via the icon shortcode.

Plugins

The 11ty plugins used in this blog are:

You can find the full list of available plugins in the 11ty docs

Webpack & Babel

All JavaScript code referenced in src/assets/scripts/main.jsis transpiled to backwards compatible JavaScript using babelto support older browsers.

The code files are then bundled using webpack, with the webpack configuration file located at src/assets/scripts/scripts.11ty.js. The bundling process uses an in-memory file system to bundle the scripts in memory and return the bundled result as a reusable JS string.

Github

The site is automatically built and linted using the provided Github Actions workflows. The workflow files are located in the .github/workflows/folder.

The lint action uses Prettier to check the code for styling and formatting issues. See the VSCode section for information on the Prettier extension to automatically format your code when you save.

VSCode

For VSCode users, I recommend installing the Prettier extensionto automatically format your code and posts on save. All recommended plugins are listed in the .vscode/folder. These recommendations should be automatically suggested when first opening the project in the editor.

That was it. Thanks for reading!

\ No newline at end of file diff --git a/posts/2024-03-19-kleitman-winston/index.html b/posts/2024-03-19-kleitman-winston/index.html index f245ac9e..08c1f997 100644 --- a/posts/2024-03-19-kleitman-winston/index.html +++ b/posts/2024-03-19-kleitman-winston/index.html @@ -1,3 +1,3 @@ umcconnell | Kleitman-Winston Algorithmskip to main content

Kleitman-Winston Algorithm

Graph containers & bounds on the number of independent sets in a locally dense graph.

Overview

We will show that for a locally dense graph we can give a strong upper bound on the number of independent sets of a certain size. This specific method for graphs is an instance of the so-called container method, that allows to give bounds on structures appearing in larger objects with specific local properties. More specifically as applied to graph theory, this turns out to be quite helpful in proving lower bounds in Ramsey theory.

The proof presented here follows the one presented in the survey paper by Samotij [1] using methods originally presented in the paper by Winston and Kleitman [2]. Some elementary knowledge of graph theory is helpful, such as the notion of independent sets and induced subgraphs, but I try to be as explicit and clear as possible. I will try to stick to common graph theoretical notation, but for the sake of both readability and completeness an overview of notation is given at the end of the post.

Basic bounds

Let’s start with some basic bounds on the number of independent sets I(G)|\mathcal{I}(G)| in a graph GG. Recall that an independent set is a set of vertices in which no two are connected by an edge. If α(G)\alpha(G) refers to the independence number, ie. the size of the largest independent set in GG, we can certainly say that

2α(G)I(G)2^{\alpha(G)} \leq |\mathcal{I}(G)|

because every subset of the largest independent set is itself an independent set (recall that 2N2^{|N|} is the number of different subsets that can be formed from a set NN).

Similarly, we can give an upper bound of

I(G)k=0α(G)(V(G)k)|\mathcal{I}(G)| \leq \sum_{k=0}^{\alpha(G)} \binom{|V(G)|}{k}

as every independent set is a subset of size at most α(G)\alpha(G) over the vertices of GG.

Theorem Statement

We will now bound the number of independent sets of a certain size in a locally dense graph by showing that every independent set is part of a small container. These containers are constructed with the Kleitman-Winston algorithm. By counting these countainers, we can estimate the number of independent sets. The tightness property of the containers then allows us to give useful bounds on the number of independent sets.

Let us now turn to the actual theorem. For N,R,qNN, R, q \in \mathbb{N} and βR\beta \in \mathbb{R} with β[0,1]\beta \in [0, 1], let GG be a graph on NN vertices satisfying:

NReβq(1)\tag{1} N \leq R e^{\beta q}

In addition, we also require that G must be a β\beta-locally dense graph. That is, for every vertex subset AV(G)A \subseteq V(G) of size at least RR we have the following lower bound on the number of edges in the induced subgraph G[A]G[A]:

eG(A)β(A2)(2)\tag{2} e_G(A) \geq \beta \binom{|A|}{2}

Note that this corresponds to the situation where the subgraph spanned by AA over GG contains at least a β\beta-fraction of the edges of the corresponding complete graph over AA, or in other words, that the average degree of AA is at least β(A1)\beta (|A| - 1).

Theorem

Given such a β\beta-locally dense graph GG satisfying (1) and (2), we can construct up to (Nq)\binom{N}{q} small containers C1,,CiC_1, \dots, C_i for 1i(Nq)1 \leq i \leq \binom{N}{q} of size at most R+qR + q. Every independent set of size exactly q+kq + k for kqk \leq q belongs to a container CiC_i.

For the number of independent sets in GG of size exactly q+kq + k we obtain:

I(G,q+k)(Nq)(Rk)(3)\tag{3} |\mathcal{I}(G, q + k)| \leq \binom{N}{q} \binom{R}{k}

Algorithm

Before describing the algorithm, let us fix a few technicalities. We need the notion of max-degree ordering to ensure high-degree vertices are quickly removed from the graph and the container quickly shrinks. For a vertex set AV(G)A \subseteq V(G), the max-degree ordering (v1,,vA)(v_1, \dots, v_{|A|}) is defined by the degree of vertices over the induced subgraph G[A]G[A] in descending order, where potential ties are broken by a fixed but arbitrary total order over V(G)V(G). In this case v1v_1 has the highest degree, etc.

The Kleitman-Winston algorithm works by iteratively removing high-degree vertices as outlined above:

Kleitman-Winston algorithm
  • Input: Independent set II(G)I \in \mathcal{I}(G), integer qIq \leq |I|
  • Output: selected vertices SS, available vertices AA
  • Procedure:
    1. Set available vertices A=V(G)A = V(G), selected vertices S=S = \varnothing
    2. Iterate for i=1,,qi=1, \dots, q:
      • Let A=(v1,,vA)A = (v_1, \dots, v_{|A|}) be ordered by max-degree
      • Let tit_i be the first index in the ordering of AA such that vtiIv_{t_i} \in I
        (i.e. first remaining vertex of II by max-degree ordering in induced subgraph G[A]G[A]).
      • Move vtiv_{t_i} from AA to SS
      • Remove higher-degree vertices Xi=(v1,,vti1)X_i = (v_1, \dots, v_{t_i - 1}) from AA:
        A=AXiA = A \setminus X_i
      • Remove vtiv_{t_i} and its neighborhood NA(vti)\mathcal{N}_A(v_{t_i}) from AA:
        A=A({vti}NA(vti))A = A \setminus (\{ v_{t_i} \} \cup \mathcal{N}_A(v_{t_i}))
    3. Output SS and AA

The container of II is given by C:=SAC := S \cup A. Notice that the tightness of the container is apparent in that fact that SICS \subseteq I \subseteq C.

Proof

The algorithm maintains a few invariants, that help prove correctness: A|A| decreases monotonically as we remove vertices in every iteration, while S|S| increases monotonically. Also notice that the previous observation SI(SA)S \subseteq I \subseteq (S \cup A) holds at every iteration of the algorithm.

It is clear that the algorithm always succeeds in constructing the set of selected vertices SS from qIq \leq |I| vertices of II. This is because the algorithm always selects the next highest degree vertex viv_i of II occuring in the subgraph G[A]G[A] at every step, i.e. no vertex viIv_i \in I is ever removed from AA and not added to SS as a discarded higher-degree vertex. In addition, the vertices of II form an independent set by assumption, and as such a vertex viv_i is never removed as part of the neighborhood of another selected vertex.

Size of A

To conclude tightness of the containers, we must show that the final AA returned from the algorithm is sufficiently small. In fact, we will show that AR|A| \leq R. In the following, we will denote by AiA_i the set of available vertices at the beginning of the i-th iteration of the algortithm, and by Ai=AiXiA'_i = A_i \setminus X_i the set of available vertices after removing higher-degree vertices but before remoing vtiIv_{t_i} \in I.

First, note that by the Handshaking lemmawe obtain an expression for the average degree of vertices:

1VvVdeg(v)=2EV(4)\tag{4} \frac{1}{|V|} \sum_{v \in V} deg(v) = \frac{2|E|}{|V|}

Suppose for sake of contradiction A>R|A| > R for the final set of available vertices. Then it must be that the vtiSv_{t_i} \in S selected in every iteration must have been selected from a set of size at least RR, even after removal of other higher-degree vertices (recall that A|A| decreases monotonically throughtout the algorithm). Or, in other words, at the start of the i-th iteration with currently available vertices AiA_i and higher-degree vertices XiX_i scheduled for removal, Ai:=AiXi>R|A'_i| := |A_i \setminus X_i| > R.

Using the bound (2) on the edge-count:

eG(Ai)β(Ai2)=βAi(Ai1)2e_G(A'_i) \geq \beta \binom{|A'_i|}{2} = \beta \frac{|A'_i|(|A'_i|-1)}{2}

As we choose vtiv_{t_i} with maximum degree from AiA'_i, we know vtiv_{t_i} must at least have the average degree (4) of AiA'_i:

degAi(vti)2eG(Ai)Aiβ(Ai1)\deg_{A'_i}(v_{t_i}) \geq \frac{2e_G(A'_i)}{|A'_i|} \geq \beta (|A'_i| - 1)

Recalling the definition of Ai|A'_i|:

Ai1=AiXi1=AiXi1Ai(ti1)1=Aiti\begin{aligned} |A'_i| - 1 = |A_i \setminus X_i| - 1 &= |A_i| - |X_i| - 1 \\ |A_i| - (t_i - 1) - 1 &= |A_i| - t_i \end{aligned}

In total we remove Xi+N(vti)+1|X_i| + |\mathcal{N}(v_{t_i})| + 1 vertices from AiA_i in every round. Putting everything together:

Ai+1Ai(Xi+N(vti)+1)Ai(Xi+degAi(vti))Ai(ti+β(Aiti))AiβAi=Ai(1β)\begin{aligned} |A_{i+1}| &\leq |A_i| - (|X_i| + |\mathcal{N}(v_{t_i})| + 1) \\ & \leq |A_i| - (|X_i| + \deg_{A'_i}(v_{t_i})) \\ &\leq |A_i| - (t_i + \beta (|A_i| - t_i) ) \\ &\leq |A_i| - \beta|A_i| = |A_i| (1 - \beta) \end{aligned}

where we used that β1\beta \leq 1 for the last inequality

We find that the set of available vertices AA shrinks at least by a factor of (1β)(1 - \beta) in every iteration. Together with the fact that the initial set AA is V(G)V(G) we obtain a contradiction to the initial condition (1) on the number of vertices in GG:

A(1β)qNeβqNR(5)\tag{5} |A| \leq (1 - \beta)^q N \leq e^{-\beta q} N \leq R

Here we used the well-known inequality (1+x)ex(1 + x) \leq e^x. After qq iterations, the initial set of available vertices has necessarily shrunk to a set of at most RR vertices.

Final bound

Let us now finally give the bound on the number of independent sets of size exactly q+kq + k. The bound (3) follows from the observation, that there are at most (Nq)\binom{N}{q} different ways to choose SS and therefore the first qq vertices of an independent set, and at most (Rk)\binom{R}{k} different ways to choose the kk remaining vertices from AA, which has size at most RR.

Another useful, but less sharp bounds, can be obtained from one of the various inequalities on the binomial coefficient:

I(G,q+k)Nqq!(Rk)(6)\tag{6} |\mathcal{I}(G, q + k)| \leq \frac{N^q}{q!}\binom{R}{k}

Wikipediahas an extensive collection of such bounds.

Overview of notation

  • Vertex set V(G)V(G)
  • Edge count eG(X)e_G(X): Number of edges in GG on vertex set XX
  • Neighborhood N(v)\mathcal{N}(v): set of vertices adjacent to vv
  • Induced subgraph G[A]G[A]: Obtained from GG by keeping all vertices in AA and their edges among them
  • Independence number α(G)\alpha(G): Size of largest independent set in GG
  • Independent sets I(G)\mathcal{I}(G): Collection of all independent sets in GG
  • Independent sets I(G,m)\mathcal{I}(G, m): Collection of all independent sets in GG of size exactly mm

Further reading

Some ressources for further details, including applications to various combinatorial problems and extensions of the container method to hypergraphs, are given below:


References

  1. https://arxiv.org/pdf/1412.0940.pdf↩︎

  2. https://doi.org/10.1016/0012-365X(82)90204-7↩︎

\ No newline at end of file +">skip to main content

Kleitman-Winston Algorithm

Graph containers & bounds on the number of independent sets in a locally dense graph.

Overview

We will show that for a locally dense graph we can give a strong upper bound on the number of independent sets of a certain size. This specific method for graphs is an instance of the so-called container method, that allows to give bounds on structures appearing in larger objects with specific local properties. More specifically as applied to graph theory, this turns out to be quite helpful in proving lower bounds in Ramsey theory.

The proof presented here follows the one presented in the survey paper by Samotij [1] using methods originally presented in the paper by Winston and Kleitman [2]. Some elementary knowledge of graph theory is helpful, such as the notion of independent sets and induced subgraphs, but I try to be as explicit and clear as possible. I will try to stick to common graph theoretical notation, but for the sake of both readability and completeness an overview of notation is given at the end of the post.

Basic bounds

Let’s start with some basic bounds on the number of independent sets I(G)|\mathcal{I}(G)| in a graph GG. Recall that an independent set is a set of vertices in which no two are connected by an edge. If α(G)\alpha(G) refers to the independence number, ie. the size of the largest independent set in GG, we can certainly say that

2α(G)I(G)2^{\alpha(G)} \leq |\mathcal{I}(G)|

because every subset of the largest independent set is itself an independent set (recall that 2N2^{|N|} is the number of different subsets that can be formed from a set NN).

Similarly, we can give an upper bound of

I(G)k=0α(G)(V(G)k)|\mathcal{I}(G)| \leq \sum_{k=0}^{\alpha(G)} \binom{|V(G)|}{k}

as every independent set is a subset of size at most α(G)\alpha(G) over the vertices of GG.

Theorem Statement

We will now bound the number of independent sets of a certain size in a locally dense graph by showing that every independent set is part of a small container. These containers are constructed with the Kleitman-Winston algorithm. By counting these countainers, we can estimate the number of independent sets. The tightness property of the containers then allows us to give useful bounds on the number of independent sets.

Let us now turn to the actual theorem. For N,R,qNN, R, q \in \mathbb{N} and βR\beta \in \mathbb{R} with β[0,1]\beta \in [0, 1], let GG be a graph on NN vertices satisfying:

NReβq(1)\tag{1} N \leq R e^{\beta q}

In addition, we also require that G must be a β\beta-locally dense graph. That is, for every vertex subset AV(G)A \subseteq V(G) of size at least RR we have the following lower bound on the number of edges in the induced subgraph G[A]G[A]:

eG(A)β(A2)(2)\tag{2} e_G(A) \geq \beta \binom{|A|}{2}

Note that this corresponds to the situation where the subgraph spanned by AA over GG contains at least a β\beta-fraction of the edges of the corresponding complete graph over AA, or in other words, that the average degree of AA is at least β(A1)\beta (|A| - 1).

Theorem

Given such a β\beta-locally dense graph GG satisfying (1) and (2), we can construct up to (Nq)\binom{N}{q} small containers C1,,CiC_1, \dots, C_i for 1i(Nq)1 \leq i \leq \binom{N}{q} of size at most R+qR + q. Every independent set of size exactly q+kq + k for kqk \leq q belongs to a container CiC_i.

For the number of independent sets in GG of size exactly q+kq + k we obtain:

I(G,q+k)(Nq)(Rk)(3)\tag{3} |\mathcal{I}(G, q + k)| \leq \binom{N}{q} \binom{R}{k}

Algorithm

Before describing the algorithm, let us fix a few technicalities. We need the notion of max-degree ordering to ensure high-degree vertices are quickly removed from the graph and the container quickly shrinks. For a vertex set AV(G)A \subseteq V(G), the max-degree ordering (v1,,vA)(v_1, \dots, v_{|A|}) is defined by the degree of vertices over the induced subgraph G[A]G[A] in descending order, where potential ties are broken by a fixed but arbitrary total order over V(G)V(G). In this case v1v_1 has the highest degree, etc.

The Kleitman-Winston algorithm works by iteratively removing high-degree vertices as outlined above:

Kleitman-Winston algorithm
  • Input: Independent set II(G)I \in \mathcal{I}(G), integer qIq \leq |I|
  • Output: selected vertices SS, available vertices AA
  • Procedure:
    1. Set available vertices A=V(G)A = V(G), selected vertices S=S = \varnothing
    2. Iterate for i=1,,qi=1, \dots, q:
      • Let A=(v1,,vA)A = (v_1, \dots, v_{|A|}) be ordered by max-degree
      • Let tit_i be the first index in the ordering of AA such that vtiIv_{t_i} \in I
        (i.e. first remaining vertex of II by max-degree ordering in induced subgraph G[A]G[A]).
      • Move vtiv_{t_i} from AA to SS
      • Remove higher-degree vertices Xi=(v1,,vti1)X_i = (v_1, \dots, v_{t_i - 1}) from AA:
        A=AXiA = A \setminus X_i
      • Remove vtiv_{t_i} and its neighborhood NA(vti)\mathcal{N}_A(v_{t_i}) from AA:
        A=A({vti}NA(vti))A = A \setminus (\{ v_{t_i} \} \cup \mathcal{N}_A(v_{t_i}))
    3. Output SS and AA

The container of II is given by C:=SAC := S \cup A. Notice that the tightness of the container is apparent in that fact that SICS \subseteq I \subseteq C.

Proof

The algorithm maintains a few invariants, that help prove correctness: A|A| decreases monotonically as we remove vertices in every iteration, while S|S| increases monotonically. Also notice that the previous observation SI(SA)S \subseteq I \subseteq (S \cup A) holds at every iteration of the algorithm.

It is clear that the algorithm always succeeds in constructing the set of selected vertices SS from qIq \leq |I| vertices of II. This is because the algorithm always selects the next highest degree vertex viv_i of II occuring in the subgraph G[A]G[A] at every step, i.e. no vertex viIv_i \in I is ever removed from AA and not added to SS as a discarded higher-degree vertex. In addition, the vertices of II form an independent set by assumption, and as such a vertex viv_i is never removed as part of the neighborhood of another selected vertex.

Size of A

To conclude tightness of the containers, we must show that the final AA returned from the algorithm is sufficiently small. In fact, we will show that AR|A| \leq R. In the following, we will denote by AiA_i the set of available vertices at the beginning of the i-th iteration of the algortithm, and by Ai=AiXiA'_i = A_i \setminus X_i the set of available vertices after removing higher-degree vertices but before remoing vtiIv_{t_i} \in I.

First, note that by the Handshaking lemmawe obtain an expression for the average degree of vertices:

1VvVdeg(v)=2EV(4)\tag{4} \frac{1}{|V|} \sum_{v \in V} deg(v) = \frac{2|E|}{|V|}

Suppose for sake of contradiction A>R|A| > R for the final set of available vertices. Then it must be that the vtiSv_{t_i} \in S selected in every iteration must have been selected from a set of size at least RR, even after removal of other higher-degree vertices (recall that A|A| decreases monotonically throughtout the algorithm). Or, in other words, at the start of the i-th iteration with currently available vertices AiA_i and higher-degree vertices XiX_i scheduled for removal, Ai:=AiXi>R|A'_i| := |A_i \setminus X_i| > R.

Using the bound (2) on the edge-count:

eG(Ai)β(Ai2)=βAi(Ai1)2e_G(A'_i) \geq \beta \binom{|A'_i|}{2} = \beta \frac{|A'_i|(|A'_i|-1)}{2}

As we choose vtiv_{t_i} with maximum degree from AiA'_i, we know vtiv_{t_i} must at least have the average degree (4) of AiA'_i:

degAi(vti)2eG(Ai)Aiβ(Ai1)\deg_{A'_i}(v_{t_i}) \geq \frac{2e_G(A'_i)}{|A'_i|} \geq \beta (|A'_i| - 1)

Recalling the definition of Ai|A'_i|:

Ai1=AiXi1=AiXi1Ai(ti1)1=Aiti\begin{aligned} |A'_i| - 1 = |A_i \setminus X_i| - 1 &= |A_i| - |X_i| - 1 \\ |A_i| - (t_i - 1) - 1 &= |A_i| - t_i \end{aligned}

In total we remove Xi+N(vti)+1|X_i| + |\mathcal{N}(v_{t_i})| + 1 vertices from AiA_i in every round. Putting everything together:

Ai+1Ai(Xi+N(vti)+1)Ai(Xi+degAi(vti))Ai(ti+β(Aiti))AiβAi=Ai(1β)\begin{aligned} |A_{i+1}| &\leq |A_i| - (|X_i| + |\mathcal{N}(v_{t_i})| + 1) \\ & \leq |A_i| - (|X_i| + \deg_{A'_i}(v_{t_i})) \\ &\leq |A_i| - (t_i + \beta (|A_i| - t_i) ) \\ &\leq |A_i| - \beta|A_i| = |A_i| (1 - \beta) \end{aligned}

where we used that β1\beta \leq 1 for the last inequality

We find that the set of available vertices AA shrinks at least by a factor of (1β)(1 - \beta) in every iteration. Together with the fact that the initial set AA is V(G)V(G) we obtain a contradiction to the initial condition (1) on the number of vertices in GG:

A(1β)qNeβqNR(5)\tag{5} |A| \leq (1 - \beta)^q N \leq e^{-\beta q} N \leq R

Here we used the well-known inequality (1+x)ex(1 + x) \leq e^x. After qq iterations, the initial set of available vertices has necessarily shrunk to a set of at most RR vertices.

Final bound

Let us now finally give the bound on the number of independent sets of size exactly q+kq + k. The bound (3) follows from the observation, that there are at most (Nq)\binom{N}{q} different ways to choose SS and therefore the first qq vertices of an independent set, and at most (Rk)\binom{R}{k} different ways to choose the kk remaining vertices from AA, which has size at most RR.

Another useful, but less sharp bounds, can be obtained from one of the various inequalities on the binomial coefficient:

I(G,q+k)Nqq!(Rk)(6)\tag{6} |\mathcal{I}(G, q + k)| \leq \frac{N^q}{q!}\binom{R}{k}

Wikipediahas an extensive collection of such bounds.

Overview of notation

  • Vertex set V(G)V(G)
  • Edge count eG(X)e_G(X): Number of edges in GG on vertex set XX
  • Neighborhood N(v)\mathcal{N}(v): set of vertices adjacent to vv
  • Induced subgraph G[A]G[A]: Obtained from GG by keeping all vertices in AA and their edges among them
  • Independence number α(G)\alpha(G): Size of largest independent set in GG
  • Independent sets I(G)\mathcal{I}(G): Collection of all independent sets in GG
  • Independent sets I(G,m)\mathcal{I}(G, m): Collection of all independent sets in GG of size exactly mm

Further reading

Some ressources for further details, including applications to various combinatorial problems and extensions of the container method to hypergraphs, are given below:


References

  1. https://arxiv.org/pdf/1412.0940.pdf↩︎

  2. https://doi.org/10.1016/0012-365X(82)90204-7↩︎

\ No newline at end of file diff --git a/posts/index.html b/posts/index.html index 6b310984..165cd3b9 100644 --- a/posts/index.html +++ b/posts/index.html @@ -1 +1 @@ -umcconnellskip to main content

Archive

  1. Kleitman-Winston Algorithm

    Graph containers & bounds on the number of independent sets in a locally dense graph.

  2. Meta Blog: Advanced

    A blog post on how to create your own blog (posts) with 11ty. Part II: Advanced technical details.

  3. Meta Blog: Basics

    A blog post on how to create your own blog (posts) with 11ty. Part I: The basics.

  4. Fibonacci in Rust

    This post goes through different approaches to generating the Fibonacci sequence in Rust. It compares the speed of these approaches using the benchmarking crate criterion.

  5. Hello Internet

    Kicking off my blog with the mandatory "Hello World" introductory post... More posts about software, technology and science to come!

\ No newline at end of file +umcconnellskip to main content

Archive

  1. Kleitman-Winston Algorithm

    Graph containers & bounds on the number of independent sets in a locally dense graph.

  2. Meta Blog: Advanced

    A blog post on how to create your own blog (posts) with 11ty. Part II: Advanced technical details.

  3. Meta Blog: Basics

    A blog post on how to create your own blog (posts) with 11ty. Part I: The basics.

  4. Fibonacci in Rust

    This post goes through different approaches to generating the Fibonacci sequence in Rust. It compares the speed of these approaches using the benchmarking crate criterion.

  5. Hello Internet

    Kicking off my blog with the mandatory "Hello World" introductory post... More posts about software, technology and science to come!

\ No newline at end of file diff --git a/posts/tags/beginner/index.html b/posts/tags/beginner/index.html index ca188311..a067b049 100644 --- a/posts/tags/beginner/index.html +++ b/posts/tags/beginner/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "beginner"

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "beginner"

\ No newline at end of file diff --git a/posts/tags/blog/index.html b/posts/tags/blog/index.html index ef88fe7d..9ab8e1e2 100644 --- a/posts/tags/blog/index.html +++ b/posts/tags/blog/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "blog"

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "blog"

\ No newline at end of file diff --git a/posts/tags/combinatorics/index.html b/posts/tags/combinatorics/index.html index 01f78dd2..b5da6341 100644 --- a/posts/tags/combinatorics/index.html +++ b/posts/tags/combinatorics/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "combinatorics"

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "combinatorics"

\ No newline at end of file diff --git a/posts/tags/fibonacci/index.html b/posts/tags/fibonacci/index.html index 1de3cf8b..18079a19 100644 --- a/posts/tags/fibonacci/index.html +++ b/posts/tags/fibonacci/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "fibonacci"

  • Fibonacci in Rust

    This post goes through different approaches to generating the Fibonacci sequence in Rust. It compares the speed of these approaches using the benchmarking crate criterion.

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "fibonacci"

  • Fibonacci in Rust

    This post goes through different approaches to generating the Fibonacci sequence in Rust. It compares the speed of these approaches using the benchmarking crate criterion.

\ No newline at end of file diff --git a/posts/tags/graph theory/index.html b/posts/tags/graph theory/index.html index 72f3ab1c..259709ca 100644 --- a/posts/tags/graph theory/index.html +++ b/posts/tags/graph theory/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "graph theory"

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "graph theory"

\ No newline at end of file diff --git a/posts/tags/math/index.html b/posts/tags/math/index.html index 54578923..33051c5b 100644 --- a/posts/tags/math/index.html +++ b/posts/tags/math/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "math"

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "math"

\ No newline at end of file diff --git a/posts/tags/posts/index.html b/posts/tags/posts/index.html index dc55b2b6..4bc350ac 100644 --- a/posts/tags/posts/index.html +++ b/posts/tags/posts/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "posts"

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "posts"

\ No newline at end of file diff --git a/posts/tags/programming/index.html b/posts/tags/programming/index.html index c94e8d1a..dfebdc08 100644 --- a/posts/tags/programming/index.html +++ b/posts/tags/programming/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "programming"

  • Fibonacci in Rust

    This post goes through different approaches to generating the Fibonacci sequence in Rust. It compares the speed of these approaches using the benchmarking crate criterion.

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "programming"

  • Fibonacci in Rust

    This post goes through different approaches to generating the Fibonacci sequence in Rust. It compares the speed of these approaches using the benchmarking crate criterion.

\ No newline at end of file diff --git a/posts/tags/rust/index.html b/posts/tags/rust/index.html index 32cd5a56..524d8def 100644 --- a/posts/tags/rust/index.html +++ b/posts/tags/rust/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "rust"

  • Fibonacci in Rust

    This post goes through different approaches to generating the Fibonacci sequence in Rust. It compares the speed of these approaches using the benchmarking crate criterion.

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "rust"

  • Fibonacci in Rust

    This post goes through different approaches to generating the Fibonacci sequence in Rust. It compares the speed of these approaches using the benchmarking crate criterion.

\ No newline at end of file diff --git a/posts/tags/webdev/index.html b/posts/tags/webdev/index.html index 7a5d4fd7..7432f73b 100644 --- a/posts/tags/webdev/index.html +++ b/posts/tags/webdev/index.html @@ -1 +1 @@ -umcconnellskip to main content

Posts Tagged "webdev"

\ No newline at end of file +umcconnellskip to main content

Posts Tagged "webdev"

\ No newline at end of file diff --git a/projects/index.html b/projects/index.html index 5fd978e6..1619a92e 100644 --- a/projects/index.html +++ b/projects/index.html @@ -1 +1 @@ -umcconnellskip to main content

Projects

Here's a selection of some of my software side projects. This is mostly a curated compilation of my Github repos.

servum

A simple, fast, static server written in Rust. No dependencies. HTTP only.

destroyer2

Online multiplayer battleship game. Uses node and redis.
Play here: https://destroyer2.herokuapp.com/

aquila

AI to assess building damage from satellite imagery after natural catastrophes.
Written using Python and Pytorch.

lc4

JavaScript encryption-decryption library for the lc4 cipher.
Additional UI: https://lc4-encryptor.glitch.me

tic-tac-toe

Unbeatable Python tic-tac-toe game with minimax. UI using Qt.

\ No newline at end of file +umcconnellskip to main content

Projects

Here's a selection of some of my software side projects. This is mostly a curated compilation of my Github repos.

servum

A simple, fast, static server written in Rust. No dependencies. HTTP only.

destroyer2

Online multiplayer battleship game. Uses node and redis.
Play here: https://destroyer2.herokuapp.com/

aquila

AI to assess building damage from satellite imagery after natural catastrophes.
Written using Python and Pytorch.

lc4

JavaScript encryption-decryption library for the lc4 cipher.
Additional UI: https://lc4-encryptor.glitch.me

tic-tac-toe

Unbeatable Python tic-tac-toe game with minimax. UI using Qt.

\ No newline at end of file