【发布时间】:2009-08-24 06:05:32
【问题描述】:
抽象问题:我有一个大约 250,000 个节点的图表,平均连接性约为 10。找到一个节点的连接是一个漫长的过程(比如说 10 秒)。将节点保存到数据库也需要大约 10 秒。我可以非常快速地检查数据库中是否已经存在节点。允许并发,但一次不超过 10 个长请求,您将如何遍历图表以最快地获得最高覆盖率。
具体问题:我正在尝试抓取网站用户页面。为了发现新用户,我从已知用户那里获取好友列表。我已经导入了大约 10% 的图表,但我一直卡在循环中或使用太多内存来记住太多节点。
我目前的实现:
def run() :
import_pool = ThreadPool(10)
user_pool = ThreadPool(1)
do_user("arcaneCoder", import_pool, user_pool)
def do_user(user, import_pool, user_pool) :
id = user
alias = models.Alias.get(id)
# if its been updates in the last 7 days
if alias and alias.modified + datetime.timedelta(days=7) > datetime.datetime.now() :
sys.stderr.write("Skipping: %s\n" % user)
else :
sys.stderr.write("Importing: %s\n" % user)
while import_pool.num_jobs() > 20 :
print "Too many queued jobs, sleeping"
time.sleep(15)
import_pool.add_job(alias_view.import_id, [id], lambda rv : sys.stderr.write("Done Importing %s\n" % user))
sys.stderr.write("Crawling: %s\n" % user)
users = crawl(id, 5)
if len(users) >= 2 :
for user in random.sample(users, 2) :
if (user_pool.num_jobs() < 100) :
user_pool.add_job(do_user, [user, import_pool, user_pool])
def crawl(id, limit=50) :
'''returns the first 'limit' friends of a user'''
*not relevant*
当前实施的问题:
- 卡在我已经导入的派系中,从而浪费时间并且导入线程处于空闲状态。
- 会在有人指出时添加更多内容。
因此,欢迎进行边际改进以及完全重写。谢谢!
【问题讨论】:
-
与几个著名的图论 (!) 算法的发现者 Robert Tarjan 有任何关系吗?
-
:) 可悲的是,只有匈牙利的小镇是我们俩的姓氏。但我们都热爱计算机和数学。
-
与问题无关,但请注意 sys.stderr.write("...\n") 可以替换为 print >> sys.stderr, "..." (不需要“\n”,并使用更常见的打印语句)。
-
对,但是我正在将标准输出重定向到一个文件(你不可能知道),并且仍然希望错误消息显示在我的控制台中。
标签: python performance algorithm language-agnostic graph-traversal