假设阅读书籍时有六种问题需要处理,
我将详细说明如下:
while True:
if encounter A :
handle A
#during handling the problem, it might spawn new problems of
#A, B, C, D, E,
produce (A,B..E or null)
continue
if B occurs:
handle B
#during hanlding the problem, it might spwan new problems
#A, B, C, D, E,
produce (A,B..E or null)
continue
if C happens:
handle C
produce (A,B..E or null)
continue
...
if there are no problmes:
break
假设我有3个问题,
上面的程序可能会在第一个程序上无限循环而从不接触第二个程序。
举一个例子,我正在读一本书,
'问题A'被定义为遇到'新词',处理它是查找词典
抬头的时候,我可能会再来一个新词,另一个词和另一个词
在这种情况下,我永远不会读完一本书的一句话。
作为解决方案,
我介绍了一个容器来收集问题,对它们进行值加权然后确定执行哪一个。
def solve_problems(problems)
problem_backet = list(problems)
while True:
if problem_backet not is null:
#value-weighted all the problem
#and determine one to implement
value_weight problems
problem = x
if problem == A:
handle A
problem_backet.append(new_problem)
continue
if problem == B:
handle B
problem_backet.append(new_problem)
continue
...
if problem_backet is null:
return
我试着寻求灵感并提高效率。
def solve_problems(problems):
global problem_backet
problem_backet = list(problems)
value_weight problems
problem = x
if problem == A:
handle A
problem_backet.append(new_problem)
solve_problems(problem_backet)
if problem == B:
handle B
problem_backet.append(new_problem)
solve_problems(problem_backet)
if problem == C:
handle C
problem_backet.append(new_problem)
solve_problems(problem_backet)
...
if problem_backet is null:
return
同样,value_weighted进程耗费巨大的努力和时间。
如何在正确的算法中解决这样的问题?
答案 0 :(得分:1)
你可以做几件事来解决这个问题。
其中之一是在机器学习风格中设置“max-iterations”或“max-effort”的值,您可以投资于阅读书籍。因此,您将仅执行(处理)多个操作,直到达到限制。此解决方案将如下所示:
while(effortRemaining > 0){
# Do your actions
}
根据您需要定义的某个指标,您所执行的操作应该是报告更多优势/更少工作量的操作。
当您执行某个操作(句柄)时,您会从effortRemaining
中减去该操作的成本/工作量,然后继续您的流程。
答案 1 :(得分:1)
'问题A'定义为遇到一个新单词',处理它是查找字典。 抬头时,我可能会遇到另一个新词,另一个词。 在这种情况下,我永远不会读完一本书中的一句话。
看起来它最终会最终读取句子,因为新单词的数量受字典大小的限制。一般来说,这对我来说听起来不错,除非有其他一些未明确提及的限制,比如在有限的时间内完成句子阅读。
如何在正确的算法中解决这样的问题?
好吧,如果没有"有限的时间"限制,你原来的算法几乎是完美的。为了使整体性能更好,我们可能首先处理所有问题A
,然后转移到B
,依此类推。它将增加我们算法的数据局部性和整体性能。
但是如果有一个有限的时间"限制,我们最终可以阅读完整的句子(没有完全理解)或最终阅读部分句子(完全理解那部分)或介于两者之间(如@Lauro Bravar建议)。
从上面的示例中我们不清楚我们如何处理value_weight
,但这类问题的正确名称是优先级排队。有各种算法和实现,请查看维基百科页面了解详细信息:https://en.wikipedia.org/wiki/Priority_queue
答案 2 :(得分:0)
你已经有了算法(在Andriy的帮助下获得了优先级队列),但你缺乏设计。当我看到你的多个if
检查问题的类型时,我认为是多态的。
为什么不尝试OOP?您有两个要定义的对象:问题和优先级队列。幸运的是,优先级队列在heapq
模块中定义。让我们关注这个问题:
在其核心定义中,它被处理并可能与其他问题进行比较(这或多或少是紧急的)。请注意,在OOP原则的指导下,我没有谈到问题的结构或实现,
但只有问题的功能:
class Problem()
def handle(self, some args): # we may need a dictionary, a database connection, ...
...
def compare(self, other):
...
但是你说当处理问题时,它可能会给队列增加新的问题。因此,让我们为handle
的定义添加精度:
def handle(self, queue, some args): # we still may need a dictionary, a database connection, ...
...
在Python中,compare
是名为__lt__
的{{3}},其中"低于"。 (你有其他特殊的比较方法,但__lt__
就足够了。)
这是一个基本的实现示例:
class Problem():
def __init__(self, name, weight):
self.__name = name
self.__weight = weight
def handle(self, queue):
print ("handle the problem {}".format(self))
while random.random() > 0.75: # randomly add new problems for the example
new_problem = Problem(name*2, random.randint(0, 100))
print ("-> Add the problem {} to the queue".format(new_problem))
heapq.heappush(queue, new_problem) # add the problem to the queue
def __lt__(self, other):
return self.__weight > other.__weight # note the >
def __repr__(self): # to show in lists
return "Problem({}, {})".format(self.__name, self.__weight)
等待!为什么"低于"和>
?这是因为模块heapq
是最小堆:它首先返回最小元素。因此,我们将大权重定义为小于权重。
现在,我们可以为示例构建一个包含伪数据的开始队列:
queue = []
for name in ["foo", "bar", "baz"]:
problem = Problem(name, random.randint(0, 100))
heapq.heappush(queue, problem) # add the problem to the queue
运行主循环:
while queue:
print ("Current queue", queue)
problem = heapq.heappop(queue) # the problem with the max weight in O(lg n)
problem.handle(queue)
我想你能够继承Problem
类来表示你可能想要处理的各种问题。