PRODUCT

Design

Content

Publish

RESOURCES

Blog

Careers

Docs

About

Writings

Dynamic Programming

Dynamic Programming

动态规划

Preface: In 1950, the core equation of modern AI was smuggled past the Pentagon under a fake name.
Following the previous #AI series and #MarvinMinksy series. This post is co-written with Claude.


Reinforcement learning is usually told as a story about imitating the brain: cats, pigeons, neurons, synapses, a machine that wants to learn the way an animal does. But the other half of its foundation has nothing to do with the brain. That half comes from Cold War military logistics: how to allocate missiles, how to schedule aircraft, when to restock a warehouse. The man who came up with it never studied animals and never built a machine that could learn. He was a mathematician who only wrote equations, and to protect his research funding, he even had to pretend that what he was doing wasn't mathematics.


1920: The Grocer's Son

Richard Bellman was born in New York in 1920. His parents, descended from Russian and Polish Jewish immigrants, ran a small grocery store on Bergen Street, near Prospect Park in Brooklyn. When he was nine, the Great Depression hit. It ruined his father's business, but even in those hard years, the family managed to keep him in school.



He first encountered algebra at eleven and was hooked on mathematics from then on. In high school he competed for his school's math team, and in his final year he earned the top ranking among all the high school students in New York. He graduated from Brooklyn College in 1941, then went on to the University of Wisconsin for a master's in mathematics.

The war upended everything. At the end of 1944, Bellman was drafted and assigned to Los Alamos, New Mexico, where he spent two years in the theoretical physics division of the Manhattan Project. After his discharge in 1946, he returned to Princeton and finished his PhD in just three months. He then went to Stanford as an associate professor, working in his favorite branch of pure mathematics: analytic number theory.

Number theory is the mathematics of whole numbers, especially primes, the numbers divisible only by 1 and themselves, like 2, 3, 5, 7, and 11. It asks questions that sound simple but are extraordinarily hard to answer: Are there infinitely many primes? How are they distributed among the whole numbers? Can every even number greater than 2 be written as the sum of two primes? Analytic number theory is the branch that uses tools built for studying continuous change, like calculus, to answer questions about whole numbers.

That sounds backwards. Whole numbers come in separate, discrete steps, so why use methods designed for smooth curves and continuous change? Yet it turns out to work remarkably well.

Looked at one by one, the primes follow no pattern. After 7 comes a gap of four to 11, then a gap of two to 13, then four again to 17. Sometimes two primes sit right next to each other, like 101 and 103; sometimes there's a long empty stretch between them. No one can predict where the next prime will appear.

But change the question. Instead of asking where the next prime is, ask how many primes there are up to a given number, and draw the answer as a line, with the size of the number along the bottom and the count of primes up the side. You get a staircase that steps up by one every time it hits a prime. Up close, the steps are uneven, some tall, some wide. But step back and look across thousands or tens of thousands, and the staircase blurs into a remarkably smooth curve.

It's the same principle as population statistics. No one can predict the day any one person will die, but an insurance company can calculate quite accurately how many out of a million sixty-year-olds will die next year. Individuals are random; the whole has a pattern. And once the distribution of primes becomes a smooth curve, the tool built for smooth curves, calculus, suddenly has something to work on.



The story goes that Gauss noticed this curve when he was fifteen. He counted thousands of primes by hand and saw that the larger the numbers got, the sparser the primes became, and that how sparse they got was related to something called the logarithm. For example, 10 × 10 = 100 uses two tens, so the base-10 logarithm of 100 is 2. Six tens multiplied together make a million, so the base-10 logarithm of a million is 6. The fixed number being multiplied is called the base. The most important thing about logarithms is how slowly they grow. Going from 1,000 to a million, the number gets a thousand times bigger, but the logarithm only goes from 3 to 6. Every time a number gets ten times larger, its logarithm goes up by just one.

Logarithms don't have to be whole numbers. Fifty falls between 10 and 100, so its base-10 logarithm falls between 1 and 2, at about 1.7. "Multiplying 1.7 times" sounds like nonsense, but think of it as growth: if a sum of money grows smoothly to ten times its size every year, after one year it's 10 times bigger, after two years 100 times bigger, and after 1.7 years it's exactly 50 times bigger. Once you allow a single "time" to be cut into smaller pieces, the count can be a fraction. Every number greater than zero has a logarithm.

Change the base, and the logarithm changes too. The same number 50 has a base-10 logarithm of 1.7, but a base-7 logarithm of about 2, since 7 × 7 = 49. The smaller the base, the more times you have to multiply, and the larger the logarithm. Gauss used a special base, about 2.718, which mathematicians call e. Logarithms with base e are called natural logarithms, because they're the most natural way to describe smooth, continuous growth, like compound interest or reproduction.

The rule Gauss guessed was this: the number of primes up to a given number is roughly that number divided by its natural logarithm. Let's plug in some numbers. The natural log of 100 is about 4.6, and 100 ÷ 4.6 is about 22; there are actually 25 primes. The natural log of 1,000 is about 6.9, which gives an estimate of about 145; the real count is 168. Up to 10,000, the estimate is about 1,086, against an actual 1,229. The natural log of a million is about 13.8, giving an estimate of about 72,382; the real number is 78,498. The estimate always runs a little low, but the bigger the number, the smaller the error in proportion: 12% off up to 100, only 8% off up to a million.

