2015-04-10 11 views
1

Учитывая, что у нас есть две линии на графике (я только заметил, что я перевернутой цифры на оси Y, это была ошибка, она должна идти от 11-1)Сортировка точек на нескольких линиях

Two lines on a graph

И мы заботимся только о целом числе X пересечениях оси

Two lines on a graph with intersections

мы должны заказать эти точки из наибольшего значения Y до самого низкого значения Y, независимо от их положений на осях X (Обратите внимание, я сделал этот ПИК вручную, чтобы они не выстроились идеально).

Two lines on a graph with intersections and ordering

У меня есть несколько вопросов:

1) я должен предположить, что это известная проблема, но у него есть определенное имя?

2) Существует ли известное оптимальное решение при работе с десятками миллиардов (или сотен миллионов) линий? Наш текущий процесс ручного вычисления каждой точки, а затем сравнения ее с гигантским списком требует часов обработки. Несмотря на то, что у нас может быть сто миллионов строк, нам обычно нужны только 100 или 50 000 результатов, некоторые из которых до сих пор «ниже» других строк, которые вычисляют их точки, не нужны.

+0

Я не уверен в решении, но я бы не использовал python для обработки «десятков миллиардов» любого материала, так как он будет медленным в этот момент, я бы использовал C – lapinkoira

+0

@lapinkoira Есть ли у вас доказательства? –

+0

Каковы пределы для координат X и Y? – johndoevodka

ответ

1
  1. Ваша структура данных является set кортежей

    lines = {(y0, Δy0), (y1, Δy1), ...} 
    
  2. Вам нужно только ntop точки, следовательно, построить set содержащий только верхние ntopyi значения, за один проход над данными

    top_points = choose(lines, ntop) 
    

    EDIT --- выбрать ntop мы должны были следить за наименьшему один, и это интересная информация, так что давайте вернемся и это значение из choose, также мы должны инициализировать decremented

    top_points, smallest = choose(lines, ntop) 
    decremented = top_points 
    

    и начать цикл ...

    while True: 
    
  3. Генерировать set из значений уменьшенного

    декрементируются = {(у -Δy, Δy) для у, Δy в top_points}

    decremented = {(y-Δy, Δy) for y, Δy in decremented if y>smallest} 
        if decremented == {}: break 
    
  4. Генерировать набор кандидатов

    candidates = top_lines.union(decremented) 
    
  5. генерировать новый набор верхних точек

    new_top_points, smallest = choose(candidates, ntop) 
    

    ниже не требуется

  6. проверить, если new_top_points == top_points

    if new_top_points == top_points: break 
        top_points = new_top_points</strike> 
    

    , конечно, мы находимся в цикле ...

Трудная часть является choose функция, но я думаю, что this answer на вопрос How can I sort 1 million numbers, and only print the top 10 in Python? мог помочь тебе.

+0

Думая об этом, существует ряд возможных оптимизаций, например. используя 'numpy' или уменьшая размер' декрементированного' на каждом шаге, удаляя все элементы, меньшие, чем наименьший элемент в 'top_points' перед' union() '... но это преждевременная оптимизация, не так ли? – gboffi

+0

Я отредактировал свой ответ, чтобы включить вторую оптимизацию, о которой я говорил в своем предыдущем комментарии, потому что немного подумать об этом так просто, что кажется необходимым ... – gboffi

0

1) Это не очень сложная вещь, просто «нормальная» проблема сортировки.

2) Обычно сортировка требует большого вычислительного времени. Но в вашем случае это одно, где вам не нужно использовать сложные методы сортировки.

На обоих графиках растут или падают постоянно, нет «прыжков». Вы можете использовать это в своих интересах. Основной алгоритм:

  • определить, растет ли график падения.
  • напишите генератор, который генерирует значения; слева направо, если поднимать, формировать справа налево при падении.
  • получить первое значение из обоих графиков
  • вставить нижнюю дальше в списке результатов
  • получить новое значение из графика, который имел низкое значение
  • повторите последние два шага, пока один генератор не является «пустым»
  • добавьте элементы слева от других генераторов.

Вы предоставили какой-либо код, а переполнение стека не является службой написания кода, поэтому я даю только базовый алгоритм.

+0

Спасибо, мы в настоящее время делаем то, что вы описываете, поэтому я ищу дополнительную информацию (например, имя или статью) проблема в том, когда вы добираетесь до первых двухсот миллионов линий, все эти генераторы разваливаются. Мне действительно не нужен код, просто описание потенциальных решений за пределами ручного вычисления каждой точки в строке. – samwise

+0

Генераторы должны иметь возможность обрабатывать очень длинные строки. Я бы увидел проблему с результатами. Список результатов будет быстро расти, увеличивая потребление памяти. Поэтому вы можете захотеть сохранить его на диск через некоторое время. Может быть, миллион ценностей. Но в целом это O (n) алгоритм, вы не получите ничего быстрее для сортировки. Если есть шея бутылки, это конкретная реализация. Что-то вроде потребления памяти или ввода-вывода. –

Смежные вопросы