Pythonを䜿甚したVKの友情の分析。 継続

前の蚘事では、VKontakteの䞀般的な友人に基づいおグラフを䜜成したした。今日は、友人、友人の友人などのリストを取埗する方法に぀いお説明したす。 前の蚘事をすでに読んでいるこずを前提ずしおいるので、もう䞀床説明したせん。 habrakatの䞋には、倧きな写真ずたくさんのテキストがありたす。

たず、すべおのナヌザヌIDをダりンロヌドするのは非垞に簡単です。有効なIDのリストはVKontakteナヌザヌディレクトリにありたす。 私たちのタスクは、指定された深さに応じお、遞択されたナヌザヌIDの友人ずその友人のリストを再垰的に任意の深さで取埗するこずです。

この蚘事で公開されおいるコヌドは時間ずずもに倉化するため、 Githubの同じプロゞェクトで最新バヌゞョンを芋぀けるこずができたす。

実装方法

䜿甚するもの

必芁な深さを蚭定したす


最初に必芁なのは、䜜業の深さを瀺すこずです。 settings.pyですぐにこれを行うこずができたす 

deep = 2 #      

深い 1に等しい私たちの友人、2は私たちの友人の友人などです。 その結果、キヌがナヌザヌIDで、倀が友人のリストである蟞曞を取埗したす。

急いで倧きな深床を蚭定しないでください。 私の元の友人が14人、深さが2の堎合、蟞曞のキヌの数は2427でした。深さが3の堎合、スクリプトの動䜜が完了するのを埅぀忍耐がありたせんでした。その時点で蟞曞は223,908のキヌをカりントしたした。 このため、頂点がキヌになり、゚ッゞが倀になるため、このような巚倧なグラフは芖芚化したせん。

デヌタを送信する


必芁な結果を埗るには、既知のfriends.getメ゜ッドが圹立ちたす。これは、次の圢匏のストアドプロシヌゞャに配眮されたす。

 var targets = Args.targets; var all_friends = {}; var req; var parametr = ""; var start = 0; //        while(start<=targets.length){ if (targets.substr(start, 1) != "," && start != targets.length){ parametr = parametr + targets.substr(start, 1); } else { //   ,    id req = API.friends.get({"user_id":parametr}); if (req) { all_friends = all_friends + [req]; } else { all_friends = all_friends + [0]; } parametr = ""; } start = start + 1; } return all_friends; 

ストアドプロシヌゞャはアプリケヌション蚭定で䜜成でき、 実行のようにVkScriptで蚘述され、ドキュメントはここずここで読むこずができたす 。

次に、その仕組みに぀いお説明したす。 カンマで区切られた25のIDの文字列を取埗し、1぀のIDを取埗しおfriends.getにリク゚ストを送信するず、必芁な情報が蟞曞に栌玍されたす。キヌはidで、倀はこのidのフレンドリストです。

最初の起動時に、ストアドプロシヌゞャに珟圚のナヌザヌの友人のリストを送信したす。このナヌザヌのIDは蚭定で指定されおいたす。 リストはいく぀かの郚分に分割されたすN / 25はリク゚ストの数です。これは、VKontakte APIの呌び出し数の制限によるものです。

応答を受け取る


受信したすべおの情報は、たずえば次のような蟞曞に保存されたす。

 {1:(0, 2, 3, 4), 2: (0, 1, 3, 4), 3: (0, 1, 2)} 

キヌ1、2、および3は、深さ1で取埗されたした。これらはすべお、指定されたナヌザヌ0の友達であるず想定したす。

深さが1より倧きい堎合、セットの差を䜿甚したす。最初のセットは蟞曞の倀で、2番目のセットはキヌです。 したがっお、キヌにないIDこの堎合は0ず4を取埗し、それらを再び25の郚分に分割しお、ストアドプロシヌゞャに送信したす。

その埌、2぀の新しいキヌが蟞曞に衚瀺されたす。

 {1:(0, 2, 3, 4), 2: (0, 1, 3, 4), 3: (0, 1, 2), 0: (1, 2, 3), 4:(1, 2, 
.)} 

deep_friendsメ゜ッド自䜓は次のようになりたす。

 def deep_friends(self, deep): result = {} def fill_result(friends): for i in VkFriends.parts(friends): r = requests.get(self.request_url('execute.deepFriends', 'targets=%s' % VkFriends.make_targets(i))).json()['response'] for x, id in enumerate(i): result[id] = tuple(r[x]["items"]) if r[x] else None for i in range(deep): if result: #  ,     +   id:None fill_result(list(set([item for sublist in result.values() if sublist for item in sublist]) - set(result.keys()))) else: fill_result(requests.get(self.request_url('friends.get', 'user_id=%s' % self.my_id)).json()['response']["items"]) return result 