There's an even more intuitive way to read this rule: near any given number, a prime turns up on average once every "natural log of that number" numbers. Near 100, the natural log is 4.6, so roughly one number in every four or five is prime. Count the numbers from 90 to 110: 97, 101, 103, 107, 109, five primes in twenty numbers, exactly one in four. Near a million, the natural log is 13.8, so only about one number in fourteen is prime. The numbers have grown ten thousand times larger, but the average gap between primes has only tripled. The primes thin out, but they thin out very, very slowly.

Gauss never proved his rule. What finally let calculus get a grip on the primes was a clever transformation. In 1737, the Swiss mathematician Leonhard Euler discovered an equation: if you add up a certain kind of reciprocal of every positive whole number, the result is exactly equal to a product made up only of primes. That equation tied "all whole numbers" and "all primes" together in a single expression. On one side was a continuous function, something you could differentiate, graph, and analyze with calculus. On the other side, hidden inside, were all the primes. Studying the function meant studying the primes indirectly.



Euler used this method to prove an astonishing result: if you add up the reciprocals of all the primes, 1/2 + 1/3 + 1/5 + 1/7 + 1/11 and so on, the total never settles on any number. It just keeps growing. Mathematicians call this “diverging.”

It grows extraordinarily slowly. Add up the reciprocals of the primes below 10 and you get about 1.18. Below 100, about 1.8. Below a million, about 2.9. Add every prime below a billion and the total is still only about 3.3; go all the way to a billion billion, 10 to the 18th power, and it barely reaches 4. It creeps so slowly you can hardly see it move, but it never stops. Name any number you like, 10 or 100, and if you keep adding, the total will eventually pass it.

Many infinite sums don’t behave this way. Take 1/2 + 1/4 + 1/8 + 1/16 and so on, where each term is half the one before. No matter how many terms you add, the total only gets closer and closer to 1 and never gets past it. This is called “converging”: infinitely many terms, but a finite total, because the terms shrink too quickly. Or take the reciprocals of the square numbers, 1/1 + 1/4 + 1/9 + 1/16 and so on. Added up forever, they settle at about 1.645, a problem Euler himself had cracked a few years earlier.

Whether an infinite sum stops depends on how fast its terms shrink. As the primes thin out, their reciprocals get smaller and smaller. If the primes thinned out quickly, their sum would stop the way 1/2 + 1/4 + 1/8 does. Euler proved that it doesn’t, and that tells us two things. First, there must be infinitely many primes, because a finite list of them would add up to a finite number. Second, the primes thin out very slowly, far more slowly than the square numbers do. If you only stared at the whole numbers one at a time, you would almost never discover this.

In 1859, the German mathematician Bernhard Riemann extended Euler's function into the complex numbers. It later became known as the Riemann zeta function. He found that there is always some error between the smooth curve of prime distribution and the actual staircase, and that this error is completely determined by the points where the function equals zero.

It's a bit like music. A chord sounds like a single blended sound, but it's really several notes of different frequencies layered on top of each other; if you know the frequencies, you can rebuild the sound exactly. What Riemann discovered was that the jagged staircase of the primes could also be broken down into a combination of "frequencies," and those frequencies are the zeros of the zeta function. Know the zeros, and you can reconstruct the distribution of the primes precisely.

The Riemann Hypothesis says that all of these zeros line up neatly along a single straight line. If it's true, the primes deviate from the smooth curve in the "quietest" possible way. It has never been proven, and it is one of the seven problems for which mathematicians have offered a million-dollar prize.

In 1896, two mathematicians, Jacques Hadamard and Charles de la Vallée Poussin, working independently along the path Riemann had laid out, finally proved the rule Gauss had guessed a century earlier. This is the Prime Number Theorem: the bigger the numbers, the closer the proportional error between the estimate and the actual count gets to zero.

The theorem means several things.

First, there is order hidden inside chaos. "Divisible only by 1 and itself" is a completely deterministic rule with nothing random about it, yet the primes it produces look like a handful of sand tossed at random. And the overall spread of that sand falls precisely along a smooth curve.

Second, it has a very practical use. Online banking, credit card payments, and the little padlock next to your browser's address bar often depend on enormous primes hundreds of digits long. Encryption systems need to find new large primes all the time, which requires that they not be too rare. The Prime Number Theorem guarantees exactly that. A 300-digit number has a natural logarithm of about 690, which means that among numbers that size, roughly one in every 690 is prime. Pick random 300-digit odd numbers and test them, and you'll hit a prime within a few hundred tries.

Third, it builds a bridge between two worlds. Whole numbers are discrete, but e comes from continuous growth. No one would have guessed in advance that asking which whole numbers are divisible only by themselves would produce an answer with 2.718 in it. The discrete and the continuous, two worlds of mathematics that seem to have nothing to do with each other, turn out to be connected at a very deep level.

