Я в python'e не силен, так как только не давно его изучаю. Нужна Ваша помоoь по оптимизации кода, так каr моя программа считает около 11 минут, а по хорошему должна около 1-2 минут. Принимаю все возможные варианты, и очень прошу Вас помочь пожалуйста! Заранее спасибо.
from itertools import groupby
from collections import Counter
import sqlite3
db = sqlite3.connect("D:\providers.db")
#---------------------------------Все записи-----------------------------------
cursor1 = db.cursor()
cursor1.execute("SELECT provider, geography FROM incomes")
#------------------------------------------------------------------------------
print("Выполняется составление транзакций, подождите...")
#--------------------------------ТРАНЗАКЦИИ------------------------------------
def CompilationTransaction():
database = cursor1.fetchall()
result = list()
for i, j in groupby(sorted(database, key = lambda x: x[0]), lambda x: x[0]):
result.append(list(j))
return result
def CompilationTransactionGeography():
result = list()
for ElemTrans in CompilationTransaction():
result.append(list(map(lambda x: x[1], ElemTrans)))
return result
#------------------------------------------------------------------------------
class Occurrences:
def __init__ (self, Clusters, Transaction):
self.C = Clusters
self.t = Transaction
#--------------Вхождение некоторого объекта в кластер(Вариант 2)---------------
def Occ(self):
ind = 0
for ElemC in self.C:
if ElemC.count(self.t):
ind = (self.C).index(ElemC)
break
self.resO = ind
#------------------------------------------------------------------------------
class SizeOrWidthCluster:
def __init__ (self, Cluster):
self.C = Cluster
#-------------------------------Размер кластера--------------------------------
def SizeC(self):
var = 0
for ElemC in self.C:
var += len(ElemC)
self.resS = var
#-----Подсчет уникальных элементов в заданном кластере(Ширина кластера)--------
def WidthC(self):
var = 0
j = 0
for ElemC in self.C:
var = Counter(ElemC)
j += len(var.keys())
self.resW = j
#------------------------------------------------------------------------------
class TransactionAddOrRemov:
def __init__(self, Clusters, Transaction, r):
self.C = Clusters
self.t = Transaction
self.r = r
#-----------------------------Добавление транзакции----------------------------
def TransactionAdd(self):
k = 0
S = SizeOrWidthCluster(self.C) #размер кластера
S.SizeC()
N = len(self.C) #Количество транзакций в кластере
W = SizeOrWidthCluster(self.C) #Количество уникальных элементов География(Ширина кластера)
W.WidthC()
Snew = S.resS + len(self.t)
Nnew = N + 1
Wnew = W.resW
for ElemC in self.C:
k += len(list(set(self.t) & set(ElemC)))
if (len(self.t) >= k):
Wnew = Wnew + (len(self.t) - k)
self.Tadd = (Snew * Nnew / (Wnew ** self.r)) - (S.resS * N / (W.resW ** self.r))
#-----------------------------Удаление транзакции------------------------------
def TransactionRemov(self):
k = 0
l = 0
S = SizeOrWidthCluster(self.C) #размер кластера
S.SizeC()
N = len(self.C) #Количество транзакций в кластере
W = SizeOrWidthCluster(self.C) #Количество уникальных элементов География(Ширина кластера)
W.WidthC()
Snew = S.resS - len(self.t)
Nnew = N - 1
Wnew = W.resW
if (len(self.C) <= 1):
self.Trem = -(S.resS * N / (W.resW ** self.r))
else:
for ElemC in self.C:
if (ElemC != self.t):
k += len(list(set(self.t) & set(ElemC)))
l += 1
if (len(self.t) >= k) and (l != 0):
Wnew = Wnew - (len(self.t) - k)
self.Trem = (Snew * Nnew / (Wnew ** self.r)) - (S.resS * N / (W.resW ** self.r))
class Clope:
def __init__ (self, Clusters, Transactions, r):
self.C = Clusters
self.t = Transactions
self.r = r
def Algoritm(self):
#-----------------------------ЧАСТЬ 1 - ИНИЦИАЛИЗАЦИЯ--------------------------
AddSpisok = list()
TransactionCopy = list()
TransactionCopy = self.t.copy()
AddSpisok.append(TransactionCopy[0]) #Добавляем 1-ую транзакцию в не основной, пустой кластер
(self.C).append(list(AddSpisok)) #Добавляем не основной(не пустой) кластер в основной кластер
TransactionCopy.pop(0)
for ElemTC in TransactionCopy: #Пробегаем по всем транзакциям
max_TC = 0
AddSpisok.clear()
for ElemC in self.C: #Пробегаем по всем класерам из мн-ва С
tadd = TransactionAddOrRemov(ElemC, ElemTC, self.r)
tadd.TransactionAdd()
if (tadd.Tadd > float(max_TC)):
max_TC = tadd.Tadd
NC = (self.C).index(ElemC)
if max_TC == 0:
AddSpisok.append(ElemTC)
(self.C).append(list(AddSpisok))
else:
self.C[NC].append(ElemTC)
f = open('Otchet1.txt', 'w')
for ElemC in self.C:
f.write(str(len(ElemC))+'\n')
f.write(str(ElemC)+'\n'+'\n')
f.close()
#-------------------------------ЧАСТЬ 2 - ИТЕРАЦИИ-----------------------------
print("-> Выполнена первая часть алгоритма: ИНИЦИАЛИЗАЦИЯ!")
for ElemT in self.t:
max_T = 0
ent_T = Occurrences(self.C, ElemT) #Индекс кластера, в кот. лежит данная транзакция
ent_T.Occ()
tr = TransactionAddOrRemov(self.C[ent_T.resO], ElemT, self.r)
tr.TransactionRemov()
for ElemC in self.C:
tadd = TransactionAddOrRemov(ElemC, ElemT, self.r)
tadd.TransactionAdd()
if (ElemC != self.C[ent_T.resO]) and (tadd.Tadd + tr.Trem > float(max_T)):
max_T = tadd.Tadd + tr.Trem
NC = (self.C).index(ElemC)
if max_T > 0:
self.C[NC].append(ElemT)
for ElemCent in self.C[ent_T.resO]:
if ElemCent == ElemT:
self.C[ent_T.resO].pop(self.C[ent_T.resO].index(ElemCent))
break
if len(self.C[ent_T.resO]) == 0:
self.C.pop(self.C.index(self.C[ent_T.resO])) #удалить пустой кластер
#------------------------------------------------------------------------------
def main():
Cluster = list()
Transactions = list()
Transactions = CompilationTransactionGeography()
r = int(input("Введите коэффициент отталкивания (целое число) r > 1: "))
print("Производятся вычисления, подождите...")
res = Clope(Cluster, Transactions, r)
res.Algoritm()
f = open('Otchet2.txt', 'w')
for ElemC in Cluster:
f.write(str(len(ElemC))+'\n')
f.write(str(ElemC)+'\n'+'\n')
f.close()
print("Вычисления окончены!")
return res
main()
db.close()