mapreduce的一个玩具示例

gdx19jrr  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(415)

我是hadoop和python的新手。我想知道如何改进算法。
这就是问题所在:(使用mapreduce结构解决)
我们将提供三个不同大小的数据集,由新浪微博用户关系生成。较小的数据集包含1000个用户,中等的数据集包含大约250万用户,较大的数据集包含480万用户。每个用户都由其唯一的id号表示。
数据文件的格式如下(不同的跟随者之间用空格分隔):

followee_1_id:follower_1_id follower_2_id follower_3_id ....
followee_2_id:follower_1_id follower_6_id follower_7_id .... ...

如。

A:B D 
B:A 
C:A B E 
E:A B C

社区检测的结果是,对于每个用户,我们都希望知道前k个最相似的人。输出格式应为(不同相似人员之间用空格分隔):

User_1:Similiar_Person_1 Similiar_Person_2 ... Similiar_Person_K 
User_2:Similiar_Person_1 Similiar_Person_2 ... Similiar_Person_K

(其中k表示10000)
我的解决方案:
我的算法是维护一个最多10000个相似的人的列表,并且每当相似的人的数量达到10001时对列表进行排序。然后打开最后一个。在那之后,我发现当数据集很大的时候 (n-10000).n.log(n) 执行时间到了,有什么改进的建议吗?
我的观察:
经过粗略的计算,我发现如果相似的人是小的,我们应该保持缓冲大。例如,如果一个人有5000个相似的人,那么我们可以把名单的上限设为100000。然后我们只需要对列表排序一次,即在打印结果之前。


# !/usr/bin/env python

from operator import itemgetter
import sys

def print_list_of_dict(list_of_dic):
    for v in list_of_dic:
        print v['name'],
    print 
return

current_person1 = None
current_person2 = None
current_S = 0

# declare a list of dictionary

ranking = []
d = {}
flag = 0

# input comes from STDIN

for line in sys.stdin:
    # remove leading and trailing whitespace
    line = line.strip()

    # parse the input we got from mapper.py
    person1, person2 = line.split()

    # first person first relation
    if not current_person1:
        current_person1 = person1
        current_person2 = person2
        current_S += 1
    else:
        # same person , same relation
        if current_person1 == person1 and current_person2 == person2:
            current_S += 1
            flag = 0
        # same person , different relation
        elif current_person1 == person1 and current_person2 != person2:
            d['name'] = current_person2
            d['similarity'] = current_S
            ranking.append(d.copy())
            if len(ranking) == 10001:
                ranking = sorted(ranking,key=itemgetter('similarity'),reverse = True)
                ranking.pop()
            current_person2 = person2
            current_S = 1
            flag = 1
        # different person
        else:
            d['name'] = current_person2
            d['similarity'] = current_S
            ranking.append(d.copy())
            if len(ranking) == 10001:
                ranking = sorted(ranking,key=itemgetter('similarity'),reverse = True)
                ranking.pop()
            ranking = sorted(ranking,key=itemgetter('similarity'),reverse = True)
            print current_person1,':',
            print_list_of_dict(ranking)
            # a new dictionary
            ranking = [] 
            current_person1 = person1
            current_person2 = person2
            current_S = 1
            flag = 2

# add and print the last relation to dictionary

d['name'] = current_person2
d['similarity'] = current_S
ranking.append(d.copy())
if len(ranking) == 10001:
    ranking = sorted(ranking,key=itemgetter('similarity'),reverse = True)
    ranking.pop()
ranking = sorted(ranking,key=itemgetter('similarity'),reverse = True)
print current_person1,':',
print_list_of_dict(ranking)
yrdbyhpb

yrdbyhpb1#

已解决,全部存储在内存中,排序一次后只打印前10000个。

相关问题