Whole-number problems are hard because every number is an isolated point. You can't describe them with ideas like change, trend, or slope, and calculus is precisely the language of change and trend. The trick of analytic number theory is to find a bridge: by looking at the whole in aggregate, or by building a function, it translates a discrete problem into a continuous one, solves it with continuous tools, and then translates the answer back.


1949: A Summer at RAND

In the summer of 1949, Bellman went to the RAND Corporation in Santa Monica, California. RAND was a think tank spun off after the war from a U.S. Air Force research project, and it studied strategy and logistics for the Air Force. When he arrived, he asked a colleague, Ed Paxson, what RAND was interested in. Paxson suggested he work on "multistage decision processes." Bellman took the suggestion.



A multistage decision process is a chain of linked decisions, where each decision changes the situation facing the next one. A great many real problems work this way. How much ammunition you ship to the front today determines how much is left in stock tomorrow; what's left tomorrow determines how much you can ship the day after. Which route a plane flies today determines which airport it's sitting at tomorrow. You can't look at any decision in isolation, because each step sets up the next. For a while, Bellman wavered between Stanford and RAND: on one side, the number theory he loved; on the other, a brand-new problem that looked rough but full of possibility. In 1952 he left Stanford and became a research mathematician at RAND.


1950: A Name Not Even a Congressman Could Object To

In the fall of 1950, Bellman's first task at RAND was to come up with a name for his research.

He explained why in his 1984 autobiography. The 1950s, he said, were not good years for mathematical research. There was a Secretary of Defense in Washington, Charles Wilson, who had a pathological fear and hatred of the word "research." Hearing it would make his face flush red with rage. You can imagine how he felt about the word "mathematics." RAND worked for the Air Force, and the Air Force's boss was Wilson. Bellman felt he had to find a way to keep both the Air Force and Wilson from noticing that what he was really doing at RAND was mathematics.



First he chose "programming." At the time, this was a military term for drawing up a schedule for training or logistics, and it had nothing to do with what we now call programming. Then, to convey that the problem was multistage and changed over time, he added "dynamic." The word "dynamic," he said, has an interesting property: it's impossible to use it in a pejorative sense. It was a name not even a Congressman could object to. Dynamic programming is the method of taking a large problem made up of a chain of decisions, breaking it into smaller problems, and solving them by working backward from the last step.


Working Backward

Take a concrete example. Say you're driving from Oakland to Los Angeles, passing through a lot of towns along the way, and at every town there are several roads to choose from. You want to find the route with the shortest total distance.

The brute-force approach is to list every possible route, add up the length of each one, and pick the shortest. But once there are enough towns, the number of routes explodes. With three roads to choose from at each town, ten towns gives you three to the tenth power, or almost sixty thousand routes. Twenty towns gives you more than three billion.

Bellman's idea was this: don't calculate forward from the start. Calculate backward from the finish.

First, look at the towns that are just one step from Los Angeles. The shortest distance from each of them to LA is obvious at a glance, so write it down. Then step back one more stage, to the towns two steps away. From each of these, all you have to do is compare: the distance to the next town, plus that town's shortest distance to LA, which you've already worked out. Which combination is smallest? Write it down. Step back again and do the same thing, all the way back to Oakland.

This way, you never have to list every route. Each town only needs to be worked out once, and each time you only have to look at the few roads right in front of you.

Behind this method is a very simple idea, which Bellman called the principle of optimality. In terms of this example: if the shortest route from Oakland to Los Angeles passes through Fresno, then the stretch of that route from Fresno to LA must itself be the shortest route from Fresno to LA. Otherwise you could swap that stretch for a shorter one, and the whole route would get shorter too, which contradicts the claim that it was the shortest route in the first place.

The principle of optimality: the best plan has the property that, wherever you start and whatever your first move, the remaining decisions must also be the best ones for the position you're in after that first move. In other words, the best whole is made up of best parts. So you can start with the last stretch and piece the route together backward, one stretch at a time.


The Bellman Equation

Write this idea down as a formula, and you get what is today the most central equation in reinforcement learning.



First, a definition: the "value" of a situation. In the driving example, a town's value is how far you still have to go from there to Los Angeles. More generally, the value of a situation is the total reward you'll end up with if you start from there and make the best choice at every step afterward.

The Bellman equation: the value of a situation equals the reward you get at this step, plus the value of the situation you move into next. And the best choice is the one that makes those two together as large as possible.

The beauty of the equation is that it turns a long problem into a short one. You don't need to see the whole future at once. You only need to know two things: what you'll get from this step, and what the next situation is worth. And what the next situation is worth can be worked out with the same equation, from the situation after that.

In real life, many things are uncertain. A shipment of ammunition sent to the front might arrive on time, or it might get blown up on the way. A flight route you choose might go smoothly, or it might run into bad weather. Bellman's equation handles this too: if there are several possible next situations, you take the value of each and average them, weighted by how likely each one is. The value of a situation becomes "the reward right now, plus the average value of the next situation."


"Value" Is a Prediction

As we saw in the first post, reinforcement learning needs two things. One is prediction: knowing which situations lead to good outcomes. That's what Pavlov's dog learned. When the bell rang, it predicted food was coming. The other is choice: knowing which actions will get you into those good situations. That's what Thorndike's cat learned. It learned to pull the string.

