Главная страница

Разработка программного продукта для решения прикладных задач. Тема курсовой работы Разработка программного продукта для решения прикладных задач


Скачать 1.19 Mb.
НазваниеТема курсовой работы Разработка программного продукта для решения прикладных задач
АнкорРазработка программного продукта для решения прикладных задач
Дата06.03.2023
Размер1.19 Mb.
Формат файлаdocx
Имя файлаOtchet.docx
ТипКурсовая
#971818
страница3 из 3
1   2   3

Задание №4

import copy
from tkinter import *

'''
Данная программа реализует метод решения
модифицированной задачи о Ханойских башняхю
Для визуализации используется библиотека tkinter.
Автор: Брянцев Вячеслав Павлович
Дата написания программы: 19.05.2021
'''

global iterXY
win = Tk()
figure = Canvas(win, width=1400, height=900)
figure.pack()
win.title("Ханойские башни. Модифицированный алгоритм")
win.geometry("1400x900")

# Определяем переменные
wd = ''
mem = []
cont = 0
disks = [2, 0, 3, 0, 5, 1, 0, 7]
iterXY = 204967
max_iterXY = 409934

# цвет для дисков
colors = {1: 'yellow', 2: 'white', 3: 'orange', 4: 'green',
5: 'blue', 6: 'purple', 7: 'pink', 8: 'red',
9: 'yellow', 10: 'white', 11: 'orange', 12: 'green',
13: 'blue', 14: 'purple', 15: 'pink', 16: 'red',
17: 'yellow', 18: 'white', 19: 'orange', 20: 'green',
21: 'blue', 22: 'purple', 23: 'pink', 24: 'red',
25: 'yellow', 26: 'white', 27: 'orange', 28: 'green',
29: 'blue', 30: 'purple', 31: 'pink', 32: 'red',
33: 'yellow', 34: 'white', 35: 'orange', 36: 'green',
37: 'blue', 38: 'purple', 39: 'pink', 40: 'red',
41: 'yellow', 42: 'white', 43: 'orange', 44: 'green',
45: 'blue', 46: 'purple', 47: 'pink', 48: 'red',
49: 'yellow', 50: 'white', 51: 'orange', 52: 'green',
53: 'blue', 54: 'purple', 55: 'pink', 56: 'red',
57: 'yellow', 58: 'white', 59: 'orange', 60: 'green',
61: 'blue', 62: 'purple', 63: 'pink', 64: 'red',
65: 'yellow', 66: 'white', 67: 'orange', 68: 'green',
69: 'blue', 70: 'purple', 71: 'pink', 72: 'red',
73: 'yellow', 74: 'white', 75: 'orange', 76: 'green',
77: 'blue', 78: 'purple', 79: 'pink', 80: 'red',
81: 'yellow', 82: 'white', 83: 'orange', 84: 'green',
85: 'blue', 86: 'purple', 87: 'pink', 88: 'red', 89: 'yellow'}

# задаем размеры дисков
for i in range(len(disks)):
mem.append(mem[:0])
if disks[len(disks) - (i + 1)] != 0:
for j in range(int(disks[-1 - i])):
mem[i].append(((len(disks) -
(i + 1)) * 10 + 10) + (int((disks[-1 - i])) - j))
else:
mem[i].clear()


def move(b1, b2):
global cont
cont += 1
b2.append(b1.pop())


# функции для осуществления переноса дисков по шпинделям
def m_even(b1, b2, b3, cont_disk):
while len(b1) + len(b3) < cont_disk or \
(''.join(str(b3)).find(''.join(str(wd)[1:-1]))) == -1:
if cont < iterXY:
if len(b1) + len(b3) == cont_disk and \
(''.join(str(b3)).find(''.join(str(wd)[1:-1]))) >= 0:
break
else:
if (len(b1) != 0 and len(b2) == 0) or \
(len(b1) != 0 and b2[-1] > b1[-1]):
move(b1, b2)
else:
move(b2, b1)
else:
break
if cont < iterXY:
if len(b1) + len(b3) == cont_disk and \
(''.join(str(b3)).find(''.join(str(wd)[1:-1]))) >= 0:
break
else:
if (len(b1) != 0 and len(b3) == 0) or \
(len(b1) != 0 and b3[-1] > b1[-1]):
move(b1, b3)
else:
move(b3, b1)
else:
break
if cont < iterXY:
if len(b1) + len(b3) == cont_disk and \
(''.join(str(b3)).find(''.join(str(wd)[1:-1]))) >= 0:
break
else:
if (len(b2) != 0 and len(b3) == 0) or \
(len(b2) != 0 and b3[-1] > b2[-1]):
move(b2, b3)
else:
move(b3, b2)
else:
break


