Рассказы о математике с примерами на языках Python и C - [8]

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

. Действительно, для квадрата Дюрера M(4) = 34, что можно посчитать на картине. Для квадратов разной размерности суммы равны соответственно: M(3) = 15, M(4) = 34, M(5) = 65, M(6) = 111, M(7) = 175, M(8) = 260, M(9) = 369, M(10) = 505.

Напишем программу для построения магических квадратов размерности N. Первый подход будет «в лоб», напрямую. Создадим массив, содержащий все числа от 1 до N>2 и получим все возможные перестановки этого массива. Их число довольно-таки велико, и составляет 1 * 2 * .. * N = N! вариантов. Также для каждого массива необходимо проверить, является ли он «магическим», т. е. выполняется ли требование равенства сумм.

Для получения всех перестановок воспользуемся алгоритмом, описанным здесь — https://prog-cpp.ru/permutation/.

Код программы приведен ниже:

>def swap(arr, i, j):

>    arr[i], arr[j] = arr[j], arr[i]


>def next_set(arr, n):

>    j = n - 2

>    while j != -1 and arr[j] >= arr[j + 1]: j -= 1


>    if j == -1:

>        return False

>    k = n - 1

>    while arr[j] >= arr[k]: k -= 1

>    swap(arr, j, k)

>    l = j + 1

>    r = n – 1

>    while l < r:

>        swap(arr, l, r)

>        l += 1

>        r -= 1

>    return True


>def is_magic(arr, n):

>    for i in range(0, n):

>        sum1 = 0

>        sum2 = 0

>        sum3 = 0

>        sum4 = 0

>    for j in range(0, n):

>        sum1 += arr[i * n + j]

>        sum2 += arr[j * n + i]

>        sum3 += arr[j * n + j]

>        sum4 += arr[(n – j - 1) * n + j]

>    if sum1 != sum2 or sum1 != sum3 or sum1 != sum4 or sum2 != sum3 or sum2 != sum4 or sum3 != sum4:

>        return False

>return True


>def show_squares(n):

>    N = n * n

>    arr = [i + 1 for i in range(N)]


>    cnt = 0

>    while next_set(arr, N):

>        if is_magic(arr, n):

>            print(arr)

>            cnt += 1


>    return cnt


># Требуемая размерность

>cnt = show_squares(3)

>print("Число вариантов:", cnt)

Программа выдала 8 вариантов для N = 3, время вычисления составило 2 секунды:


[2, 7, 6, 9, 5, 1, 4, 3, 8][6, 1, 8, 7, 5, 3, 2, 9, 4]
[2, 9, 4, 7, 5, 3, 6, 1, 8][6, 7, 2, 1, 5, 9, 8, 3, 4]
[4, 3, 8, 9, 5, 1, 2, 7, 6][8, 1, 6, 3, 5, 7, 4, 9, 2]
[4, 9, 2, 3, 5, 7, 8, 1, 6][8, 3, 4, 1, 5, 9, 6, 7, 2]

Действительно, как известно, существует только 1 магический квадрат 3x3:




Остальные являются лишь его поворотами или отражениями (очевидно что при повороте квадрата его свойства не изменятся).

Теперь попробуем вывести квадраты 4х4. Запускаем программу… и ничего не видим. Как было сказано выше, число вариантов перебора для 16 цифр равняется 16! или 20922789888000 вариантов. На моем компьютере полный перебор такого количества занял бы 1089 дней!

Однако посмотрим на магический квадрат еще раз:




Суммы всех элементов по горизонтали и вертикали равны. Из этого мы легко можем записать равенство его членов:

x11 + x12 + x13 + x14 = x21 + x22 + x23 + x24 x11 + x12 + x13 + x14 = x14 + x24 + x34 + x44 x11 + x12 + x13 + x14 = x13 + x23 + x33 + x43 x11 + x12 + x13 + x14 = x12 + x22 + x32 + x42 x11 + x12 + x13 + x14 = x11 + x21 + x33 + x44 x11 + x12 + x13 + x14 = x31 + x32 + x33 + x34

И наконец, общая сумма: т. к. квадрат заполнен числами 1..16, то если сложить все 4 строки квадрата, то получаем 4S = 1 + .. + 16 = 136, т. е. S = 34 (что соответствует приведенной в начале главы формуле).

Это значит, что мы легко можем выразить последние элементы через предыдущие:

x14 = S - x11 - x12 - x13