Bellman's "value" is the mathematical version of the first. The value of a situation is, at bottom, a prediction about the future: starting from here, how much good will I end up with? And the Bellman equation provides the second as well. Once you know the value of every situation, choosing becomes simple: at every step, move toward the situation with the highest value. For Pavlov and Thorndike, prediction and choice were two animals in two different countries. With Bellman, they were written into the same equation for the first time.


1957: The Markov Decision Process

In 1957, Bellman published a book titled Dynamic Programming, and the same year a paper called "A Markovian Decision Process." In it, he laid out a standard framework for this whole class of problems. The framework has four parts:

  • States: the situation the system is in at a given moment, like the position on a chessboard, the stock in a warehouse, or which airport a plane is sitting at.

  • Actions: the choices available in each state.

  • Transitions: the probability that a given action will take you into each new state.

  • Rewards: the gain or loss that comes with each transition.

The "Markov" in the name comes from the Russian mathematician Andrey Markov, and refers to a particular assumption: what happens next depends only on the state you're in now, not on how you got there. Chess works this way. What determines your next move is the position on the board in front of you; the sequence of moves that produced that position doesn't matter.

Today's textbooks call this four-part framework the "Markov decision process." It's the common language of the entire field of reinforcement learning. The game of Go that AlphaGo faced, and the word-by-word answers ChatGPT generates during training, are both written mathematically in this framework.


The Curse of Dimensionality

Dynamic programming has a fatal weakness.

In the driving example, the situation has only one variable: which town you're in. But real problems usually have many. In a warehouse problem, for instance, the situation might include the stock level of ten different products. Say each product's stock is divided into just ten levels. Then the total number of possible situations is ten to the tenth power: ten billion. Dynamic programming requires working out every one. At one per second, that would take about 2.77 million hours, or more than three hundred years.

And that's only ten products at ten levels each. Every added variable multiplies the number of situations again. Bellman called this problem the "curse of dimensionality." Chess and Go are classic victims of the curse. The number of possible positions in chess is around ten to the forty-somethingth power; Go has far more, vastly more than the number of atoms in the universe. No machine could ever work through all of them.


1960: The Sears Catalog

In 1960, Ronald Howard, a young engineer at MIT, published Dynamic Programming and Markov Processes. He proposed a new method of solution called "policy iteration." Start with any set of rules for what to do, and work out what each situation is worth under those rules. Then, in each situation, check whether a different choice would do better, and if so, switch. Recalculate the values, improve the rules again, and keep going around until the rules stop changing. He proved that each round gets better, and that the process is guaranteed to stop after a finite number of steps with the best possible set of rules.

Howard later revealed that he invented the method to solve a real problem for Sears, Roebuck and Company: deciding which customers to send catalogs to. Because it involved trade secrets, he couldn't describe the actual problem in his book and had to demonstrate the method with made-up examples instead.

By the end of the 1950s, this whole toolkit, dynamic programming, the Bellman equation, the Markov decision process, and policy iteration, was already quite mature. But all of it rested on one assumption: that you know the rules of the world completely in advance.

Which actions are available in each situation, how likely each action is to take you where, how much reward each step brings: all of it has to be known. Most of RAND's logistics problems met this condition, because the rules were set by people and the probabilities could be estimated from historical data. So strictly speaking, what Bellman's method solved was planning, not learning. You hold a complete map, sit down, and calculate the best route.

Thorndike's cat had no map. It didn't know in advance which string opened the door, or what would happen when it pulled one; it could only try, again and again. The rat in SNARC had no map either. Real learning means working out the value of each situation from experience, little by little, with no map at all.

And even with a map, Bellman's method gets trapped by the curse of dimensionality: there are too many situations to ever finish calculating.

In 1965, Bellman left RAND for the University of Southern California, where he held professorships in mathematics, electrical engineering, and medicine at the same time. In his later years his interests turned increasingly toward biology and medicine. In 1973 he was diagnosed with a brain tumor. Surgery removed it, but complications left him severely disabled. Even so, he published more than a hundred papers in the last eleven years of his life. Over his career he wrote more than six hundred papers and about forty books. He died in Los Angeles in March 1984, at sixty-three. His autobiography came out the same year.

In those same years when Bellman was arriving at RAND and naming dynamic programming, an engineer at IBM's lab in Poughkeepsie, New York, was getting a computer to teach itself checkers. He didn't know in advance what each board position was worth, and there were far too many positions to work them all out. So he had the program play game after game against itself, estimating the value of each position bit by bit from experience, using exactly Bellman's idea of working backward. 🧪

Preface:1950 年,现代 AI 的核心方程,是用一个假名字从五角大楼眼皮底下偷运出来的。

接之前的 #AI 和 #MarvinMinsky 系列,本文和claude合作完成。


强化学习通常被讲成一个模仿大脑的故事:猫、鸽子、神经元、突触,一台想要像动物一样学习的机器。但它的另一半根基,和大脑没有任何关系。那一半来自冷战时期的军事后勤:导弹该怎么分配,飞机该怎么调度,仓库该什么时候补货。提出它的人从来没有研究过动物,也没有造过一台会学习的机器。他是一个只写方程的数学家,而且为了保住自己的研究经费,他还得假装自己做的不是数学。


1920:杂货店的儿子

Richard Bellman 1920 年出生于纽约,父母是俄罗斯和波兰犹太移民的后代,在布鲁克林展望公园附近的 Bergen Street 上开一家小杂货店。他九岁那年,大萧条开始了。父亲的生意被拖垮,但家里在极其艰难的情况下,还是供他读完了书。

他十一岁第一次接触代数,从此迷上了数学。高中时,他代表学校参加数学竞赛,毕业那年在全纽约的中学生里拿到了最高排名。1941 年他从布鲁克林学院毕业,又去威斯康星大学读了数学硕士。

战争打乱了一切。1944 年底,Bellman 被征召入伍,分配到新墨西哥州的洛斯阿拉莫斯,参与曼哈顿计划,在理论物理部门工作了两年。1946 年退伍后,他回到普林斯顿,只用了三个月就完成了博士学位。之后他去斯坦福当副教授,研究的是他最喜欢的纯数学分支:解析数论。

数论是研究整数的数学,尤其是质数,也就是只能被 1 和它自己整除的数,比如 2、3、5、7、11。数论问的都是一些听起来很简单、却极难回答的问题:质数有没有无穷多个?它们在整数里是怎么分布的?是不是每个大于 2 的偶数,都能写成两个质数之和?而解析数论,则是数论的一个分支,用微积分这类研究连续变化的工具,去回答关于整数的问题。

这听起来有些反直觉。整数是一格一格、彼此断开的,为什么要用研究光滑曲线和连续变化的方法去研究它?但事实证明,这非常有效。

质数一个个看,毫无规律。7 后面隔四个数是 11,11 后面隔两个是 13,13 后面又隔四个是 17。有时两个质数紧挨着,比如 101 和 103;有时中间隔着一大片空白。没人能预测下一个质数在哪里。

但如果换一个问题,不问"下一个质数在哪",而问"到某个数为止,一共有多少个质数",再把答案画成一条线,横轴是数的大小,纵轴是质数的个数,就会得到一条阶梯,每遇到一个质数就往上跳一格。近看,这些台阶高低不齐、宽窄不一。可是退远一点,几千、几万地看,台阶就连成了一条非常平滑的曲线。

这和人口统计是一个道理。没有人能预测某一个人哪天会去世,但保险公司可以相当准确地算出,一百万个六十岁的人里,明年大约会有多少人去世。个体是随机的,整体却有规律。而一旦质数的分布变成了一条平滑的曲线,研究平滑曲线最擅长的工具,也就是微积分,就有了用武之地。

据说高斯十五岁时就注意到了这条曲线。他亲手数了几千个质数,发现数越大,质数越稀疏,而稀疏的程度和一种叫"对数"的东西有关。比如 10 × 10 = 100,用了两个 10,所以 100 以 10 为底的对数是 2。六个 10 连乘是一百万,所以一百万以 10 为底的对数是 6。而被连乘的固定数则是底数。对数最重要的特点是,它长得非常慢。从 1000 到一百万,数大了一千倍,对数只从 3 变成 6。数每大十倍,对数只加一。

对数也不一定是整数。50 夹在 10 和 100 之间,它以 10 为底的对数就夹在 1 和 2 之间,大约是 1.7。"连乘 1.7 次"听上去说不通,但可以把它想成增长:一笔钱每年平稳地变成 10 倍,过一年是 10 倍,过两年是 100 倍,过 1.7 年时正好长到 50 倍。只要允许把"一次"切成小份,次数就可以是小数。每一个大于 0 的数,都有自己的对数。

底不同,对数也不同。同样是 50,以 10 为底是 1.7,以 7 为底约是 2,因为 7 × 7 = 49。底越小,要乘的次数越多,对数就越大。高斯用的是一种特殊的底,约等于 2.718,数学家叫它 e。以 e 为底的对数叫"自然对数",因为它最适合描述复利、繁殖这类平稳连续的增长。

高斯猜出的规律是,到某个数为止,质数的个数大约等于这个数除以它的自然对数。带进数字看一看。100 的自然对数约是 4.6,100 ÷ 4.6 约等于 22,实际有 25 个质数。1000 的自然对数约是 6.9,估出来约 145 个,实际是 168 个。一万以内,估计约 1086 个,实际是 1229 个。一百万的自然对数约是 13.8,估出来约 72,382 个,实际是 78,498 个。估计总是偏低一点,但数越大,偏差的比例越小:100 以内差了 12%,一百万以内只差 8%。

这条规律还有一个更直观的读法:在某个数附近,平均每隔"它的自然对数"个数,才会出现一个质数。100 附近,自然对数是 4.6,大约每四五个数就有一个质数。去数一数 90 到 110 之间:97、101、103、107、109,二十个数里五个质数,正好每四个一个。一百万附近,自然对数是 13.8,大约每 14 个数才有一个。数大了一万倍,质数之间的平均间隔只多了三倍。质数越来越稀疏,但稀疏得极慢。

高斯没能证明这条规律。真正让微积分能够研究质数的,是一个巧妙的转换。1737 年,瑞士数学家欧拉发现了一个等式:把所有正整数的某种倒数加起来,得到的结果,恰好等于一个只由质数组成的乘积。这个等式把"所有整数"和"所有质数"连进了同一个式子里。等式的一边是一个连续的函数,可以求导、可以画图、可以用微积分去分析;另一边,藏着全部的质数。研究这个函数,就等于在间接地研究质数。

欧拉用这个方法证明了一个惊人的结论:所有质数的倒数加起来,1/2 + 1/3 + 1/5 + 1/7 + 1/11……这个和永远不会停在某个数上,而是会一直变大下去。数学上,这叫"发散"。

它涨得极慢。把 10 以内的质数倒数加起来,大约是 1.18;加到 100 以内,约 1.8;加到一百万以内,约 2.9;加完十亿以内的所有质数,也才大约 3.3;一直加到一百亿亿,也就是 10 的 18 次方,才勉强到 4。慢到几乎看不出在涨,但它永远在涨。不管你说出多大的数,10 也好,100 也好,只要一直加下去,总有一天会超过它。

很多无穷加法并不是这样的。比如 1/2 + 1/4 + 1/8 + 1/16……每一项是前一项的一半,不管加多少项,总和都只会越来越接近 1,永远超不过它。这叫"收敛":项数是无穷的,总和却是有限的,因为后面的项缩小得太快了。再比如所有平方数的倒数,1/1 + 1/4 + 1/9 + 1/16……加到最后会停在约 1.645。这个问题恰好也是欧拉在几年前解开的。

一个无穷加法会不会停,取决于后面的项缩小得有多快。质数越来越稀疏,它们的倒数也越来越小。如果质数稀疏得很快,这个和就会像 1/2 + 1/4 + 1/8 那样停住。欧拉证明了它停不住,这说明两件事。第一,质数一定有无穷多个,因为如果只有有限个,倒数加起来必然是一个有限的数。第二,质数稀疏得非常慢,比平方数要密得多。这件事如果只盯着一个个整数去看,几乎不可能发现。

1859 年,德国数学家黎曼把欧拉的这个函数推广到了复数上,后来人们称它为黎曼 ζ 函数。他发现,质数分布那条平滑曲线和真实的阶梯之间总有一些误差,而这些误差,完全由这个函数等于零的那些点决定。

这有点像音乐。一个和弦听起来是一个混在一起的声音,但它其实是几个不同频率的音叠加而成的;知道了这些频率,就能把声音完整地重建出来。黎曼的发现是,质数那条凹凸不平的阶梯,也可以拆成一组"频率"的叠加,而这些频率,就是 ζ 函数的零点。知道了零点,就能精确地重建质数的分布。

黎曼猜想说的,就是这些零点全都整齐地排在一条直线上。如果它是对的,质数的分布就会以最"安静"的方式偏离那条平滑的曲线。这个猜想至今没有被证明,是数学界悬赏一百万美元的七大难题之一。

1896 年,两位数学家 Jacques Hadamard 和 Charles de la Vallée Poussin 各自独立地沿着黎曼的路线,终于证明了高斯一百年前猜出的那条规律。这就是质数定理:数越大,估计和实际之间的偏差比例就越接近零。

这条定理意味着几件事。

第一,混乱里藏着秩序。"只能被 1 和自己整除"是一条完全确定的规则,没有任何随机的成分,可它产生的质数,看起来却像随手撒出的一把沙子。而这把沙子的整体分布,又精确地落在一条平滑的曲线上。

第二,它有一个非常实际的用处。今天的网上银行、信用卡支付、浏览器地址栏旁那把小锁,很多都依赖几百位长的巨大质数。加密系统需要随时找到新的大质数,这就要求它们不能太稀少。质数定理正好保证了这一点:一个 300 位的数,自然对数大约是 690,也就是说在这么大的数附近,大约每 690 个数里就有一个质数。随机挑一些 300 位的奇数去检验,几百次之内就能撞上一个。

第三,它在两个世界之间架了一座桥。整数是断开的,e 却来自连续的增长。没有人会事先想到,研究"哪些整数只能被自己整除",答案里会冒出 2.718。数学里离散和连续这两个看似毫不相干的世界,在很深的地方是连在一起的。

整数问题之所以难,是因为每个数都是孤立的一点,没法用"变化"”趋势"”斜率"这样的概念去描述,而微积分恰恰是描述变化和趋势的语言。解析数论的诀窍,是找到一座桥:通过统计整体,或者通过构造一个函数,把断开的问题翻译成连续的问题,用连续的工具解出来,再翻译回去。


1949:兰德公司的夏天

1949 年夏天,Bellman 去了加州圣莫尼卡的兰德公司。兰德是二战后从美国空军的一个研究项目里独立出来的智库,专门为空军研究战略和后勤问题。他到了之后,问同事 Ed Paxson 兰德对什么感兴趣。Paxson 建议他研究"多阶段决策过程"。Bellman 照做了。

