Как известно, гипотеза Пуанкаре на сегодня является единственной решённой задачей тысячелетия.
Её формулировка довольно проста:
Всякое односвязное компактное трёхмерное многообразие без края гомеоморфно трёхмерной сфере. Источник [1].
В 2002-2003 годах российский математик Григорий Яковлевич Перельман (Источник [10]) опубликовал 3 препринта на Arxiv.org со своим доказательством (Источник [11],[12], [13]). Его правильность проверили и подтвердили 3 независимые группы учёных (Источник [3], [6]) и в 2006 году Перельману присудили премию Филдса, а в 2010 году Премию тысячелетия в 1 млн долларов, но тот от обеих высоких наград отказался. Источник [1].
В этой статье мы сделаем компьютерную визуализацию основных пунктов доказательства.
Упрощённая схема доказательства приведена в Источник [1]:
Пусть есть произвольное односвязное компактное трёхмерное многообразие без края:

Начнём с потоков Риччи:
Поток Риччи — система дифференциальных уравнений в частных производных, описывающая деформацию римановой метрики на многообразии. Ключевая идея данных уравнений- где кривизна больше — там метрика меняется быстрее.Источник [2].
Уравнение Риччи записывается так:
Где:
— метрический тензор (задаёт геометрию многообразия),
— тензор Риччи (характеризует кривизну),
t — параметр «времени» потока (не физическое время, а параметр эволюции метрики).
Для иллюстрации напишем код на Python, демонстрирующий одномерную кривизну и поток:
import numpy as np import matplotlib.pyplot as plt # Параметры N = 100 # число точек на отрезке L = 1.0 # длина отрезка dx = L / (N - 1) x = np.linspace(0, L, N) # Начальное «поле кривизны» (аналог скалярной кривизны в 1D) # Сделаем горбик в центре R = np.zeros(N) center = N // 2 width = N // 8 for i in range(N): R[i] = np.exp(-((i - center) / width)**2) # Метрика (в 1D это просто локальный масштаб ds^2 = g dx^2) g = np.ones(N) # изначально везде 1 dt = 0.01 # шаг по «времени потока» steps = 500 # сколько шагов сделать history_g = [] for t in range(steps): # Аналог потока Риччи: dg/dt ~ -R (упрощённо) dg = -2* R * dt g += dg # Ограничиваем, чтобы метрика не стала отрицательной g = np.maximum(g, 0.1) if t % 50 == 0: history_g.append(g.copy()) # Визуализация plt.figure(figsize=(8, 4)) for i, g_snap in enumerate(history_g): plt.plot(x, g_snap, label=f'step {i*50}') plt.plot(x, R, 'k--', linewidth=1, label='curvature R') plt.xlabel('x') plt.ylabel('metric g') plt.title('Simplified Ricci-like flow (1D toy model)') plt.legend() plt.grid(True) plt.show()
Результат работы программы видно здесь:

В 2d код будет посложнее:
import numpy as np import matplotlib.pyplot as plt from scipy.spatial import Delaunay from matplotlib.animation import FuncAnimation # --- Параметры --- N = 120 # число точек dt = 0.002 # шаг по «времени» steps = 400 # сколько шагов target_curvature = 0.0 # целевая кривизна в каждой вершине (0 = плоская) np.random.seed(42) points = np.random.rand(N, 2) * 10.0 # [0,10] x [0,10] def compute_angles_and_curvature(points, tri): """ Для каждой вершины считаем сумму углов треугольников вокруг неё. Дискретная гауссова кривизна: K_i = 2π - Σ углов. """ n = len(points) angles_sum = np.zeros(n) for s in tri.simplices: i, j, k = s a = points[j] - points[i] b = points[k] - points[i] c = points[k] - points[j] la = np.linalg.norm(a) lb = np.linalg.norm(b) lc = np.linalg.norm(c) # защита от вырожденных треугольников if la < 1e-8 or lb < 1e-8 or lc < 1e-8: continue cos_i = np.clip((la**2 + lb**2 - lc**2) / (2*la*lb), -1.0, 1.0) cos_j = np.clip((la**2 + lc**2 - lb**2) / (2*la*lc), -1.0, 1.0) cos_k = np.clip((lb**2 + lc**2 - la**2) / (2*lb*lc), -1.0, 1.0) angles_sum[i] += np.arccos(cos_i) angles_sum[j] += np.arccos(cos_j) angles_sum[k] += np.arccos(cos_k) K = 2*np.pi - angles_sum return K # --- Подготовка для анимации --- fig, ax = plt.subplots(figsize=(6, 6)) ax.set_aspect('equal') ax.axis('off') # Хранилище кадров frames_K = [] frames_points = [] # Начальное состояние tri = Delaunay(points) K = compute_angles_and_curvature(points, tri) frames_K.append(K.copy()) frames_points.append(points.copy()) # --- Эволюция (поток) --- for t in range(steps): # Вычисляем кривизну tri = Delaunay(points) K = compute_angles_and_curvature(points, tri) # Правило обновления: двигаем точки так, чтобы кривизна стремилась к target_curvature diff = target_curvature - K # Локальное масштабирование: если K > target, «раздвигаем» точки вокруг вершины scale_factor = 1.0 + dt * diff scale_factor = np.clip(scale_factor, 0.8, 1.2) # ограничение, чтобы не схлопнулось center = points.mean(axis=0) points = center + (points - center) * scale_factor[:, np.newaxis] # Сохраняем состояние if t % 10 == 0: frames_K.append(K.copy()) frames_points.append(points.copy()) # --- Визуализация: последний кадр + распределение кривизны --- tri_final = Delaunay(frames_points[-1]) K_final = frames_K[-1] plt.figure(figsize=(10, 4)) plt.subplot(1, 2, 1) plt.triplot(frames_points[-1][:, 0], frames_points[-1][:, 1], tri_final.simplices, color='gray', linewidth=0.4, alpha=0.7) sc = plt.scatter(frames_points[-1][:, 0], frames_points[-1][:, 1], c=K_final, cmap='coolwarm', s=25, edgecolors='k', linewidths=0.3) plt.colorbar(sc, label='Gaussian curvature K') plt.title('Final state after Ricci-like flow') plt.axis('equal') plt.subplot(1, 2, 2) mean_K = [np.mean(K) for K in frames_K] var_K = [np.var(K) for K in frames_K] plt.plot(mean_K, label='Mean curvature', color='blue') plt.plot(var_K, label='Variance of curvature', color='orange') plt.axhline(target_curvature, color='green', linestyle='--', label='Target') plt.xlabel('Step (every 10 iterations saved)') plt.ylabel('Curvature stats') plt.legend() plt.grid(True, alpha=0.3) plt.title('Evolution of curvature statistics') plt.tight_layout() plt.show()
В итоге мы получим следующую картинку:


Он позволяет деформировать риманову метрику на многообразии, но в процессе деформации возможно образование «сингулярностей» — точек, в которых кривизна стремится к бесконечности, и деформацию невозможно продолжить.Источник [1]

В таком случае производят хирургию: Вырезают "шею" и залепляют её шарами, а затем продолжают деформацию.Источник [1].
Напишем код для демонстрации:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # --- Параметры поверхности (гантель) --- def radius_gantel(z, L=4.0, r_thick=1.0, neck_width=0.4, neck_height=0.5): """ Радиус сечения гантели в зависимости от z. L - полная длина вдоль z, r_thick - радиус шаров, neck_width - ширина шеи, neck_height - насколько она тонкая. """ # Нормализованная координата от -1 до 1 t = z / (L / 2) # Функция, которая даёт «шею» в центре и «шары» по краям r = r_thick * (1.0 - neck_height * np.exp(-t**2 / (neck_width**2))) return r def smooth_radius(z, L, r_thick, alpha=0.3): """ Имитация сглаживания (упрощённый «поток Риччи»): делаем шею менее выраженной, поверхность более сферической. alpha - сила сглаживания: 0 = без сглаживания, 1 = почти сфера. """ t = z / (L / 2) # Базовая гантель r_base = radius_gantel(z, L, r_thick, neck_width=0.6, neck_height=0.7) # Целевая сфера (радиус как среднее) r_sphere = r_thick # Линейная интерполяция между гантелью и сферой r_smooth = (1 - alpha) * r_base + alpha * r_sphere return r_smooth # --- Генерация сетки --- L = 4.0 z = np.linspace(-L/2, L/2, 80) theta = np.linspace(0, 2*np.pi, 80) Z, Theta = np.meshgrid(z, theta) # Радиусы для «до» (гантель) и «после» (сглаженная) R_before = radius_gantel(Z, L) R_after = smooth_radius(Z, L, r_thick=1.0, alpha=0.85) # сильное сглаживание # Переход в декартовы координаты X_before = R_before * np.cos(Theta) Y_before = R_before * np.sin(Theta) X_after = R_after * np.cos(Theta) Y_after = R_after * np.sin(Theta) # --- Визуализация --- fig = plt.figure(figsize=(12, 5)) ax1 = fig.add_subplot(121, projection='3d') surf1 = ax1.plot_surface(X_before, Y_before, Z, cmap='viridis', alpha=0.9, edgecolor='none') ax1.set_title('До: гантелеподобное многообразие\n(возможная сингулярность в шее)') ax1.set_xlabel('X'); ax1.set_ylabel('Y'); ax1.set_zlabel('Z') ax2 = fig.add_subplot(122, projection='3d') surf2 = ax2.plot_surface(X_after, Y_after, Z, cmap='plasma', alpha=0.9, edgecolor='none') ax2.set_title('После: сглаженное многообразие\n(упрощённая имитация потока Риччи)') ax2.set_xlabel('X'); ax2.set_ylabel('Y'); ax2.set_zlabel('Z') plt.tight_layout() plt.show()
В результате получаем следующую картинку:

