算法探查器
需求
编写一个程序,允许程序员探查不同的算法
分析
探查器应该允许程序员在数字列表上运行排序算法。探查器可以记录算法的运行时间、比较的次数以及交换的次数。此外,当算法交换两个值的时候,探查器可以输出列表的记录。程序员可以给探查器提供自己的数字列表,或者要求探查器生成一个给定大小的、随机排序的数字列表。程序员可以要求列表包含不同的数字,或者允许列表包含重复的值。为了便于使用,探查器允许程序员在算法运行之前通过选项来指定大多数的功能。默认的行为是在10个唯一数字的、随机排序的列表上运行该算法,并且记录时间、比较和交换的次数。
配置一个要进行探查的排序算法的步骤如下:
- 定义一个排序函数,并且在排序算法的函数头中包含另一个参数,该参数是一个Profiler对象。
- 在排序算法的代码中,在设计统计、比较和交换的地方,用该Profiler对象运行comparison()和exchange()方法。
设计
程序员使用两个模块:
- Profiler——该模块定义了Profiler类
- Algorithms——该模块定义了用来探查的排序函数
Profiler类的接口如下:
探查器方法 | 作用 |
---|---|
p.test(function,lyst,size,unique,comp,exch,trace) | 用给定的设置运行function,并输出结果 |
p.comparison() | 如果指定了该项,自增比较的次数 |
p.exchange() | 如果指定了该项,自增交换的次数 |
p.str() | 和str(p) 相同,根据该选项,返回的结果字符串表示 |
下面对p.test()的参数进行解释:
参数 | 解释 |
---|---|
function | 正在分析的算法 |
lyst | 允许呼叫者使用他的列表(通常赋值None) |
size | 列表的大小,默认为10 |
unique | 如果为真,则列表包含唯一整数(赋值为布尔类型) |
comp | 如果为真,则计数比较(赋值为布尔类型) |
exch | 如果为真,则计数交换(赋值为布尔类型) |
trace | 如果为真,则在每次交换后打印列表(赋值为布尔类型) |
贴一下书上的代码,有兴趣可以分析一下:
"""
File: profiler.py
Defines a class for profiling sort algorithms.
A Profiler object tracks the list, the number of comparisons
and exchanges, and the running time. The Profiler can also
print a trace and can create a list of unique or duplicate
numbers.
Example use:
from profiler import Profiler
from algorithms import selectionSort
p = Profiler()
p.test(selectionSort, size = 15, comp = True,
exch = True, trace = True)
"""
import time
import random
class Profiler(object):
def test(self, function, lyst = None, size = 10,
unique = True, comp = True, exch = True,
trace = False):
"""
function: the algorithm being profiled
target: the search target if profiling a search
lyst: allows the caller to use her list
size: the size of the list, 10 by default
unique: if True, list contains unique integers
comp: if True, count comparisons
exch: if True, count exchanges
trace: if True, print the list after each exchange
Run the function with the given attributes and print
its profile results.
"""
self._comp = comp
self._exch = exch
self._trace = trace
if lyst != None:
self._lyst = lyst
elif unique:
self._lyst = list(range(1, size + 1))
random.shuffle(self._lyst)
else:
self._lyst = []
for count in range(size):
self._lyst.append(random.randint(1, size))
self._exchCount = 0
self._cmpCount = 0
self._startClock()
function(self._lyst, self)
self._stopClock()
print(self)
def exchange(self):
"""Counts exchanges if on."""
if self._exch:
self._exchCount += 1
if self._trace:
print(self._lyst)
def comparison(self):
"""Counts comparisons if on."""
if self._comp:
self._cmpCount += 1
def _startClock(self):
"""Record the starting time."""
self._start = time.time()
def _stopClock(self):
"""Stops the clock and computes the elapsed time
in seconds, to the nearest millisecond."""
self._elapsedTime = round(time.time() - self._start, 3)
def __str__(self):
"""Returns the results as a string."""
result = "Problem size: "
result += str(len(self._lyst)) + "\n"
result += "Elapsed time: "
result += str(self._elapsedTime) + "\n"
if self._comp:
result += "Comparisons: "
result += str(self._cmpCount) + "\n"
if self._exch:
result += "Exchanges: "
result += str(self._exchCount) + "\n"
return result
如需转载,请注明原文出处,作者:vergilben