多阶段决策过程,是指一连串前后相连的决定,每一个决定都会改变下一个决定面对的处境。很多现实问题都是这样的。今天往前线运多少弹药,决定了明天库存还剩多少;明天剩多少,又决定了后天能运多少。一架飞机今天飞哪条航线,决定了它明天停在哪个机场。你不能孤立地看每一个决定,因为每一步都在为下一步铺路。Bellman 在斯坦福和兰德之间犹豫了一阵。一边是他热爱的数论,一边是这个全新的、看起来粗糙但充满可能的问题。1952 年,他离开斯坦福,正式成为兰德的研究数学家。


1950:一个连议员都挑不出毛病的名字

1950 年秋天,Bellman 在兰德面临的第一个任务,是给自己的研究起一个名字。

他在 1984 年的自传里讲过原因。他说 1950 年代对数学研究来说不是好年头。华盛顿有一位国防部长 Charles Wilson,对"研究"这个词抱有一种病态的恐惧和厌恶,听到它就会脸色涨红、大发雷霆。至于"数学"这个词会让他有什么反应,可想而知。兰德是为空军工作的,空军的顶头上司就是 Wilson。Bellman 觉得,他得想办法让空军和 Wilson 都看不出来,他在兰德做的其实是数学。

他先选了"规划"(programming)。这个词当时是军事术语,指的是制定一套训练或后勤的时间表,和今天说的"编程"不是一回事。然后他想表达这个问题是多阶段的、随时间变化的,于是加上了"动态"(dynamic)。他说,"动态"这个词有一个很有意思的特点:你没办法把它用在贬义上。这是一个连国会议员都挑不出毛病的名字。动态规划,即是把一个由一连串决定组成的大问题,拆成一个个小问题,从最后一步往前倒推着解决。


从后往前走

用一个具体的例子来说。假设你要从奥克兰开车去洛杉矶,中间要穿过很多个城镇,每到一个城镇都有几条路可以选。你想找出总路程最短的那条路线。

最笨的办法,是把所有可能的路线都列出来,一条条算总长度,再挑最短的那条。但城镇一多,路线的数量就会爆炸。每个城镇有三条路可选,经过十个城镇,就有三的十次方,也就是将近六万条路线。经过二十个城镇,就是三十多亿条。

Bellman 的想法是:不要从起点往前算,而是从终点往回算。

先看离洛杉矶只有一步的那些城镇。从每一个城镇到洛杉矶的最短距离,一眼就能看出来,记下来。然后往前退一步,看离洛杉矶两步的城镇。从这些城镇出发,你只需要比较:走到下一个城镇的距离,加上那个城镇到洛杉矶的最短距离(已经算好了),哪个加起来最小?记下来。再往前退一步,同样的办法。一直退到奥克兰。

这样一来,你不用再列出所有路线。每个城镇只需要算一次,而且每次只需要看眼前的几条路。

这个方法背后有一个非常简单的道理,Bellman 称之为"最优性原理"。用这个例子来说就是:如果从奥克兰到洛杉矶的最短路线经过弗雷斯诺,那么这条路线里从弗雷斯诺到洛杉矶的那一段,本身也必须是从弗雷斯诺到洛杉矶的最短路线。否则你就可以把那一段换成更短的,整条路线也就跟着变短了,这就和"它是最短路线"矛盾了。

最优性原理:一个最好的决策方案有这样一个性质,不管你从哪里出发、第一步怎么走,剩下的那些决定,对于你走完第一步之后所处的位置来说,也必须是最好的。换句话说,一个最好的整体,是由一个个最好的部分组成的。所以你可以从最后一段开始,一段一段地往前拼。


贝尔曼方程

把这个道理写成一个公式,就是今天强化学习里最核心的一条方程。

先定义一个概念:一个处境的"价值"。在开车的例子里,一个城镇的价值,就是从这里到洛杉矶还要走多远。在更一般的问题里,一个处境的价值,就是从这里出发、之后每一步都做出最好的选择,最终能拿到的全部回报。

贝尔曼方程(Bellman equation):一个处境的价值,等于你在这一步能拿到的回报,加上你接下来会进入的那个处境的价值。而最好的选择,就是让这两项加起来最大的那一个。

这个方程的妙处,在于它把一个很长的问题变成了一个很短的问题。你不需要一眼看清整个未来,只需要知道两件事:眼前这一步能得到什么,以及下一个处境值多少。而下一个处境值多少,又可以用同一个方程,从再下一个处境推出来。

现实中,很多事情不是确定的。你往前线运了一批弹药,它可能按时到达,也可能在路上被炸掉。你选了一条航线,可能顺利,也可能遇到坏天气。Bellman 的方程同样能处理这种情况:如果下一个处境有好几种可能,就把每种可能的价值,按它发生的概率加权平均。一个处境的价值,就变成了"眼前的回报,加上下一个处境的平均价值"。


"价值"是一种预测

第一篇讲过,强化学习需要两样东西。一样是预测:哪些处境会带来好的结果。Pavlov 的狗学会的就是这个,铃声一响,它就预测到食物要来了。另一样是选择:采取什么行动,才能进入那些好的处境。Thorndike 的猫学会的是这个,它学会了去拉那根绳子。