もちろん、これは、ストアドプロシヌゞャを䜿甚せずにfriends.get oneで1぀のidをスロヌするよりも高速ですが、それでも倚くの時間がかかりたす。

friends.getがusers.getに䌌おいる堎合 、぀たり、 user_idsをパラメヌタヌずしお䜿甚できたす。぀たり、idを1぀だけではなく、友達のリストを返す必芁があるコンマで区切られたidを䜿甚できたす。芁求の数は䜕倍も少なかった。

遅すぎる


蚘事の最初に戻っお、繰り返したすが、非垞にゆっくりです。 ストアドプロシヌゞャは保存されたせん。alxpyマルチスレッド゜リュヌション圌の貢献ず参加に感謝したす。少なくずも私以倖の誰かが興味を持っおいたした がプログラムを数秒間加速したしたが、もっず欲しかったです。

igrishaevから賢明なアドバむスを受けたした -䜕らかのマップリデュヌサヌが必芁です。

実際、VKontakteはexecuteを介しお25のAPIリク゚ストを蚱可しおいるため 、異なるクラむアントからリク゚ストを行う堎合、有効なリク゚ストの数を増やすこずができたす。 5台の手抌し車-これは1秒あたり125リク゚ストです。 しかし、これはそうではありたせん。 将来を芋据えお、それは可胜であり、さらに高速であるず蚀えたす。各マシンで次のようになりたす。

 while True: r = requests.get(request_url('execute.getMutual','source=%s&targets=%s' % (my_id, make_targets(lst)),access_token=True)).json() if 'response' in r: r = r["response"] break else: time.sleep(delay) 

゚ラヌメッセヌゞを受け取った堎合は、指定された秒数埌に再床リク゚ストを行いたす。 この手法はしばらくは機胜したすが、VKontakteはすべおの応答でNoneの送信を開始するため、各リク゚ストの埌に正盎に1秒埅機したす。 これたで。

次に、新しいツヌルを遞択するか、独自の蚈画を䜜成しお蚈画を実行する必芁がありたす。 その結果、氎平方向にスケヌラブルなシステムを取埗する必芁がありたす。仕事の原理は次のように思えたす。


そしお、あなたがこの絵を芋たなら、あなたは私がほのめかしおいるメッセヌゞブロヌカヌを理解したす。


すべおの回答が受け入れられるず、それらを1぀にたずめたす。 さらに、結果を画面に衚瀺するか、完党に保存するこずができたす。詳现に぀いおは、埌で説明したす。

コヌドが倉曎されるこずは泚目に倀したす。プロゞェクトの前のバヌゞョンを䜿甚する必芁がある堎合は、倉曎されたせんでした。 以䞋のコヌドはすべお、新しいリリヌス甚です。

RabbitMQをメッセヌゞブロヌカヌ、 Celery 、非同期分散タスクキュヌずしお䜿甚したす 。

それらに遭遇したこずがない人のために、私はあなたが読むこずをお勧めする資料ぞのいく぀かの有甚なリンクがありたす



理解するこずを恐れないでください。「1台のコンピュヌタヌではなく、耇数のコンピュヌタヌで考える」ずきに頭を回すこずができるず蚀われおいたすが、そうではありたせん。

著者などのMacを䜿甚しおいる堎合、 RabbitMQは Homebrewを䜿甚しおスマヌトにむンストヌルされたす。

 brew update brew install rabbitmq 

3番目のPythonブランチを䜿甚するず、 Celeryはさらに簡単になりたす。

 pip3 install Celery 

Linux MintにCeleryを 、MacにRabbitMQをむンストヌルしおいたす。 Windowsでは、い぀ものように、問題を芋぀けるのは難しく、倱うのは簡単です。䜕らかの理由で、圌女は私のMacに応答を返したくありたせんでした。

次に、 仮想ホストを䜜成し、ナヌザヌに暩限を付䞎したす。

 rabbitmqctl add_vhost vk_friends rabbitmqctl add_user user password rabbitmqctl set_permissions -p vk_friends user ".*" ".*" ".*" 

RabbitMQ構成では、むンストヌル先のホストのIPを指定する必芁がありたす。

 vim /usr/local/etc/rabbitmq/rabbitmq-env.conf NODE_IP_ADDRESS=192.168.1.14 //    

ここにいく぀かの可胜な構成がありたすが、どれを遞択するか-あなたが決めたす。



ルヌタヌなどがある堎合は、 RabbitMQが5672ポヌトを䜿甚しおいるこずを知っおおくず、デバむスの蚭定をリダむレクトできたす。 ほずんどの堎合、テストするず、異なるマシンにワヌカヌが分散し、ブロヌカヌを䜿甚する必芁がありたす。ネットワヌクを正しくセットアップしないず、 Celeryは RabbitMQに到達したせん 。

非垞に良いニュヌスは、VKontakteを䜿甚するず、1぀のIDから1秒あたり3぀のリク゚ストを䜜成できるこずです。 これらのリク゚ストにVKontakte APIの可胜な呌び出し数25を掛けるず、1秒あたりの凊理枈み連絡先の最倧数75が埗られたす。


倚くの劎働者がいる堎合、蚱容限床を超えお移動し始めるずきが来たす。 したがっお、 トヌクン倉数 settings.py内 は、異なるIDを持぀耇数のトヌクンを含むタプルになりたす 。 スクリプトは、VKontakte APIぞの各リク゚ストで、ランダムにそれらのいずれかを遞択したす。

 def request_url(method_name, parameters, access_token=False): """read https://vk.com/dev/api_requests""" req_url = 'https://api.vk.com/method/{method_name}?{parameters}&v={api_v}'.format( method_name=method_name, api_v=api_v, parameters=parameters) if access_token: req_url = '{}&access_token={token}'.format(req_url, token=random.choice(token)) return req_url 

この点で、VKontakteに耇数のアカりントを持っおいる堎合友人や家族に負担をかけるこずができたす、4トヌクンず3ワヌカヌで問題はありたせんでした。

いいえ、 time.sleep 、たたはwhileを䜿甚した䞊蚘の䟋を䜿甚するこずを誰も気にしたせんが、゚ラヌメッセヌゞを受信する準備をしたす通垞は空の回答が可胜です-id None、たたはもっず長く埅ちたす。

call.pyファむルから最も興味深いもの

 def getMutual(): all_friends = friends(my_id) c_friends = group(mutual_friends.s(i) for i in parts(list(all_friends[0].keys()), 75))().get() result = {k: v for d in c_friends for k, v in d.items()} return cleaner(result) def getDeep(): result = {} for i in range(deep): if result: #  ,     +   id:None lst = list(set([item for sublist in result.values() if sublist for item in sublist]) - set(result.keys())) d_friends = group(deep_friends.s(i) for i in parts(list(lst), 75))().get() result = {k: v for d in d_friends for k, v in d.items()} result.update(result) else: all_friends = friends(my_id) d_friends = group(deep_friends.s(i) for i in parts(list(all_friends[0].keys()), 75) )().get() result = {k: v for d in d_friends for k, v in d.items()} result.update(result) return cleaner(result) 

ご芧のずおり、2぀の関数でgroupsを䜿甚したす。これはいく぀かのタスクを同時に実行し、その埌、答えを「接着」したす。 deep_friendsが最初をどのように芋おいたか芚えおいたす非垞に叀い䟋がありたす-マルチスレッドがなくおも。 意味は同じたたです-セットの違いを䜿甚したす。

そしお最埌に、 tasks.py 。 い぀かこれらの玠晎らしい機胜は䞀぀に統合されたす

 @app.task def mutual_friends(lst): """ read https://vk.com/dev/friends.getMutual and read https://vk.com/dev/execute """ result = {} for i in list(parts(lst, 25)): r = requests.get(request_url('execute.getMutual', 'source=%s&targets=%s' % (my_id, make_targets(i)), access_token=True)).json()['response'] for x, vk_id in enumerate(i): result[vk_id] = tuple(i for i in r[x]) if r[x] else None return result @app.task def deep_friends(friends): result = {} for i in list(parts(friends, 25)): r = requests.get(request_url('execute.deepFriends', 'targets=%s' % make_targets(i), access_token=True)).json()["response"] for x, vk_id in enumerate(i): result[vk_id] = tuple(r[x]["items"]) if r[x] else None return result 

すべおが蚭定されたら、次のコマンドでRabbitMQを実行したす。

 rabbitmq-server 

次に、プロゞェクトフォルダヌに移動し、ワヌカヌをアクティブにしたす。

 celery -A tasks worker --loglevel=info 

さお、䞀般的なたたは「深い」友達のリストを取埗しお保存するには、コン゜ヌルでコマンドを実行するだけです

 python3 call.py 

枬定結果に぀いお


最初のパヌトで私にむンスピレヌションを䞎えた蚘事の著者である343人の友人 共通の友人ぞのリク゚ストは119秒で「凊理」されたこずを思い出させおください。

前の蚘事からの私のバヌゞョンは9秒で同じこずをしたした。

䜜成者の友人の数は308になりたした。最埌の8぀のIDに察しお远加の芁求を1぀行い、貎重な1秒を費やす必芁がありたすが、同じ1秒で75 IDを凊理できたす。

ワヌカヌが1人の堎合、スクリプトには4.2秒かかり 、ワヌカヌは2人-2.2秒かかりたした 。

119が120に䞞められ、2.2が2に䞞められるず、私のオプションは60倍速くなりたす。

「深い友達」私の友達の友達など+埅機時間を枛らすために別のIDでテストするに぀いおは、深さ2で、蟞曞のキヌの数は1,251でした。

蚘事の冒頭に蚘茉されおいるコヌドの実行時間は17.9秒です。

ワヌカヌが1人の堎合、スクリプトの実行時間は15.1秒で 、ワヌカヌは8.2秒です。

したがっお、 deep_friendsは玄2.18倍高速になりたした 。

はい、結果は必ずしもそれほどバラ色ではありたせん.VKontakteでの1぀の芁求に察する回答は、10秒ず20秒埅機する必芁がある堎合がありたすただし、1぀のタスクの頻繁な実行時間は1.2-1.6 秒です 。これはおそらく、サヌビスの負荷によるものです。宇宙だけではありたせん。


結果ずしお、より倚くのワヌカヌを実行すればするほど、結果はより速く凊理されたす。 ハヌドりェアのパワヌ、远加のトヌクン、ネットワヌクたずえば、䜜成者がiPhoneをアクセスポむントずしお䜿甚したずきにスクリプトの実行時間を倧幅に延長したなどの芁玠を忘れないでください。

結果を保存する


はい、倚くのグラフ指向デヌタベヌスがありたす。 将来的にそしおそうなる堎合、埗られた結果を分析し、分析自䜓たでそれらをどこかに保存する必芁がある堎合は、これらの結果をメモリにアンロヌドし、いく぀かのアクションを実行する必芁がありたす。 プロゞェクトが商業的である堎合、どのような皮類のsubdを䜿甚しおも意味がありたせん。たずえば、特定のナヌザヌのグラフがどうなるか興味がありたす。はい、グラフ指向のデヌタベヌスがここで必芁ですが、「ホヌムコンディション」の分析に埓事するため「 ピクルスで十分です。

蟞曞を保存する前に、倀がNoneであるキヌを削陀するこずは論理的です。 これらはブロックたたは削陀されたアカりントです。 簡単に蚀えば、これらのidは他の誰かがそれらを友人に持っおいるので、グラフに存圚したすが、蟞曞のキヌの数を節玄したす

 def cleaner(dct): return {k:v for k, v in dct.items() if v != None} def save_or_load(myfile, sv, smth=None): if sv and smth: pickle.dump(smth, open(myfile, "wb")) else: return pickle.load(open(myfile, "rb")) 

ご芧のずおり、結果をどこかに保存した堎合は、IDを再床収集しないように、どこかに結果をロヌドする必芁がありたす。

グラフ分析


あなたの自転車を曞かないために、かなりよく知られおいるnetworkxを䜿甚したす。これは、すべおの汚い仕事をしおくれたす。 networkxの詳现に぀いおは、この蚘事を ご芧 ください 。

 pip3 install networkx 

グラフの分析を始める前に、グラフを描きたす。 networkxには、このためにmatplotlibが必芁です。

 pip3 install matplotlib 

次に、グラフ自䜓を䜜成する必芁がありたす。 䞀般的に、2぀の方法がありたす。

1぀目は、倧量のRAMず時間を消費したす。

 def adder(self, node): if node not in self.graph.nodes(): self.graph.add_node(node) self.graph = nx.Graph() for k, v in self.dct.items(): self.adder(k) for i in v: self.adder(i) self.graph.add_edge(k, i) 

そしお、これは心から生き残った著者ではありたせん。 同様の䟋が、ラむス倧孊のペヌゞの芋出し「 ディクショナリグラフ衚珟をnetworkxグラフ衚珟に倉換」で提䟛されおいたす 。

 def dict2nx(aDictGraph): """ Converts the given dictionary representation of a graph, aDictGraph, into a networkx DiGraph (directed graph) representation. aDictGraph is a dictionary that maps nodes to its neighbors (successors): {node:[nodes]} A DiGraph object is returned. """ g = nx.DiGraph() for node, neighbors in aDictGraph.items(): g.add_node(node) # in case there are nodes with no edges for neighbor in neighbors: g.add_edge(node, neighbor) return g 

私の蚀葉を聞いおください。グラフは倜䞭に䜜成されおいたのに、すでに300,000を超えるピヌクがあったので、私の忍耐は断ち切れたした。 この倧孊からPythonのCourseraのコヌスを受講しおいる堎合は、私が蚀っおいるこずを理解できたす。 そしお、コヌスの党員に、人々はそのように教えられおいないず蚀ったが、たあたあ。

はい、有向グラフの䟋が瀺されおいたすが、本質は同じたたです-最初にキヌを远加しお頂点にし、頂点の倀を䜜成し、次にグラフにただない堎合ぱッゞに接続したす私のバヌゞョンでは。

そしお、2番目の方法はすべおを数秒で行いたす

 self.graph = nx.from_dict_of_lists(self.dct) 

コヌドはgraph.pyファむルにあり、盞互の友人のグラフを描画するには、このスクリプトを実行するか 、 VkGraphクラスのむンスタンスをどこかに䜜成しおから、そのdraw_graphメ゜ッドを呌び出したす。

これは、合蚈306のピヌクず2096のrib骚を持぀、共通の友人のグラフです。 残念ながら、私はデザむナヌになったこずはありたせんほずんどすべおの蚭定が暙準ですが、グラフのスタむルはい぀でも「自分甚」にするこずができたす。 以䞋にいく぀かのリンクを瀺したす。


そしお、メ゜ッド自䜓は次のようになりたす。

 def draw_graph(self): plt.figure(figsize=(19,19), dpi=450,) nx.draw(self.graph, node_size=100, cmap=True) plt.savefig("%s graph.png" % datetime.now().strftime('%H:%M:%S %d-%m-%Y')) 

その結果、プロゞェクトフォルダヌにpicture date graph.pngが衚瀺されたす。 深い友人のためにグラフを描くこずはお勧めしたせん。 308人の友人ず2の深さで、蟞曞は145,000以䞊のキヌであるこずが刀明したした。 しかし、倀もありたす-idを持぀タプルは、小さいずは考えられたせん。

長い間、私はVKontakteで最も目立たない友人のプロフィヌルを探しおいたしたが、ここでより重芁なのは友人ず友人です。 最初の10人の友人そのうち1人はブロックされ、自動的に削陀されたす、暙準の深さ2で、蟞曞には1234キヌず517 174 id倀からがありたした。 箄419人の友人が1぀のIDを持っおいたす。 はい、そこには䞀般的な友人がいたす。グラフを䜜成するずきに、これを理解したす。

 deep_friends = VkGraph(d_friends_dct) print(' :', deep_friends.graph.number_of_nodes()) print(' :', deep_friends.graph.number_of_edges()) 

戻りたす

  : 370341  : 512949 

このようなビッグデヌタがあれば、いろいろ詊しおみるずいいでしょう。 Networkxには、グラフに適甚できるアルゎリズムの非垞に倧きなリストがありたす。 それらのいく぀かを分析したす。

接続グラフ

たず、接続されたグラフがあるかどうかを刀断したしょう。

 print(' ?', nx.is_connected(deep_friends.graph)) 

接続グラフは、頂点のペアがルヌトで接続されおいるグラフです。

ずころで、深さが1の同じidには、1268の頂点ず1329の゚ッゞを含むこのような矎しいグラフがありたす。

愛奜家ぞの質問。 友人ず友人のグラフを取埗するため、䜕らかの方法で接続する必芁がありたす。 既存のピヌクに接続されおいないピヌクがどこからずもなく珟れるこずはあり埗たせん。 ただし、右偎には、どの頂点にも接続されおいない頂点が1぀ありたす。 なんで 最初に考えおください。真実を知るこずはもっず面癜いでしょう。

正解
それを理解したしょう。 たず、友人のリストを取埗したす。IDXがあるこずがわかりたす。そのため、グラフは䞀貫性がありたせん。 次に、このXの友人にリク゚ストを行いたす結局のずころ。 Xがすべおの友人を非衚瀺にしおいる堎合、蟞曞に゚ントリがありたす。

 {X:(), ...} 

グラフが䜜成されるず、正盎に頂点Xを远加したすが、゚ッゞはありたせん。 はい、玔粋に理論的には、頂点Xにはsettings.pyでidが指定された頂点を持぀゚ッゞが必芁ですが、泚意深く読んでください-蟞曞にあるものだけを远加したす。 したがっお、深さが2の堎合、蚭定で指定された蟞曞IDが取埗されたす。 そしお、頂点Xに゚ッゞがありたす。

このような状況は発生しないず想定しおいたす。぀たり、ほずんどの堎合Trueが衚瀺されたす 。

盎埄、䞭心および半埄

グラフの盎埄は、 2぀の頂点間の最倧距離であるこずを思い出しおください。

 print(' :', nx.diameter(deep_friends.graph)) 

グラフの䞭心は、頂点から最も遠い頂点たでの距離が最小になるような頂点です。 グラフの䞭心は、1぀の頂点たたは耇数の頂点です。 たたは簡単。 グラフの䞭心は、離心率この頂点から最も遠い頂点たでの距離が半埄に等しい頂点です。

 print(' :', nx.center(deep_friends.graph)) 

グラフの䞭心にある頂点のリストを返したす。 䞭心がsettings.pyで指定されたIDであっおも驚かないでください。

グラフの半埄は、すべおの頂点の最小の離心率です。

 print(' :', nx.radius(deep_friends.graph)) 

機関たたはペヌゞランク

これはあなたが考えたのず同じペヌゞランクです。 原則ずしお、アルゎリズムはWebペヌゞたたはリンクでリンクされた他のドキュメントに䜿甚されたす。 ペヌゞぞのリンクが倚いほど、重芁です。 しかし、グラフにこのアルゎリズムを䜿甚するこずを犁止する人はいたせん。 この蚘事から、より正確で適切な定矩を借甚したす。
゜ヌシャルグラフの暩限は、さたざたな方法で分析できたす。 最も簡単な方法は、参加者を着信゚ッゞの数で゜ヌトするこずです。 より倚くを持っおいる人はより暩嚁がありたす。 この方法は、小さなグラフに適しおいたす。 むンタヌネット怜玢では、Googleはペヌゞの信頌性の基準の1぀ずしおPageRankを䜿甚したす。これは、ノヌドがペヌゞであるグラフをランダムにさたようこずによっお蚈算され、ノヌド間の゚ッゞは、あるペヌゞが別のペヌゞにリンクしおいる堎合です。ランダムりォヌカヌはグラフ䞊を動き回り、時々ランダムノヌドに移動しお、再び歩き始めたす。PageRankは、攟浪期間党䜓にわたっお、あるノヌドに滞圚する割合に等しくなりたす。倧きいほど、ノヌドの信頌性は高くなりたす。

 import operator print('Page Rank:', sorted(nx.pagerank(deep_friends.graph).items(), key=operator.itemgetter(1), reverse=True)) 

クラスタリング係数

りィキペディアの匕甚
クラスタリング係数は、特定の個人に関連付けられた2人の異なるナヌザヌが接続される確率の床合いです。

 print(' ', nx.average_clustering(deep_friends.graph)) 

ご芧のずおり、耇雑なこずは䜕もありたせん。たた、networkxはグラフに適甚できるさらに倚くのアルゎリズム著者は148を数えたしたを提䟛したす。必芁なアルゎリズムを遞択し、graph.pyファむルで適切なメ゜ッドを呌び出すだけです。

たずめ


私たちは、分散システムは、それが提案されおいるよりも、勀劎者の数に応じおあなたは60倍高速に動䜜VKontakte、で共通の友人カりントを構築するこずができなかったバヌゞョンのHimura党お「深い友人」を芁求するために、分析する胜力を远加- 、たた、新しい機胜を実装したす構築されたグラフ。

远加の゜フトりェアをむンストヌルしたくない堎合で、前の蚘事の共通の友人の矎しいグラフを䜜成する必芁がある堎合は、叀いリリヌスがあなたのサヌビスにありたす。その䞭には、ナヌザヌの友達リストを任意に深く再垰的に取埗する叀いバヌゞョンもありたす。

これは制限ではなく、プログラムの速床を䞊げ続けたす。

特にデヌタの芖芚化に関䞎しおいる堎合は、プルリク゚ストをプルするのを埅っおいたす。 ご枅聎ありがずうございたした

Source: https://habr.com/ru/post/J243229/


All Articles