Kodduu Python
1.07K subscribers
312 photos
28 videos
188 links
Научись программировать на Python на интересных примерах

Самый быстрый курс https://stepik.org/a/187914
Самый нескучный курс https://stepik.org/a/185238

Во вопросам сотрудничества: @AlexErf
Download Telegram
Собрали программу для тех кому некогда, но нужно быстро пройти весь Python + DataScience 👈👈👈

Подпишись 👉🏻 @KodduuPython 🤖
4🔥1
Создадим интересную программу на Python, которая реализует генетический алгоритм для решения задачи оптимизации — нахождения минимума функции. Мы применим генетический алгоритм для минимизации функции Растригина, известной своей сложностью и множеством локальных минимумов.


import numpy as np
import matplotlib.pyplot as plt

# Определение функции Растригина
def rastrigin(x):
A = 10
return A * len(x) + sum([(xi**2 - A * np.cos(2 * np.pi * xi)) for xi in x])

# Параметры генетического алгоритма
POP_SIZE = 100 # Размер популяции
GENES = 2 # Количество генов (размерность задачи)
GENERATIONS = 50 # Количество поколений
MUTATION_RATE = 0.1 # Вероятность мутации

# Инициализация популяции
population = [np.random.uniform(-5.12, 5.12, GENES) for _ in range(POP_SIZE)]

# Эволюционный цикл
best_scores = []
for generation in range(GENERATIONS):
# Оценка приспособленности
fitness = [ -rastrigin(individual) for individual in population]

# Сохранение лучшего результата
best_scores.append(-min(fitness))