def m_odd(b1, b2, b3, cont_disk):
while cont < iterXY or len(b1) + len(b3) < cont_disk or \
(''.join(str(b3)).find(''.join(str(wd)[1:-1]))) == -1:
if cont < iterXY:
if len(b1) + len(b3) == cont_disk and \
(''.join(str(b3)).find(''.join(str(wd)[1:-1]))) >= 0:
break
else:
if (len(b1) != 0 and len(b3) == 0) or \
(len(b1) != 0 and b3[-1] > b1[-1]):
move(b1, b3)
else:
move(b3, b1)
else:
break
if cont < iterXY:
if len(b1) + len(b3) == cont_disk and \
(''.join(str(b3)).find(''.join(str(wd)[1:-1]))) >= 0:
break
else:
if (len(b1) != 0 and len(b2) == 0) or \
(len(b1) != 0 and b2[-1] > b1[-1]):
move(b1, b2)
else:
move(b2, b1)
else:
break
if cont < iterXY:
if len(b1) + len(b3) == cont_disk and \
(''.join(str(b3)).find(''.join(str(wd)[1:-1]))) >= 0:
break
else:
if (len(b2) != 0 and len(b3) == 0) or \
(len(b2) != 0 and b3[-1] > b2[-1]):
move(b2, b3)
else:
move(b3, b2)
else:
break


def move_disks(b1, b2, b3, cont_disk):
if len(b1) != 0:
if len(b1) % 2 != 0:
m_odd(b1, b2, b3, cont_disk)
else:
m_even(b1, b2, b3, cont_disk)


# Отрисовка шпинделей
def draw_beams():
xt = 115
for k in range(8):
figure.create_rectangle(xt, 120, xt + 5, 500, fill='grey', width=1)
label1 = Label(text=str(8 - k), font="Arial 14")
label1.place(x=xt, y=530)
xt += 170


# Отрисовка перемещения дисков
def draw_disks():
x_0 = -50
figure.delete("all")
draw_beams()
for n in range(len(disks)):
x_0 = x_0 + 170
y_0 = 500
for m in range(len(mem[n])):
figure.create_rectangle(x_0, y_0, x_0 + mem[n][0 + m], y_0 - 10,
fill=colors[mem[n][m]], width=0)
figure.create_rectangle(x_0, y_0, x_0 - mem[n][0 + m], y_0 - 10,
fill=colors[mem[n][m]], width=0)
y_0 = y_0 - 10
figure.create_text(x_0, y_0 + 4, text=str(mem[n][m]))

label_cont = Label(text="Количество итераций: " + str(cont), font="Times 12")
label_cont.place(x=600, y=40)


# Функция, осуществляющая передвижение дисков.
def init_move():
global wd, mem, i
for i in range(len(disks) - 2):
if i == len(disks) - 3:
wd = mem[i + 2][:]
move_disks(mem[i + 2], mem[i], mem[i + 1],
(len(mem[i + 1]) + len(mem[i + 2])))
wd = mem[i + 1][:]
move_disks(mem[i + 1], mem[i + 2], mem[i],
(len(mem[i]) + len(mem[i + 1])))
wd = mem[i][:]
move_disks(mem[i], mem[i + 1], mem[i + 2],
(len(mem[i]) + len(mem[i + 2])))
else:
wd = mem[i + 2][:]
move_disks(mem[i + 2], mem[i], mem[i + 1],
(len(mem[i + 1]) + len(mem[i + 2])))
wd = mem[i + 1][:]
move_disks(mem[i + 1], mem[i + 2], mem[i],
(len(mem[i]) + len(mem[i + 1])))
wd = mem[i][:]
move_disks(mem[i], mem[i + 2], mem[i + 1],
(len(mem[i]) + len(mem[i + 1])))
draw_disks()


def start_m():
global mem
mem = [[87, 86, 85, 84, 83, 82, 81], [], [61], [55, 54, 53, 52, 51], [], [33, 32, 31], [], [12, 11]]
x_0 = -50
figure.delete("all")
draw_beams()
for v in range(len(disks)):
x_0 = x_0 + 170
y_0 = 500
for w in range(len(mem[v])):
figure.create_rectangle(x_0, y_0, x_0 + mem[v][0 + w], y_0 - 10,
fill=colors[mem[v][w]], width=0)
figure.create_rectangle(x_0, y_0, x_0 - mem[v][0 + w], y_0 - 10,
fill=colors[mem[v][w]], width=0)
y_0 = y_0 - 10
figure.create_text(x_0, y_0 + 4, text=str(mem[v][w]))
label1 = Label(text="Количество итераций: 0", font="Arial 14")
label1.place(x=600, y=40)

start_m()

