Методы Python для сокращения времени работы Алгоритм KTNS

Я пытался разработать алгоритм под названием «Сохраняйте инструмент как можно скорее, но во время моделирования я понял, что он требует слишком много времени для запуска».

Я хочу уменьшить время выполнения и проверить другие предыдущие вопросы о том, как ускорить кодирование на Python. Python медленнее, чем Java / C#? [закрыто] Я нашел несколько решений, но не знаю, как реализовать их в моем коде.

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

Здесь я прилагаю весь свой код. Если у вас есть предложения по его улучшению, пожалуйста, не стесняйтесь поделиться со мной.

import sets
import numpy
import copy
import time

J= {1: [6, 7],2: [2, 3], 3: [1, 6, 9], 4: [1, 5, 9], 5: [5, 8, 10], 6: [1, 3, 6, 8], 7: [5, 6, 8, 9], 8: [5, 7, 8], 9: [1, 4, 5, 8], 10: [1, 2, 4, 10]}

def KTNS(sigma=[10, 9, 4, 1, 6, 3, 7, 5, 2, 8], Jobs=J,  m=10 ,capacity=4 ):
    t0=time.time()
    Tools = {}
    Lin = {}
    n=len(sigma) 
    for i in range(1,m+1): 
        for e in sigma: 
            if i in Jobs[e]:
                Tools[i]=sets.Set([])

    count = 1
    available_tools=sets.Set()
    for e in sigma:
        for i in Jobs[e]:
            Tools[i].add(count)
            available_tools.add(i)
        count+=1
    Tin=copy.deepcopy(Tools)
    for e in Tin:
        Lin[e]=min(Tin[e])
    count=1
    J = numpy.array([0] *m)
    W = numpy.array([[0] * m] * n)
    while count<=len(sigma):
        for e in Tools:
            if len(available_tools)<capacity:
                reference=len(available_tools)
            else:
                reference=capacity
            while numpy.count_nonzero(J == 1) <reference: 
                min_value = min(Lin.itervalues())
                min_keys = [k for k in Lin if Lin[k] == min_value]
                temp = min_keys[0] #min(Lin, key=Lin.get)
                if min_value>count:
                    if len(min_keys)>=2:
                        if count==1:
                            J[temp - 1] = 1
                            Lin[temp] = '-'
                        else:
                            J0=W[count-2]
                            k=0
                            for elements in min_keys: #tested
                                if numpy.count_nonzero(J == 1) < reference:
                                    if J0[elements-1]==1:
                                        J[elements-1]=1
                                        Lin[elements]='-'
                                        k=1
                                    else:
                                        pass
                                else:
                                    pass
                            if k==0: 
                                J[temp - 1] = 1
                                Lin[temp] = '-'
                    else: 
                        J[temp - 1] = 1
                        Lin[temp] = '-'
                else:
                    J[temp-1]=1
                    Lin[temp] = '-'
            Tin[e].discard(count)
            for element in Tin:
                try:
                    Lin[element] = min(Tin[element])
                except ValueError:
                    Tin[element]=sets.Set([len(sigma)+1])
                    Lin[element]=len(sigma)+1
        W[count-1]=J
        J= numpy.array([0] *m)
        count+=1
    Cost=0
    for e in range(1,len(sigma)):
        temp=W[e]-W[e-1]
        temp[temp < 0] = 0
        Cost+=sum(temp)

    return Cost+capacity,time.time()-t0

Вы всерьез ожидаете, что кто-то изучит ваш код, выяснит, что он делает, и предложит улучшения?

zmbq 01.05.2018 18:16

Если вам нужен полный обзор рабочего кода, попробуйте codereview.stackexchange.com - но прочтите справочный центр перед тем, как публиковать, чтобы убедиться, что ваш вопрос там по теме!

Blorgbeard 01.05.2018 18:20

Также может помочь подробное объяснение алгоритма, который вы реализуете.

Blorgbeard 01.05.2018 18:21

Умножив время на 13000, я получу, что весь процесс занимает 65 секунд. Какое максимальное время занимает должен? Я согласен с Blorgbeard - в то время как многим людям неправильно говорят перейти на codereview, у вас есть полностью функционирующий код, на который вы хотите, чтобы люди посмотрели. Этот вопрос подойдет, просто убедитесь, что вы упомянули, что он размещен здесь. (Здесь это не не по теме, но, вероятно, там будет лучше встречено, поэтому я не голосую за закрытие.)

Scott Mermelstein 01.05.2018 18:21

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

Bert Kellerman 01.05.2018 18:22

@zmbq Я только просил кое-какие знания, потому что я пробовал несколько функций, и они не работали. Я не хотел, чтобы вы выясняли весь код и исправляли его, только я хотел знать методы или предложения. Если правильное место - это обзор cody, я отправлю его туда, но я подумал, что здесь может поместиться.

A.Piquer 01.05.2018 19:17
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
40
1

Ответы 1

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

Похоже, вы могли бы просто сделать списками Tools, Lin и Tin, например Lin = [] вместо Lin = {}, и я ожидаю, что вы увидите резкое улучшение производительности.

Вы знаете размеры ваших 3 словарей, поэтому просто инициализируйте их до нужного вам размера. Создайте Lin и Tools следующим образом:

Lin = [None] * m+1
Tools = [None] * m+1
Tin = [None] * m+1

Это создаст список из m + 1 элементов (это то, что вы получите с вашим циклом от 1 до m + 1). Поскольку вы выполняете индексацию на основе 1, она оставляет пустое место в Lin [0], Tools [0] и т. д., Но тогда вы сможете получить доступ к Lin [1] - Lin [10], как и вы » ре в настоящее время занимаюсь. Простой пример, который вы можете попробовать сами:

python3 -m timeit -s 'foo = [x for x in range(10000)]' 'foo[500]'

100000000 loops, best of 3: 0.0164 usec per loop

python3 -m timeit -s 'foo = {x: x for x in range(10000)}' 'foo[500]'

10000000 loops, best of 3: 0.0254 usec per loop

Просто изменив словари на список, вы получите почти двукратное улучшение. Ваша 65-секундная задача теперь займет около 35 секунд.

Кстати, ознакомьтесь с вики-страницей python для советы по увеличению скорости, включая множество ссылок о том, как профилировать вашу функцию.

И как мне приспособить использование словарей к списку? В настоящее время я использую словари, потому что они довольно просты для доступа к информации и ее обновления. Если я использую список и удаляю некоторые элементы, индекс будет изменен, и я не узнаю. Любая идея?

A.Piquer 01.05.2018 19:39

Помните, что списки также являются динамическими, и вы можете добавить push в индекс, добавить в конец и конкретные индексы del, хотя я не вижу нигде в вашем коде, который вам может понадобиться. Вы никогда не добавляете Lin, Tin или Tools, хотя вы добавляете их в набор, который вы помещаете в Tools [i]. Просто создайте свой список. Я немного поправил свой ответ, чтобы прояснить это. Удачи!

Scott Mermelstein 01.05.2018 20:09

Другие вопросы по теме