# Селекция
parents = [population[i] for i in np.argsort(fitness)[-POP_SIZE//2:]]

# Кроссовер
offspring = []
for _ in range(POP_SIZE//2):
parent1, parent2 = np.random.choice(parents, 2, replace=False)
crossover_point = np.random.randint(1, GENES)
child = np.concatenate([parent1[:crossover_point], parent2[crossover_point:]])
offspring.append(child)

# Мутация
for individual in offspring:
if np.random.rand() < MUTATION_RATE:
mutation_point = np.random.randint(GENES)
individual[mutation_point] += np.random.uniform(-1, 1)
individual[mutation_point] = np.clip(individual[mutation_point], -5.12, 5.12)

# Обновление популяции
population = parents + offspring

# Вывод результатов
best_individual = population[np.argmax(fitness)]
print("Лучшее решение:", best_individual)
print("Значение функции:", rastrigin(best_individual))

# Визуализация сходимости
plt.plot(best_scores)
plt.title('Сходимость генетического алгоритма')
plt.xlabel('Поколение')
plt.ylabel('Значение функции')
plt.show()


Описание кода:

1. Функция Растригина (`rastrigin`): сложная функция с множеством локальных минимумов, часто используемая для тестирования алгоритмов оптимизации.

2. Параметры алгоритма:
- POP_SIZE: количество особей в популяции.
- GENES: количество генов в хромосоме (размерность задачи).
- GENERATIONS: количество поколений для эволюции.
- MUTATION_RATE: вероятность мутации потомка.

3. Инициализация популяции: создаем начальную популяцию со случайными значениями в диапазоне [-5.12, 5.12].

4. Эволюционный цикл:
- Оценка приспособленности: вычисляем отрицательное значение функции Растригина для каждой особи (так как мы минимизируем функцию).
- Сохранение лучшего результата: отслеживаем наилучшее значение функции в каждом поколении.
- Селекция: выбираем лучших особей (с наилучшей приспособленностью) для создания потомства.
- Кроссовер: комбинируем гены пар родителей для создания новых особей.
- Мутация: вносим случайные изменения в гены потомков с определенной вероятностью.
- Обновление популяции: формируем новую популяцию из родителей и потомков.

5. Вывод результатов:
- Находим и выводим лучшую особь после всех поколений.
- Выводим соответствующее значение функции Растригина.
- Строим график сходимости значений функции по поколениям.

Как запустить код:

1. Установите необходимые библиотеки:


pip install numpy matplotlib


2. Сохраните код в файл, например `genetic_algorithm.py`.

3. Запустите скрипт:


python genetic_algorithm.py


Ожидаемый результат:

- В консоли отобразится лучшее найденное решение и значение функции в этой точке.
- Откроется график, показывающий, как значение функции менялось по мере эволюции поколений.

Примечания:
2
- Эксперименты с параметрами: Попробуйте изменить параметры алгоритма (размер популяции, количество поколений, вероятность мутации), чтобы увидеть, как они влияют на результат и скорость сходимости.
- Расширение на большую размерность: Вы можете увеличить GENES для решения задачи в пространстве большей размерности, что сделает задачу более сложной.

Заключение:

Этот пример демонстрирует применение генетических алгоритмов для решения задач оптимизации сложных функций. Генетические алгоритмы имитируют процессы естественного отбора и генетической мутации, позволяя находить приближенные решения в задачах, где аналитическое решение затруднительно.

Подпишись 👉🏻 @KodduuPython 🤖
🔥2
Вот код, который создает интерактивную визуализацию, где точки движутся, образуя различные узоры. Этот код создает окно с анимацией точек, которые перемещаются по кругу и создают интересные узоры. К тому же, это легко настраивается для других геометрических форм.


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# Настройка параметров
num_points = 50
radius = 10

# Создаем исходные координаты точек на окружности
angles = np.linspace(0, 2 * np.pi, num_points, endpoint=False)
x_coords = radius * np.cos(angles)
y_coords = radius * np.sin(angles)

fig, ax = plt.subplots()
ax.set_aspect('equal', 'box')
scatter = ax.scatter(x_coords, y_coords, s=50, color='blue')
ax.set_xlim(-radius * 1.2, radius * 1.2)
ax.set_ylim(-radius * 1.2, radius * 1.2)

def update(frame):
# Обновление углов и координат для движения точек
new_angles = angles + 0.1 * frame
x_coords = radius * np.cos(new_angles + frame * 0.01)
y_coords = radius * np.sin(new_angles + frame * 0.01)
scatter.set_offsets(np.c_[x_coords, y_coords])
return scatter,

ani = animation.FuncAnimation(fig, update, frames=200, interval=50, blit=True)
plt.show()


Этот код:

- Создает 50 точек, которые расположены по кругу.
- С каждой итерацией они слегка смещаются, создавая эффект "волны" и "размытости".
- Получается гипнотическая анимация, которую можно менять, изменяя радиус, количество точек или скорость.

Подпишись 👉🏻 @KodduuPython 🤖
Попробуем создать более сложную анимацию, в которой точки будут двигаться по нелинейным траекториям, создавая узоры. Этот пример использует траектории, которые зависят от синусоидальных и косинусоидальных функций с переменным радиусом, чтобы добавить нелинейные колебания.


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# Настройка параметров
num_points = 50
base_radius = 10

# Создаем исходные углы для точек
angles = np.linspace(0, 2 * np.pi, num_points, endpoint=False)

fig, ax = plt.subplots()
ax.set_aspect('equal', 'box')
scatter = ax.scatter([], [], s=50, color='purple')
ax.set_xlim(-base_radius * 1.5, base_radius * 1.5)
ax.set_ylim(-base_radius * 1.5, base_radius * 1.5)

# Обновление координат для нелинейных траекторий
def update(frame):
# Нелинейный радиус с добавлением синусоидальной амплитуды
radius = base_radius + 3 * np.sin(frame * 0.05)
x_coords = radius * np.cos(angles + 0.05 * frame) + 2 * np.sin(angles * 3 + frame * 0.1)
y_coords = radius * np.sin(angles + 0.05 * frame) + 2 * np.cos(angles * 4 + frame * 0.1)

scatter.set_offsets(np.c_[x_coords, y_coords])
return scatter,

# Настройка анимации
ani = animation.FuncAnimation(fig, update, frames=400, interval=50, blit=True)
plt.show()


### Как это работает:
- Радиус каждой точки зависит от времени и изменяется по синусоиде, что делает движение точек более динамичным.
- Траектория движения каждой точки - это комбинация нескольких синусоидальных и косинусоидальных функций, что создает уникальные узоры на каждом кадре.
- Частотные множители для angles (например, 3 и 4 внутри x_coords и `y_coords`) добавляют колебания по окружности, что создает сложные, закрученные траектории.

Подпишись 👉🏻 @KodduuPython 🤖
This media is not supported in your browser
VIEW IN TELEGRAM
Код анимации выше 👆👆👆

Подпишись 👉🏻 @KodduuPython 🤖
👍3
Собрали программу Junior FullStack Developer and Data Scientist, включает 3 наших самых компактных курса, можно пройти за 2-3 викэнда. В программе вся база по Python + вся база по JavaScript + вся база по Data Science в Python 😎

Подпишись 👉🏻 @KodduuPython 🤖
Как насчёт кода, который рисует фрактал *Множества Мандельброта* и анимирует его приближение? Это отличный пример красоты и сложности фрактальной геометрии! И демо того как оно может тормозить на большом кол-во объектов 🐌 В следующем посте расскажем как ускорить ⚡️

Вот код для визуализации этого фрактала с постепенным "увеличением" на определённой области:


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# Настройка параметров фрактала
width, height = 800, 800 # Размер окна
max_iter = 256 # Максимальное количество итераций

# Начальные координаты для анимации (центр Мандельброта)
xmin, xmax, ymin, ymax = -2.0, 1.0, -1.5, 1.5

# Функция для вычисления множества Мандельброта
def mandelbrot(c, max_iter):
z = c
for n in range(max_iter):
if abs(z) > 2:
return n
z = z*z + c
return max_iter

# Функция, которая генерирует фрактал
def generate_mandelbrot(xmin, xmax, ymin, ymax, width, height, max_iter):
x, y = np.linspace(xmin, xmax, width), np.linspace(ymin, ymax, height)
C = x + y[:, None] * 1j
mandelbrot_set = np.frompyfunc(lambda c: mandelbrot(c, max_iter), 1, 1)(C).astype(np.float32)
return mandelbrot_set

# Создаем фигуру и ось для анимации
fig, ax = plt.subplots(figsize=(6, 6))
im = ax.imshow(generate_mandelbrot(xmin, xmax, ymin, ymax, width, height, max_iter),
extent=(xmin, xmax, ymin, ymax), cmap='hot', origin='lower')

# Функция обновления для анимации
def update(frame):
zoom_factor = 1.5 ** (-frame * 0.1)
x_center, y_center = -0.7435, 0.1314 # координаты интересной точки
dx, dy = (xmax - xmin) * zoom_factor, (ymax - ymin) * zoom_factor
xmin_new, xmax_new = x_center - dx / 2, x_center + dx / 2
ymin_new, ymax_new = y_center - dy / 2, y_center + dy / 2

mandelbrot_set = generate_mandelbrot(xmin_new, xmax_new, ymin_new, ymax_new, width, height, max_iter)
im.set_data(mandelbrot_set)
im.set_extent((xmin_new, xmax_new, ymin_new, ymax_new))
return im,

# Анимация фрактала
ani = animation.FuncAnimation(fig, update, frames=100, interval=50, blit=True)
plt.show()


### Объяснение кода:
- Множество Мандельброта создаётся путём проверки, стремятся ли точки в комплексной плоскости к бесконечности при итерациях по формуле \( z = z^2 + c \).
- Функция `generate_mandelbrot` вычисляет фрактал для заданных границ и преобразует его в массив значений.
- Анимация `update` постепенно уменьшает масштаб (приближает) вокруг интересной точки, что позволяет видеть больше деталей.

Подпишись 👉🏻 @KodduuPython 🤖
This media is not supported in your browser
VIEW IN TELEGRAM
Код анимации тут 👆👆👆

Подпишись 👉🏻 @KodduuPython 🤖
Для ускорения анимации Множества Мандельброта можно воспользоваться несколькими подходами:

1. Уменьшить разрешение (размер width и `height`), чтобы уменьшить количество вычисляемых точек.
2. Оптимизировать функцию `mandelbrot` с использованием Numba для компиляции в машинный код, что значительно ускоряет обработку.
3. Параллельные вычисления для обработки точек массива.

Давайте применим Numba и создадим ускоренную версию. Для этого сначала нужно установить numba, если она не установлена:


pip install numba


Затем добавим @njit из Numba, чтобы ускорить расчёты:


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from numba import njit

# Настройка параметров фрактала
width, height = 600, 600 # Уменьшили размер для повышения скорости
max_iter = 256 # Максимальное количество итераций

# Компилируем функцию с помощью Numba
@njit
def mandelbrot(c, max_iter):
z = c
for n in range(max_iter):
if abs(z) > 2:
return n
z = z * z + c
return max_iter

@njit
def generate_mandelbrot(xmin, xmax, ymin, ymax, width, height, max_iter):
x = np.linspace(xmin, xmax, width)
y = np.linspace(ymin, ymax, height)
mandelbrot_set = np.empty((height, width), dtype=np.float32)
for i in range(width):
for j in range(height):
mandelbrot_set[j, i] = mandelbrot(x[i] + 1j * y[j], max_iter)
return mandelbrot_set

# Создаем фигуру и ось для анимации
fig, ax = plt.subplots(figsize=(6, 6))
im = ax.imshow(generate_mandelbrot(-2.0, 1.0, -1.5, 1.5, width, height, max_iter),
extent=(-2.0, 1.0, -1.5, 1.5), cmap='hot', origin='lower')

# Функция обновления для анимации
def update(frame):
zoom_factor = 1.5 ** (-frame * 0.1)
x_center, y_center = -0.7435, 0.1314 # координаты интересной точки
dx, dy = (1.0 - -2.0) * zoom_factor, (1.5 - -1.5) * zoom_factor
xmin_new, xmax_new = x_center - dx / 2, x_center + dx / 2
ymin_new, ymax_new = y_center - dy / 2, y_center + dy / 2

mandelbrot_set = generate_mandelbrot(xmin_new, xmax_new, ymin_new, ymax_new, width, height, max_iter)
im.set_data(mandelbrot_set)
im.set_extent((xmin_new, xmax_new, ymin_new, ymax_new))
return im,

# Анимация фрактала
ani = animation.FuncAnimation(fig, update, frames=100, interval=50, blit=True)
plt.show()


### Изменения в коде:
- Numba (`@njit`) значительно ускоряет функции mandelbrot и generate_mandelbrot за счёт компиляции в машинный код.
- Уменьшение `width` и `height` до 600x600 пикселей снижает нагрузку на процессор.

Эти изменения помогут повысить производительность, делая анимацию более плавной и быстрой.

Подпишись 👉🏻 @KodduuPython 🤖
This media is not supported in your browser
VIEW IN TELEGRAM
Код анимации тут 👆👆👆

Подпишись 👉🏻 @KodduuPython 🤖
Скидка на программу Junior FullStack Developer and Data Scientist действует до 22.11.

Программа включает 3 наших самых компактных курса, можно пройти за 2-3 викэнда. В программе вся база по Python + вся база по JavaScript + вся база по Data Science в Python 😎

Подпишись 👉🏻 @KodduuPython 🤖