To save content items to your account,
please confirm that you agree to abide by our usage policies.
If this is the first time you use this feature, you will be asked to authorise Cambridge Core to connect with your account.
Find out more about saving content to .
To save content items to your Kindle, first ensure no-reply@cambridge.org
is added to your Approved Personal Document E-mail List under your Personal Document Settings
on the Manage Your Content and Devices page of your Amazon account. Then enter the ‘name’ part
of your Kindle email address below.
Find out more about saving to your Kindle.
Note you can select to save to either the @free.kindle.com or @kindle.com variations.
‘@free.kindle.com’ emails are free but can only be saved to your device when it is connected to wi-fi.
‘@kindle.com’ emails can be delivered even when you are not connected to wi-fi, but note that service fees apply.
Logic Theorist was the first artificially intelligent program, created in 1955 by Allen Newell and Herbert Simon, and actually predating the term “artificial intelligence,” which was introduced the next year. Logic Theorist could apply the rules of symbolic logic to prove mathematical theorems – the first time a computer accomplished a task considered solely within the domain of human intelligence. Given a starting statement, it applied logical laws to generate a set of new statements, then recursively continued the process. Eventually, this procedure would discover a chain of logical transformations that connected the starting statement to the desired final statement. Applied naively, this process would generate an intractable number of possible paths, but Logic Theorist had the ability to detect and discard infeasible paths that couldn’t lead to a solution.
Very often, software developers need to evaluate the trade-offs between different approaches to solving a problem. Do you want the fastest solution, even if it’s difficult to implement and maintain? Will your code still be useful if you have to process 100 times as much data? What if an algorithm is fast for some inputs but terrible for others? Algorithm analysis is the framework that computer scientists use to understand the trade-offs between algorithms. Algorithm analysis is primarily theoretical: It focuses on the fundamental properties of algorithms, and not on systems, languages, or any particular details of their implementations.
This chapter introduces the key concepts of algorithm analysis, starting from the practical example of searching an array for a value of interest. We’ll start by making experimental comparisons between two searching methods: a simple linear search and the more complex binary search. The second part of the chapter introduces one of the most important mathematical tools in computer science, Big-O notation, the primary tool for algorithm analysis.
No other computational problem has been studied in more depth, or yielded a greater number of useful solutions, than sorting. Historically, business computers spent 25% of their time doing nothing but sorting data (Knuth, 2014c), and many advanced algorithms start by sorting their inputs. Dozens of algorithms have been proposed over the last 80-odd years, but there is no “best” solution to the sorting problem. Although many popular sorting algorithms were known as early as the 1940s, researchers are still designing improved versions – Python’s default algorithm was only implemented in the early 2000s and Java’s current version in the 2010s.
Computer animators have always sought to push boundaries and create impressive, realistic visual effects, but some processes are too demanding to model exactly. Effects like fire, smoke, and water have complex fluid dynamics and amorphous boundaries that are hard to recreate with standard physical calculations. Instead, animators might turn to another approach to create these effects: particle systems. Bill Reeves, a graphics researcher and animator, began experimenting with particle-based effects in the early 1980s while making movies at Lucasfilm. For a scene in Star Trek II: The Wrath of Khan (1982), he needed to create an image of explosive fire spreading across the entire surface of a planet. Reeves used thousands of independent particles, each one representing a tiny piece of fire (Reeves, 1983). The fire particles were created semi-randomly, with attributes for their 3D positions, velocities, and colors. Reeves’ model governed how particles appeared, moved, and interacted to create a realistic effect that could be rendered on an early 1980s computer. Reeves would go on to work on other Lucasfilm productions, including Return of the Jedi (1983), before joining Pixar, where his credits include Toy Story (1995) and Finding Nemo (2003).
Java is an object-oriented programming language. Java programs are implemented as collections of classes and objects that interact with each other to deliver the functionality that the programmer wants. So far, we’ve used “class” as being roughly synonymous with “program,” and all of our programs have consisted of one public class with a main method that may call additional methods. We’ve also talked about how to use the new keyword to initialize objects like Scanner that can perform useful work. It’s now time to talk about the concepts of objects and classes in more depth and then learn how to write customized classes.
The previous two chapters showed how the concept of last-in-first-out data processing is surprisingly powerful. We’ll now consider the stack’s counterpart, the queue. Like a waiting line, a queue stores a set of items and returns them in first-in-first-out (FIFO) order. Pushing to the queue adds a new item to the back of the line and pulling retrieves the oldest item from the front. Queues have a lower profile than stacks, and are rarely the centerpiece of an algorithm. Instead, queues tend to serve as utility data structures in a larger system.
A hash, in culinary terms, is a dish made of mixed foods – often including corned beef and onions – chopped into tiny pieces. In the early twentieth century, it became a shorthand for something of dubious origin, probably unwise to consume. In computer science, a hash function is an operation that rearranges, mixes, and combines data to produce a single fixed-size output. Unlike their culinary namesake, hash functions are wonderfully useful. A hash value is like a “fingerprint” of the input used to calculate it. Hash functions have applications to security, distributed systems, and – as we’ll explore – data structures.
There’s a perception that computer science is constantly changing, and in some respects that’s true: There are always new languages, frameworks, and application domains rising up and old ones sinking down. All of this change that we see around us, though, is like the top part of an iceberg. The most visible elements of our field are built upon and supported by a deeper layer of knowledge that’s mostly invisible to the casual observer. This book is about what’s under the water, the fundamental things that make programming possible, even if we don’t see them right away.
Computers have always mixed with art and music. Even in the earliest days of computing, when machines were the size of entire rooms, artists and composers began to harness them to create original works that could only exist in the digital realm. “Generative art” or “algorithmic art” is a term for works created according to a process that evolves with no or limited guidance from a human creator. Rather than directly making choices, the artist instead focuses on the design and initialization of a system that produces the final work. The appeal of algorithmic art lies in its combination of detail, technical complexity, and variation. Generative art frequently incorporates ideas from biology, physics, and mathematics.
Minecraft is the most popular video game in history. Created by Markus “Notch” Persson using Java, it has sold more than 250 million copies since its first release in 2011. Minecraft is a sandbox-style game with no plot or required goals: Players explore an open three-dimensional world made of cubic blocks, and can mine for resources, craft items, and build. Every Minecraft world is effectively infinite and procedurally generated. Rather than having a fixed map, the game automatically generates new terrain as the player explores the world. The idea of procedurally generated game worlds goes back to some of the earliest computer games, including the highly influential Rogue (1980), which sent the player on a crawl through a brutally difficult random dungeon and inspired an entire genre of successors.
The walk matrix associated to an $n\times n$ integer matrix $\mathbf{X}$ and an integer vector $b$ is defined by ${\mathbf{W}} \,:\!=\, (b,{\mathbf{X}} b,\ldots, {\mathbf{X}}^{n-1}b)$. We study limiting laws for the cokernel of $\mathbf{W}$ in the scenario where $\mathbf{X}$ is a random matrix with independent entries and $b$ is deterministic. Our first main result provides a formula for the distribution of the $p^m$-torsion part of the cokernel, as a group, when $\mathbf{X}$ has independent entries from a specific distribution. The second main result relaxes the distributional assumption and concerns the ${\mathbb{Z}}[x]$-module structure.
The motivation for this work arises from an open problem in spectral graph theory, which asks to show that random graphs are often determined up to isomorphism by their (generalised) spectrum. Sufficient conditions for generalised spectral determinacy can, namely, be stated in terms of the cokernel of a walk matrix. Extensions of our results could potentially be used to determine how often those conditions are satisfied. Some remaining challenges for such extensions are outlined in the paper.
Given an $n\times n$ symmetric matrix $W\in [0,1]^{[n]\times [n]}$, let ${\mathcal G}(n,W)$ be the random graph obtained by independently including each edge $jk\in \binom{[n]}{2}$ with probability $W_{jk}=W_{kj}$. Given a degree sequence $\textbf{d}=(d_1,\ldots, d_n)$, let ${\mathcal G}(n,\textbf{d})$ denote a uniformly random graph with degree sequence $\textbf{d}$. We couple ${\mathcal G}(n,W)$ and ${\mathcal G}(n,\textbf{d})$ together so that asymptotically almost surely ${\mathcal G}(n,W)$ is a subgraph of ${\mathcal G}(n,\textbf{d})$, where $W$ is some function of $\textbf{d}$. Let $\Delta (\textbf{d})$ denote the maximum degree in $\textbf{d}$. Our coupling result is optimal when $\Delta (\textbf{d})^2\ll \|\textbf{d}\|_1$, that is, $W_{ij}$ is asymptotic to ${\mathbb P}(ij\in{\mathcal G}(n,\textbf{d}))$ for every $i,j\in [n]$. We also have coupling results for $\textbf{d}$ that are not constrained by the condition $\Delta (\textbf{d})^2\ll \|\textbf{d}\|_1$. For such $\textbf{d}$ our coupling result is still close to optimal, in the sense that $W_{ij}$ is asymptotic to ${\mathbb P}(ij\in{\mathcal G}(n,\textbf{d}))$ for most pairs $ij\in \binom{[n]}{2}$.
We study computational aspects of repulsive Gibbs point processes, which are probabilistic models of interacting particles in a finite-volume region of space. We introduce an approach for reducing a Gibbs point process to the hard-core model, a well-studied discrete spin system. Given an instance of such a point process, our reduction generates a random graph drawn from a natural geometric model. We show that the partition function of a hard-core model on graphs generated by the geometric model concentrates around the partition function of the Gibbs point process. Our reduction allows us to use a broad range of algorithms developed for the hard-core model to sample from the Gibbs point process and approximate its partition function. This is, to the extent of our knowledge, the first approach that deals with pair potentials of unbounded range.
Let $r$ be any positive integer. We prove that for every sufficiently large $k$ there exists a $k$-chromatic vertex-critical graph $G$ such that $\chi (G-R)=k$ for every set $R \subseteq E(G)$ with $|R|\le r$. This partially solves a problem posed by Erdős in 1985, who asked whether the above statement holds for $k \ge 4$.
Understand algorithms and their design with this revised student-friendly textbook. Unlike other algorithms books, this one is approachable, the methods it explains are straightforward, and the insights it provides are numerous and valuable. Without grinding through lots of formal proof, students will benefit from step-by-step methods for developing algorithms, expert guidance on common pitfalls, and an appreciation of the bigger picture. Revised and updated, this second edition includes a new chapter on machine learning algorithms, and concise key concept summaries at the end of each part for quick reference. Also new to this edition are more than 150 new exercises: selected solutions are included to let students check their progress, while a full solutions manual is available online for instructors. No other text explains complex topics such as loop invariants as clearly, helping students to think abstractly and preparing them for creating their own innovative ways to solve problems.
We use Stein’s method to obtain distributional approximations of subgraph counts in the uniform attachment model or random directed acyclic graph; we provide also estimates of rates of convergence. In particular, we give uni- and multi-variate Poisson approximations to the counts of cycles and normal approximations to the counts of unicyclic subgraphs; we also give a partial result for the counts of trees. We further find a class of multicyclic graphs whose subgraph counts are a.s. bounded as $n\to \infty$.
For given positive integers $r\ge 3$, $n$ and $e\le \binom{n}{2}$, the famous Erdős–Rademacher problem asks for the minimum number of $r$-cliques in a graph with $n$ vertices and $e$ edges. A conjecture of Lovász and Simonovits from the 1970s states that, for every $r\ge 3$, if $n$ is sufficiently large then, for every $e\le \binom{n}{2}$, at least one extremal graph can be obtained from a complete partite graph by adding a triangle-free graph into one part.
In this note, we explicitly write the minimum number of $r$-cliques predicted by the above conjecture. Also, we describe what we believe to be the set of extremal graphs for any $r\ge 4$ and all large $n$, amending the previous conjecture of Pikhurko and Razborov.