2016-10-09 2 views
1

Проблема:Максимальное количество задач, выполняемых параллельно?

Нам дано множество из п задач, каждая из которых имеет целое время начала и время окончания . Каково максимальное количество задач, выполняемых параллельно в в любое время?

Алгоритм должен работать в O (n log n) время.

Это назначение школы, так что я не нужен прямой ответ, но любые фрагменты кода приветствуются, пока они находятся в Java или Scala (уступке предполагается записать в Скале.)

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

Вводимые данные могут быть, например, Array[Pair[Int,Int]] = Array((1000,2000),(1500,2200)) и т. Д.

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

PS: Предполагается, что очередь приоритетов будет инициализирована PriorityQueue() (ord).

Редактировать: я придумал решение с использованием очередей приоритетов, но спасибо за все ответы. Вы, ребята, помогли мне разобраться в логике!

+1

Предположим, что у вас есть задачи в двух списках (один отсортированный по времени начала, другой конец времени) и вы поддерживаете индексы для «текущего» задачи в каждой из них. Затем вы знаете время, когда происходит следующий старт и следующий конец. Поэтому вам просто нужно пройти через массивы одновременно и запомнить максимум. Вы могли бы сделать аналогию с двумя очередями с приоритетом, но это, вероятно, медленнее, чем отсортированные массивы (это просто предположение, вам нужно было бы точно убедиться). –

+0

@NicoSchertler Если я пойду через отсортированные массивы одновременно, то алгоритм будет работать в линейном времени? – Jonatan

+1

Да, но сначала вам нужно отсортировать. Следовательно, n log n. –

ответ

2

Soln без использования очереди приоритетов.

Рассмотрим множество задач следующим образом:

[(1,2), (1,5), (2,4), ....] // (a,b) : (start_time, end_time) 

Шаг 1: Construct массив с учетом start_time и end_time вместе.

[1,2,1,5,2,4....] 

Шаг 2: Поддерживать другой массив, чтобы узнать, является ли время в индексе я это start_time или END_TIME

[S,E,S,E,S,E...] // S:Start_Time, E:End_Time 

Шаг 3: Сортировка первого массива. И обязательно измените индекс в другом массиве соответственно.

Этап 4: Поддерживать две переменные, parallel_ryt_now и max_parallel_till_now. И пройти второй массив следующим образом:

for i in 1:len(second_array): 
    if(second_array[i] == "S"): 
     parallel_ryt_now ++ 
    else 
     parallel_ryt_now -- 
    if parallel_ryt_now > max_parallel_till_now: 
      max_parallel_till_now = parallel_ryt_now 

Логик:

Хотя обход отсортированного массива, когда и сталкивается с start_time, это означает, что задача началась.Таким образом, приращение на parallel_ryt_now и когда и столкнулись с end_time, означает, что задача завершена, таким образом, уменьшать parallel_ryt_now.

Таким образом, в каждый момент parallel_ryt_now вар хранит параллельно запущенные задачи.

Время Сложность = Сортировать + траверс = O(nlogn) + O(n) = O(nlogn)

Space Сложность = O(n) (Чтобы сохранить дополнительный массив для информации о том времени, в индексе i является start_time или end_time)

I надеюсь, что это помогло.

+0

Если вы убедитесь, что все теги 'E' находятся перед всеми тегами' S' за одно и то же время, то это отличный способ сделать это. Поэтому лучше сортируйте один массив со структурой или аналогичным образом. –

+0

Для любой задачи 'E'> =' S'. Таким образом, мы можем указать их –

+1

Я имею в виду сценарий, когда на какой-то момент времени 't', есть некоторые задачи, которые заканчиваются на' t', а некоторые задачи начинаются с 't'. Вы не хотите считать их всех. –