def end_move():
last_p = [[], [], [], [], [], [], [], []]
mem = [[87, 86, 85, 84, 83, 82, 81], [], [61], [55, 54, 53, 52, 51], [], [33, 32, 31], [], [12, 11]]
for g in mem:
last_p[7].extend(g)
x_0 = -50
figure.delete("all")
draw_beams()
for s in range(len(disks)):
x_0 = x_0 + 170
y_0 = 500
for q in range(len(last_p[s])):
figure.create_rectangle(x_0, y_0, x_0 + last_p[s][0 + q], y_0 - 10,
fill=colors[last_p[s][q]], width=0)
figure.create_rectangle(x_0, y_0, x_0 - last_p[s][0 + q], y_0 - 10,
fill=colors[last_p[s][q]], width=0)
y_0 = y_0 - 10
figure.create_text(x_0, y_0 + 4, text=str(last_p[s][q]))

label_cont = Label(text="Количество итераций: 409934", font="Arial 12")
label_cont.place(x=600, y=40)


# Функция, осуществляющая перенос дисков исходя из номера итерации.
def av_move(p):
global max_iterXY, iterXY
global cont, mem

disk_fly = 0
spindles_fly_one = 0
mem = [[87, 86, 85, 84, 83, 82, 81], [], [61], [55, 54, 53, 52, 51], [], [33, 32, 31], [], [12, 11]]
cont = 0
iterXY = 0
iterXY = float(eval("entry{}".format(p)).get()) * max_iterXY / 100 # Получение номера итерации.
if iterXY > 409934:
iterXY = max_iterXY
if iterXY % 1 == 0.0: # Если итерация цельная, то запускает функцию init_move без изменений
init_move()
else: # Запускает функцию init_move(), копирует расположение дисков и снова её запускает на +1 итерацию.
init_move()
old_mem = copy.deepcopy(mem)
iterXY += 1
init_move()

# Если элемент старого списка совпадает с элементом нового, то пропуск.
# Иначе - найти, какой именно элемент отделился, убрать его из нового списка и произвести отрисовку
# уже без него.
for d in range(len(mem)):
if old_mem[j] == mem[j]:
pass
else:
if len(old_mem[j]) < len(mem[j]): # Слева направо
disk_fly = copy.deepcopy(mem[j].pop())
spindles_fly_one = copy.deepcopy(j)
init_move()

elif len(old_mem[j]) > len(mem[j]): # Справа налево
spindles_fly_two = copy.deepcopy(j)
old_mem[j].pop()
mem = old_mem
init_move()
draw_disk(disk_fly, spindles_fly_one, spindles_fly_two) # Запуск отрисовки диска в воздухе


# Функция, осуществляющая отрисовку диска в воздухе.
def draw_disk(disk, spindle1, spindle2):
figure.delete("all")
draw_beams()
draw_disks()
y0 = 100
y1 = y0 - 10

list_sizes = []
xt = 115
for d in range(8):
list_sizes.append(xt)
xt += 170

between = (list_sizes[spindle1] + list_sizes[spindle2]) / 2
x0 = between - disk
x1 = between + disk

figure.create_rectangle(x0, y0, x1, y1, fill=colors[disk], width=0)
figure.create_text(x0 + disk, y0 - 6, text=str(disk))


# Интерфейс окна
draw_beams()

stButton = Button(win, text="Начало", command=start_m, font="Arial 14")
stButton.place(x=250, y=630, width=150)

eButton = Button(win, text="Окончание", command=end_move, font="Arial 14")
eButton.place(x=950, y=630, width=150)

iterationLabel = Label(text="Количество итераций: " + str(0), font="Arial 14")
iterationLabel.place(x=600, y=40)

onButton = Button(text=" П.1 ", command=lambda: av_move(1))
onButton.place(x=500, y=680, width=50)

twButton = Button(text=" П.2 ", command=lambda: av_move(2))
twButton.place(x=600, y=680, width=50)

thButton = Button(text=" П.3 ", command=lambda: av_move(3))
thButton.place(x=700, y=680, width=50)

fButton = Button(text=" П.4 ", command=lambda: av_move(4))
fButton.place(x=800, y=680, width=50)

entry1 = Entry(font="Arial 14")
entry1.place(x=500, y=630, width=50)

entry2 = Entry(font="Arial 14")
entry2.place(x=600, y=630, width=50)

entry3 = Entry(font="Arial 14")
entry3.place(x=700, y=630, width=50)

entry4 = Entry(font="Arial 14")
entry4.place(x=800, y=630, width=50)

win.mainloop()

Приложение Б: Листинг GUI заданий

Задание №2



Задание №3









Задание №4

1   2   3


написать администратору сайта