Bellman 的"价值",就是第一样东西的数学版本。一个处境的价值,本质上是对未来的一种预测:从这里出发,我最终能拿到多少好处。而贝尔曼方程同时也给出了第二样东西:知道了每个处境的价值,选择就变得很简单,每一步都走向价值最高的那个处境就行了。预测和选择,在 Pavlov 和 Thorndike 那里是两个国家的两种动物。在 Bellman 这里,第一次被写进了同一个方程。


1957:马尔可夫决策过程

1957 年,Bellman 出版了《动态规划》一书,同年又发表了一篇论文,题为《一个马尔可夫决策过程》。他在里面给这一类问题搭了一个标准的框架。这个框架由四样东西组成:

  • 处境:系统当时所处的状态,比如棋盘上的局面、仓库里的库存、飞机停在哪个机场。
    行动:在每个处境下可以做的选择。
    转移:做了某个行动之后,会以多大的概率进入哪个新处境。
    回报:每一次转移带来的好处或坏处。

名字里的"马尔可夫",来自俄国数学家 Andrey Markov,指的是一个特定的假设:下一步会发生什么,只取决于你现在所处的处境,而和你是怎么走到这里的无关。下棋就是这样。决定下一步怎么走的,只是眼前棋盘上的局面,至于这个局面是经过哪些步骤形成的,并不重要。

这个四件套框架,今天的教科书叫它"马尔可夫决策过程"。它是整个强化学习领域的通用语言。AlphaGo 面对的围棋、ChatGPT 在训练中逐字生成的回答,在数学上都被写成这个框架。


维度的诅咒

动态规划有一个致命的弱点。

在开车的例子里,处境只有一个变量:你在哪个城镇。但现实中的问题往往有很多个变量。比如一个仓库问题,处境可能包括十种货物各自的库存量。假设每种货物的库存只分十个档次,那么所有可能的处境加起来,就是十的十次方,一百亿个。动态规划要求每个处境都算一遍。如果一秒钟算一个,算完需要大约二百七十七万个小时,也就是三百多年。

而这只是十种货物、十个档次。变量每多一个,处境的数量就要再乘一次。Bellman 把这个困难称为"维度诅咒"(curse of dimensionality)。国际象棋和围棋就是被这个诅咒困住的典型。国际象棋可能的局面数量,大约是十的四十多次方;围棋则更多,远远超过宇宙中原子的总数。没有任何一台机器能把这些局面全部算一遍。


1960:西尔斯百货的目录

1960 年,麻省理工学院的一位年轻工程师 Ronald Howard 出版了《动态规划与马尔可夫过程》。他提出了一种新的解法,叫"策略迭代":先随便定一套做法,算出按这套做法每个处境值多少;然后在每个处境,看看换一种做法能不能更好,能就换;再重新算价值,再改进做法,如此循环,直到做法不再改变为止。他证明了,这个过程每一轮都会变得更好,而且一定会在有限的步数内停下来,得到最好的那套做法。

Howard 后来透露,他发明这个方法,是为了解决西尔斯百货公司的一个实际问题:怎样决定该给哪些顾客寄商品目录。因为涉及商业机密,他在书里没能写出这个问题本身,只能用一些虚构的例子来演示。

动态规划、贝尔曼方程、马尔可夫决策过程、策略迭代,这一整套工具在 1950 年代末已经相当成熟。但它们都有一个前提:你必须事先完全知道这个世界的规则。

每一个处境下有哪些行动可选,每个行动会以多大的概率把你带到哪里,每一步能拿到多少回报,这些全都必须是已知的。兰德公司的后勤问题大多满足这个前提,因为规则本来就是人定的,概率可以从历史数据里估出来。所以严格来说,Bellman 的方法解决的是"规划",而不是"学习":你拿着一张完整的地图,坐下来算出最好的路线。

Thorndike 的猫没有地图。它事先不知道哪根绳子开门,不知道拉了之后会发生什么,只能一次次去试。SNARC 里的老鼠也没有地图。真正的学习,是在没有地图的情况下,从一次次经验里慢慢摸索出每个处境的价值。

而 Bellman 的方法即使有地图,也会被维度诅咒困住:处境太多,根本算不完。

1965 年,Bellman 离开兰德,去南加州大学同时担任数学、电机工程和医学教授,晚年的兴趣越来越多地转向生物和医学。1973 年,他被诊断出脑瘤。手术切除了肿瘤,但并发症让他严重残疾。在生命的最后十一年里,他仍然发表了一百多篇论文。他一生写了六百多篇论文和大约四十本书。1984 年 3 月,他在洛杉矶去世,享年六十三岁。他的自传在同一年出版。

就在 Bellman 进入兰德、给动态规划起名字的那几年,纽约州波基普西的 IBM 实验室里,一位工程师正在让一台计算机自己学下跳棋。他事先不知道每一个局面值多少,局面也多到不可能全部算一遍。他让程序和自己一盘盘地下,从经验里一点点估出每个局面的价值,用的正是 Bellman 那个从后往前推的思路。🧪