Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codereview #4

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open

Codereview #4

wants to merge 18 commits into from

Conversation

agbragin
Copy link

No description provided.

@@ -0,0 +1,53 @@
__author__ = 'Антон Брагин'

class Graph:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для таких задач класс это overkill


def __init__(self, vertices, edges):
"""
Initialize graph object
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Коменты, дословно повторяющие код не нужны.


fn = get_permutation_number(permutation)

with open('nextperm.out', 'w') as fout:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут не нужна вложенность.

Вообще, можно и нужно делать так

with open('foo.txt') as f:
    data = f.read()

print(data) # и вот тут data определенна всегда, несмотря на то, что она объявляется во вложенном блоке

@matklad
Copy link
Collaborator

matklad commented Apr 13, 2014

Хорошо!

  • Будь проще -- не для каждой задачи нужно писать отдельный класс. В Питоне очень мощные встроенные структуры данных(dict, list, set, tuple, collections.namedtuple) и с ними можно писать простой и понятный код. А если используешь классы, то лучше продумывай интерфейс.
  • Не забывай про то, что пустая строка и пустой контейнер это False
  • Юнит-тесты это хорошо =) Но для маленьких задач есть более легковесный способ самопроверки
def is_prime(n):
    some code

assert is_prime(997)
assert not is_prime(42)
assert not is_prime(1)
  • Не то чтобы это сильно относится к данному случаю, но вообще про комментарии есть одно важное замечание, про которое редко говорят: если хочется прокомментировать какой-то кусок кода, то лучше переписать его так, чтобы комментарии не были нужны.
  • Замечание "классы тормозят, поэтому давай-те ка напишем что-то непонятое" мне кажется странным -- вроде там нечему тормозить. Если будет время, попробую с этим разобраться, но не обещаю -- понапосылали тут на review по 29 файлов =)

@agbragin
Copy link
Author

Алексей, большое спасибо за анализ и замечания! Код исправлю в соответствии с комментариями и перевыложу.

Bottleneck в graphs/components.py постараюсь найти самостоятельно)

Представление графа в виде массивов head, edge, next - это не совсем что-то непонятное=), эта реализация достаточно часто используется (описана, например, тут); на Java она ощутимо быстрее, чем вариант, когда для хранения списков смежности используются объекты.

@matklad
Copy link
Collaborator

matklad commented Apr 15, 2014

Представление графа в виде массивов head, edge, next - это не совсем что-то непонятное=)
По крайней мере для меня она была новая, спасибо.

на Java она ощутимо быстрее, чем вариант, когда для хранения списков смежности используются объекты.

Это сомнительно. В статье head edge next сравнивалась с хранением списка смежности в виде двусвязного списка(узлы с указателями). Это не совсем честно, потому что списки тормозят сами по себе. Честнее было бы сравниваться не со списком, а с вектором(расширяющимся массивом). И в этом случае производительность была бы примерно одинаковая, при том что код был бы такой же, как и для связного списка. Так что, прежде чем говорить что что-то тормозит, надо озаботится выбором оптимального конкретного типа данных(ArrayList vs LinkedList).

Другой вопрос в том, что в Java из коробки нет коллекций для примитивных типов, и ArrayList будет тормозить(возможно, но вроде мне это никогда не мешало) просто из-за boxingа.

Третий вопрос заключается в выборе абстрактного типа данных для хранения "списков" =)
Дело в том, что список, на самом деле, не нужен, а нужно множество. И, если в качестве реализации множества выбрать HashSet, то у списка смежности получатся такие же константы по времени, как и у матрицы смежности.

На практике как правило хорошо использовать именно вектора, а не множества, потому что не всегда нужна операция "есть ли ребро между A и B", но у вектора константа меньше, чем у хэш сета

@matklad
Copy link
Collaborator

matklad commented Apr 15, 2014

И не совсем корректно тут говорить об объектах, ничто не мешает head/edge/next решение обернуть в объект с красивым интерфейсом

@effect
Copy link
Owner

effect commented Apr 16, 2014

На счет ощутимо быстрее действительно сомнительно.
Но если гнаться за эффективностью и оптимизацией, то понятно что, скажем, при 100000 вершинах и 200000 ребер три массива (head, edge, next) известного размера, лучше чем 100000 списков - будь то LinkedList или ArrayList - в любом случае оверхед на хранение самих списков получится значительный.

@matklad
Copy link
Collaborator

matklad commented Apr 16, 2014

в любом случае оверхед на хранение самих списков получится значительный.

по памяти overhead действительно будет в любом случае, а по времени думаю что не в любом.

В случае с head/edge/next расположение соседей вершины в памяти зависит от порядка, в котором добавлялись рёбра, и, вообще говоря, не будет cache-friendly.
А в случае ArrayList соседи вершины лежат в одном массиве, что хорошо для обходов.

w = self.edge[e]

if self.component[w] == -1:
vertices_deque.append(w)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хм, а не может ли тут получится, что одна вершинка добавляется в deque несколько раз?

@matklad
Copy link
Collaborator

matklad commented Apr 16, 2014

в любом случае оверхед на хранение самих списков получится значительный.

Сделал глупый бенчмарк на Java: https://gist.github.com/matklad/3212a661cc3d6c7adca4
Мерил список смежности на ArrayList(1), head,edge,next представление(2), и список смежности на массивах интов(3).

(2) и (3) примерно одинаковые по времени работы, (1) раза в два медленнее.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants