2016-11-26 2 views
1

Есть ли шанс оптимизировать следующую строку кода:Список оптимизации производительности

val adj: Array[ListBuffer[Int]] = Array.fill(n)(ListBuffer[Int]()) 
... 
.. 

val sourceVertexes = inGraph.zipWithIndex.filter(v => a.zipWithIndex.exists(r => r._2 != v._2 && r._1.exists(f => f == v._2)) 

inGraph - массив вершин с направлением/ссылки на другие вершины. inGraph размер может быть, скажем, 10000 вершин.

Я пытаюсь найти список источников (список вершин с любым в-пришедший краем)

val adj: Array[List[Int]] = Array.fill(n)(List[Int]()) 
+0

Что такое 'a' в первой строке кода? – kraskevich

+0

Только что обновленный вопрос. Я больше подозреваю, что я должен изменить тип данных из (List или ListBuffer) на что-то другое. – Pavel

ответ

2

Да, это можно сделать это быстрее, используя более эффективный алгоритм. Какой код делает сейчас в основном:

for each vertex: 
    for each edge: 
     if egde goes to vertex: 
      discard it 

Он имеет O(n * m) временную сложность в худшем случае (когда m это число ребер и n это число вершин).

Вот решение, которое является линейным размером графика:

noIncoming = a hash set with all vertices (or just a boolean array) 
for each edge: 
    if edge is not a loop: 
     noIncoming.remove(edge.desitination) // or we can put a mark in a boolean array 

noIncoming есть множество вершин, не имеющие входящих ребер.

+0

Спасибо, не знал, что это работает так. Однако я решил пойти на другое решение. Я создал другой массив списков, чтобы сохранить список входящих краев, которые дали мне поиск времени в лайнерах! – Pavel