Таким образом, исходное многообразие гомеоморфно (то есть переходит путём непрерывных деформаций) связной сумме трёхмерных сфер,

то есть трёхмерной сфере.

Таким образом, в данной статье сделана компьютерная визуализация основных идей доказательства Перельмана, получены несколько графических иллюстраций многообразия, потоков Риччи, сглаживания "шеи" и финального результата.
Статья носит чисто иллюстративный и демонстративный характер для наглядного представления доказательства гипотезы Пуанкаре.
Литература:
1.https://ru.wikipedia.org/wiki/Гипотеза_Пуанкаре
2.https://ru.wikipedia.org/wiki/Поток_Риччи
3.https://arxiv.org/abs/math/0612069
4.https://old.mccme.ru/free-books/matpros/articles/МП-24/mp-24-pages-8.pdf
5.https://arxiv.org/abs/0809.1483
6.https://arxiv.org/pdf/math/0211159
7.https://www.wikidata.org/wiki/Q99179783
8.https://www.wikidata.org/wiki/Q99178831
9.https://docs.yandex.ru/docs/view?tm=1784695492&tld=ru&lang=ru&name=mp-24-pages-8.pdf&text=гипотеза пуанкаре доказательство&url=https%3A%2F%2Fold.mccme.ru%2Ffree-books%2Fmatpros%2Farticles%2F%25D0%259C%25D0%259F-24%2Fmp-24-pages-8.pdf&lr=20683&mime=pdf&l10n=ru&sign=a33bbb82ab624fbc77c6d5f4d9a042d9&keyno=0&nosw=1&serpParams=tm%3D1784695492%26tld%3Dru%26lang%3Dru%26name%3Dmp-24-pages-8.pdf%26text%3D%25D0%25B3%25D0%25B8%25D0%25BF%25D0%25BE%25D1%2582%25D0%25B5%25D0%25B7%25D0%25B0%2B%25D0%25BF%25D1%2583%25D0%25B0%25D0%25BD%25D0%25BA%25D0%25B0%25D1%2580%25D0%25B5%2B%25D0%25B4%25D0%25BE%25D0%25BA%25D0%25B0%25D0%25B7%25D0%25B0%25D1%2582%25D0%25B5%25D0%25BB%25D1%258C%25D1%2581%25D1%2582%25D0%25B2%25D0%25BE%26url%3Dhttps%253A%2F%2Fold.mccme.ru%2Ffree-books%2Fmatpros%2Farticles%2F%2525D0%25259C%2525D0%25259F-24%2Fmp-24-pages-8.pdf%26lr%3D20683%26mime%3Dpdf%26l10n%3Dru%26sign%3Da33bbb82ab624fbc77c6d5f4d9a042d9%26keyno%3D0%26nosw%3D1
10.https://ru.wikipedia.org/wiki/Перельман,_Григорий_Яковлевич
11.https://arxiv.org/abs/math/0307245