x24 = S - x21 - x22 - x23

x34 = S - x31 - x32 - x33

x41 = S - x11 - x21 - x31

x42 = S - x12 - x22 - x32

x43 = S - x13 - x23 - x33

x44 = S + x14 - x14 - x24 - x34

Что это дает? Очень многое. Вместо перебора 16 вариантов суммарным количеством 16! = 20922789888000 мы должны перебрать лишь 9 вариантов, что дает 9! = 362880 вариантов, т. е. в 57657600 раз меньше! Как нетрудно догадаться, мы фактически выразили крайние строки квадрата через соседние, т. е. уменьшили размерность поиска с 4х4 до 3х3. Это же правило будет действовать и для квадратов большей диагонали.

Обновленная программа выглядит более громоздко (в ней также добавлены проверки на ненулевые значения и проверки на уникальность элементов), зато расчет происходит в разы быстрее. Здесь также используется возможность работы со множествами в языке Python, что легко позволяет делать перебор нужных цифр в цикле:

set(range(1, 16 + 1)) - множество чисел [1..16]

set(range(1, 16 + 1)) - set([x11]) - множество чисел [1..16] за исключением x11.

Также добавлена простая проверка на минимальность суммы: очевидно, что сумма всех элементов не может быть меньше чем 16 + 1 + 2 + 3 = 22.

>digits = set(range(1,16+1))

>cnt = 0

>for x11 in digits:

>    for x12 in digits - set([x11]):

>        for x13 in digits - set([x11, x12]):

>            for x14 in digits - set([x11, x12, x13]):

>                s = x11 + x12 + x13 + x14

>                    if s < 22: continue

>                    for x21 in digits - set([x11, x12, x13, x14]):

>                        for x22 in digits - set([x11, x12, x13, x14, x21]):

>                    for x23 in digits - set([x11, x12, x13, x14, x21, x22]):

>                        x24 = s - x21 - x22 - x23

>                        if x24 <= 0 or x24 in [x11, x12, x13, x14, x21, x22, x23]: continue


Рекомендуем почитать
В поисках бесконечности

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


Математика на ходу

Как приобщить ребенка к математике и даже сделать так, чтобы он ее полюбил? Замечательные британские популяризаторы науки Роб Истуэй и Майк Эскью нашли веселый и легкий путь к детскому сердцу, превратив страшное пугало – математику – в серию увлекательных игр для детей от 4 до 14 лет. Пусть ваш ребенок исподволь овладевает математической премудростью, играя изо дня в день в угадайку, числовые прятки, двадцаточку и зеленую волну. Вы сможете играть за столом, в очереди к врачу, в магазине, на прогулке, используя подручный счетный материал: машины на стоянке, товары на полках супермаркета, мотоциклистов на дороге… И конечно, ничто не мешает вам переиначивать придуманные авторами математические забавы на свой лад, приспосабливая их ко вкусам и потребностям собственных детей.


Значимые фигуры

Несмотря на загадочное происхождение отдельных своих элементов, математика не рождается в вакууме: ее создают люди. Некоторые из этих людей демонстрируют поразительную оригинальность и ясность ума. Именно им мы обязаны великими прорывными открытиями, именно их называем пионерами, первопроходцами, значимыми фигурами математики. Иэн Стюарт описывает открытия и раскрывает перед нами судьбы 25 величайших математиков в истории – от Архимеда до Уильяма Тёрстона. Каждый из этих потрясающих людей из разных уголков мира внес решающий вклад в развитие своей области математики.


Квантовый оптоэлектронный генератор

В книге развита теория квантового оптоэлектронного генератора (ОЭГ). Предложена модель ОЭГ на базе полуклассических уравнений лазера. При анализе доказано, что главным источником шума в ОЭГ является спонтанный шум лазера, обусловленный квантовой природой. Приводятся схемы и экспериментальные результаты исследования малошумящего ОЭГ, предназначенного для применения в различных областях военно-космической сферы.


Флатландия. Сферландия

Произведения Э. Эбботта и Д. Бюргера едины по своей тематике. Авторы в увлекательной форме с неизменным юмором вводят читателя в русло важных геометрических идей, таких, как размерность, связность, кривизна, демонстрируя абстрактные объекты в различных «житейских» ситуациях. Книга дополнена научно-популярными статьями о четвертом измерении. Ее с интересом и пользой прочтут все любители занимательной математики.


Стратегии решения математических задач

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