Алгоритмы неформально. Инструкция для начинающих питонистов - [18]

Шрифт
Интервал

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

3. Максимизация и минимизация

В жизни мы, как правило, стараемся избегать крайностей, но в мире алгоритмов интерес обычно представляют экстремальные значения. Некоторые мощные алгоритмы предназначены для поиска максимумов (например, максимальная прибыль, максимальная эффективность, максимальная производительность) и минимумов (минимальные затраты, минимальная вероятность ошибки, минимальный дискомфорт и т.д.). В этой главе мы изучим градиентный подъем и градиентный спуск — два простых, но действенных метода эффективного нахождения максимумов и минимумов функций. Кроме того, рассмотрим некоторые проблемы, присущие задачам максимизации и минимизации, и способы их решения. Наконец, мы обсудим, как узнать, уместно ли использовать тот или иной алгоритм в конкретной ситуации. Начнем с гипотетического сценария — выбора оптимальной ставки налога для максимизации доходов правительства и посмотрим, как использовать алгоритм для поиска решения.


Выбор ставки налога

Представьте, что вас избрали премьер-министром небольшой страны. Перед вами стоят амбициозные цели, но нет средств для их реализации. А значит, после вступ­ления в должность вы первым делом должны максимизировать поступления от налогов, которые собирает ваше правительство.

Остается понять, какую ставку следует выбрать для максимизации налоговых поступлений. Если ставка налога составляет 0 %, то вы получите нулевые поступ­ления в бюджет. При 100 % налогоплательщики наверняка постараются избежать какой-либо производственной деятельности и начнут искать лазейки настолько усердно, что поступления тоже будут близкими к нулю. Для оптимизации поступлений необходимо найти правильный баланс между ставками настолько высокими, что они подавляют производственную деятельность, и настолько низкими, что сборы оказываются недостаточными. Но чтобы достичь этого баланса, следует больше узнать о том, как налоговая ставка связана с поступлениями.


Шаги в правильном направлении

Допустим, вы обсуждаете проблему со своей командой экономистов. Они понимают, о чем идет речь, и возвращаются в научно-исследовательскую лабораторию. Там они применяют средства, используемые ведущими учеными-экономистами всего мира: колбы, астролябии, колеса с бегающими хомячками и ивовые прутья для лозоходства, чтобы определить точную связь между ставкой налога и поступлениями.

Через какое-то время экономисты сообщают, что нашли функцию, связывающую ставку налога с поступлениями, и написали ее для вас на Python. Можно предположить, что функция выглядит примерно так:

import math

def revenue(tax):

    return(100 * (math.log(tax+1) - (tax - 0.2)**2 + 0.04))

Эта функция Python получает ставку налога в аргументе и возвращает числовой вывод. Сама функция хранится в переменной revenue. Вы запускаете Python для построения простого графика и вводите с консоли приведенную ниже программу. Как и в главе 1, мы воспользуемся модулем matplotlib ради функциональности построения графиков.

import matplotlib.pyplot as plt

xs = [x/1000 for x in range(1001)]

ys = [revenue(x) for x in xs]

plt.plot(xs,ys)

plt.title('Tax Rates and Revenue')

plt.xlabel('Tax Rate')

plt.ylabel('Revenue')

plt.show()

На графике приводятся налоговые поступления (в миллиардах денежных единиц вашей страны), которые ожидает получить ваша команда для всех ставок налога от 0 до 1 (где 1 соответствует 100 %-ной налоговой ставке). Если в вашей в настоящее время установлена ставка 70 %, то в код можно добавить две строки для нанесения этой точки на кривую:

import matplotlib.pyplot as plt

xs = [x/1000 for x in range(1001)]

ys = [revenue(x) for x in xs]

plt.plot(xs,ys)

current_rate = 0.7

plt.plot(current_rate,revenue(current_rate),'ro')

plt.title('Tax Rates and Revenue')

plt.xlabel('Tax Rate')

plt.ylabel('Revenue')

plt.show()

В итоге мы получаем простой график, как на рис. 3.1.

Рис. 3.1. Связь между ставкой налога и поступлениями; точка представляет текущее значение ставки

Согласно формуле экономистов, текущая ставка налога не обеспечивает максимальных поступлений в бюджет. Хотя простое визуальное изучение графика приблизительно показывает, какой уровень соответствует максимальным поступлениям, приближенная оценка вас не устраивает, и вы хотите найти более точное значение для оптимальной ставки налога. По графику видно, что любое повышение ставки от текущих 70 % приведет к снижению поступлений, а некоторое снижение текущей ставки должно повысить поступления, поэтому в данной ситуации максимизация поступлений требует снижения ставки налога.

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


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.