arXiv теперь является независимой некоммерческой организацией! Узнать больше
Оглавление, темный режим, ссылки
License: CC BY-NC-ND 4.0
arXiv:2508.09828v1 [cs.SE] 13 августа 2025

Быстрые и точные эвристики для оценки bus-factor

Себастиано А. Пикколо email: sebastiano.piccolo@unical.it Аффилиация: Калабрийский университет
Кафедра математики и информатики
, Ренде (CS), Италия
© none
Аннотация.

Фактор автобуса — это критический индикатор риска, который количественно определяет, сколькими ключевыми участниками может пожертвовать проект, прежде чем будут скомпрометированы основные знания или функциональность. Несмотря на его практическую значимость, точное вычисление фактора автобуса является NP-трудной задачей при существующих формализациях, что делает масштабируемый анализ невыполнимым для крупных программных систем..

В данной статье мы моделируем программные проекты как двудольные графы разработчиков и задач и предлагаем две новые аппроксимационные эвристики, Минимальное покрытие и Максимальное покрытие, основанные на итеративном графовом «шелушении» (graph peeling), для двух влиятельных формализаций bus factor. Наши методы значительно превосходят широко используемую эвристику, основанную на степени вершин, которая, как мы показываем, может приводить к существенно завышенным оценкам..

Мы проводим всестороннюю эмпирическую оценку на более чем 1 0001\,000 синтетических графах со степенным распределением и демонстрируем, что наши эвристики обеспечивают более точные оценки, масштабируясь до графов с миллионами узлов и ребер за считанные минуты. Наши результаты показывают, что предложенные эвристики не только более точны, но и устойчивы к структурным вариациям в графе распределения задач между разработчиками. Мы выпускаем нашу реализацию в виде программного обеспечения с открытым исходным кодом для поддержки будущих исследований и практического внедрения..

1. Введение

Современные программные системы редко создаются изолированными разработчиками. Вместо этого они формируются крупными совместными экосистемами, которые часто включают сотни или тысячи участников, работающих в разных географических регионах, часовых поясах и организационных границах (Yamashita et al., 2015; Majumder et al., 2019). Хотя эта модель сотрудничества обеспечивает масштабируемость и инновации, она также порождает серьезные риски: что произойдет, если ключевой участник внезапно исчезнет из проекта — уйдет из компании, сменит команду, выгорит или просто перестанет отвечать?

Этот риск обычно отражается с помощью показателя bus-factor — разговорного, но все более формализуемого критерия, который количественно определяет минимальное число людей, чья потеря приведет к серьезной остановке прогресса проекта (Zazworka et al., 2010; Avelino et al., 2016; Rigby et al., 2016; Cosentino et al., 2015; Piccolo et al., 2024).

Риск потери или фрагментации знаний из-за недоступности людей особенно актуален в таких контекстах, как проекты с открытым исходным кодом, где участие контрибьюторов является добровольным, а перерывы в работе — обычное явление (Majumder et al., 2019; Avelino et al., 2016), а также в контекстах, где небольшое количество людей обладает знаниями о большей части проекта, устаревших компонентах и может выступать в роли посредников при обмене знаниями (Piccolo et al., 2018; Lawrence and Lorsch, 1986; Piccolo et al., 2022; Heath and Staudenmayer, 2000; Palomba et al., 2021).

За прошедшие годы было предложено несколько формализаций bus factor. Одно направление исследований, включая работы Avelino et al.(Avelino et al., 2016) и Zazworka et al.(Zazworka et al., 2010), моделирует проекты в виде двудольных графов между людьми и задачами (например, файлами, фичами, модулями) и определяет bus factor как количество людей, удаление которых оставляет половину задач непокрытыми. Другая формулировка, предложенная Piccolo et al.(Piccolo et al., 2024; Piccolo et al., 2025), фокусируется на связности задач и определяет bus factor через то, как удаление человека влияет на размер наибольшей связанной компоненты задач.

Несмотря на эти различия в определениях, возникает общая преграда: вычисление bus-фактора является вычислительно сложным при обеих формулировках. Фактически, даже приближенные решения могут оказаться затратными на больших графах. В результате специалисты часто полагаются на простые эвристики, такие как удаление людей в порядке убывания степени.

Тем не менее, как мы показываем на Рисунке 1, этот подход может быть опасным образом вводящим в заблуждение. В некоторых случаях эвристика степени грубо переоценивает количество людей, необходимых для достижения пороговых значений критического покрытия задач, не уделяя приоритетного внимания людям, присутствие которых поддерживает ключевую структурную связность. На рисунке также показана производительность наших эвристик Минимальное покрытие и Максимальное покрытие, которые достигают значительно лучших оценок в обеих формулировках..

На изображении показана несостоятельность эвристик удаления на основе степени вершины.

⟦Figure 1. Пример кривых bus-factor, вычисленных как по определению Avelino et al., так и по определению Piccolo et al., где эвристика степени (зеленая линия) оценивает больший bus-factor, чем тот, который оценивается двумя эвристиками, разработанными в этой статье. Изображение показывает несостоятельность эвристик порядка удаления на основе степени.

Эти пробелы в текущей практике порождают несколько исследовательских вопросов:

  • ⟦• Можем ли мы разработать эвристики, которые лучше аппроксимируют формальные определения bus factor и при этом остаются масштабируемыми для больших графов?
  • ⟦• Как эти эвристики ведут себя при различных структурных свойствах двудольного графа людей и задач?
  • ⟦• Насколько эффективно работают эти эвристики?

Для ответа на эти вопросы в данной работе предлагаются следующие вклады:

  1. ⟦(1) Мы предлагаем две новые эвристики приближения: Minimum Coverage и Maximum Coverage, которые итеративно удаляют контрибьюторов с минимальным/максимальным покрытием для более точной оценки bus-factor.
  2. ⟦(2) Мы представляем жадную стратегию минимизации, которая дополняет вышеупомянутые эвристики по мере Пикколо и др. путем оптимизации структурного разрушения связности задач.
  3. ⟦(3) Мы представляем теоретический анализ временной сложности наших алгоритмов и показываем, как они масштабируются для графов с миллионами вершин и ребер.
  4. ⟦(4) Мы проводим всестороннюю эмпирическую оценку на большом синтетическом наборе данных, состоящем из 1000 двудольных графов с распределением по степеням, которая показывает, что наши эвристические алгоритмы превосходят современные аналоги как по точности, так и по надежности.
  5. ⟦(5) Мы исследуем, как структура графа влияет на производительность эвристик, получая новые сведения о том, когда различные эвристики оказываются успешными или терпят неудачу.

Остальная часть статьи организована следующим образом: в разделе 2 рассматриваются предложенные до сих пор показатели bus-factor, а также стратегии их оценки. В разделе 3 представлены основы теории графов и формализована проблема bus-factor вместе с подходами, предложенными Avelino et al. (Avelino et al., 2016), Zazworka et al. (Zazworka et al., 2010) и Piccolo et al. (Piccolo et al., 2024). В разделе 4 описываются разработанные нами эвристики, приводится их вычислительная сложность и соответствующие детали реализации. В разделе 5 обсуждается наша экспериментальная оценка, в которой мы оцениваем точность наших эвристик, их масштабируемость и поведение при различных структурах графов. Наконец, в разделе 6 статья завершается..

2. Связанные работы

Фактор автобуса (также известный как фактор грузовика) количественно определяет минимальное количество ключевых сотрудников, внезапный уход которых нанесет ущерб проекту. Фактор автобуса относится к более широкой категории проблем проектов, известных как запахи сообщества (Almarimi et al., 2020; Catolino et al., 2020; Catolino et al., 2021; Palomba et al., 2021). В исследованиях в области программной инженерии эта концепция рассматривалась главным образом через решение двух связанных задач: 1) выявление основных разработчиков, то есть тех, кто вносит существенный вклад в кодовую базу, и 2) оценка фактора автобуса проекта при заданной модели вклада и покрытия задач.

Обычный метод идентификации ключевых разработчиков заключается в вычислении степени авторства (Degree of Authorship, DoA), которая присваивает участникам баллы авторства для каждого файла на основе различных сигналов, таких как история коммитов, код-ревью или встречи (Yamashita et al., 2015; Cosentino et al., 2015; Avelino et al., 2016; Jabrayilzade et al., 2022; Fritz et al., 2014). Как правило, для вычисления фактора автобуса (bus-factor) кодовая база представляется в виде двудольного графа людей и файлов исходного кода, а такие метрики, как DoA, используются не только для оценки вклада каждого разработчика в каждый файл, но и для фильтрации графа от несущественного вклада..

Одна из самых ранних формализаций фактора автобуса была предведена Зазворкой и др. (Zazworka et al., 2010), которые предложили измерять надежность проекта как количество людей, которые могут уйти без угрозы для покрытия задач выше заданного порога. Их фреймворк определяет три варианта фактора автобуса (Zmin,tZ_{\min,t}, Zmax,tZ_{\max,t} и Zavg,tZ_{\mathrm{avg},t}), основанных на минимальном, максимальном и среднем количестве задач, все еще покрытых после удаления любого подмножества участников размера kk. Общая формулировка имеет вид Zα,t=max⁡{n∈ℕ:covα​(n)≥t​m}Z_{\alpha,t}=\max\{n\in\mathbb{N}:\mathrm{cov}_{\alpha}(n)\geq tm\}, где mm — общее количество задач, а covα​(n)\mathrm{cov}_{\alpha}(n) измеряет покрытие после удаления. Несмотря на свою общность, этот подход подвергался критике за вычислительную невыполнимость для крупных проектов (Ricca et al., 2011; Ferreira et al., 2017) и за опору на фиксированные пороги. Ханнебауэр и Грун (Hannebauer and Gruhn, 2014) показали, что вычисление Zmin,tZ_{\min,t} и Zmax,tZ_{\max,t} является NP-сложным, и хотя Zavg,tZ_{\mathrm{avg},t} вычисляется за полиномиальное время, его сложнее интерпретировать и он менее информативен в практических сценариях. Совсем недавно Пикколо и др. (Piccolo et al., 2025) показали, что Zmax,tZ_{\max,t} является слишком оптимистичным и не может отражать изменения проекта, которые увеличивают или уменьшают его фактор автобуса (такие как разрежение графа проекта путем удаления ребер).

Чтобы преодолеть ограничения исчерпывающих определений Зазворки, в более поздних работах фактор автобуса определялся как минимальное число людей, уход которых приводит к остановке проекта. Косентино и др. (Cosentino et al., 2015) представили инструмент на основе коммитов, который определяет ключевых разработчиков (которые соответствуют высокому порогу знаний XX, например, 1/N1/N от общего авторства) и второстепенных разработчиков (выше более низкого порога YY, часто Y=0.5​XY=0.5X). Фактор автобуса в таком случае равен размеру объединения этих двух наборов разработчиков (Lisan and Norris, 2024). Эта схема с двумя породами может выделить немногих экспертов, охватывающих компонент, но она требует выбора XX и YY априори и может быть чувствительна к этим параметрам. Авелино и др. (Avelino et al., 2016) предложили более простой эвристический подход на основе DoA: вычислить оценку DoA для каждого разработчика по каждому файлу, затем итеративно удалять текущего ведущего автора (того, кто покрывает больше всего файлов) и увеличивать счетчик фактора автобуса, останавливаясь, когда менее 50% файлов остаются покрытыми каким-либо автором. Другими словами, людей продолжают удалять до тех пор, пока более половины кода не окажется заброшенным (Avelino et al., 2016). Ригби и др. (Rigby et al., 2016), с точки зрения управления рисками, рассмотрели как вероятность, так и влияние ухода разработчиков и предложили эвристику на основе имитационного моделирования методом Монте-Карло для оценки фактора автобуса проекта. Феррейра и др. (Ferreira et al., 2017) в ходе сравнения эвристик оценки фактора автобуса обнаружили, что алгоритм удаления Авелино и подход Косентино являются наиболее точными предикторами фактора автобуса (и ключевых разработчиков), причем метод Авелино в среднем работает немного лучше. Недавно Джабраилзаде и др. (Jabrayilzade et al., 2022) предложили мультимодальный оценщик фактора автобуса, который расширяет метрику DoA Авелино за счет учета устаревания вкладов со временем и включения метаданных ревью и встреч. Их алгоритм показал немного лучшие результаты, чем оригинальный инструмент Авелино, использующий только DoA, при прогнозировании как фактора автобуса, так и ключевых инженеров, определенных респондентами опроса (Jabrayilzade et al., 2022)⟧.

Подходы машинного обучения также получили распространение для прогнозирования риска bus-factor. Алмарими и др. (Almarimi et al., 2020; Almarimi et al., 2023) разработали csDetector, который сигнализирует о наличии «truck-factor smell» — формы запаха сообщества — с помощью классификаторов на основе деревьев решений. Хотя csDetector эффективен в выявлении рискованных проектов, он не оценивает числовой bus factor, а вместо этого требует его в качестве входных данных для обучения. Его бинарный характер делает его более подходящим в качестве дополнительного диагностического инструмента.

Для преодоления ограничений зависимости от пороговых значений и ненормированных метрик, Пикколо и др. (Piccolo et al., 2018; Piccolo et al., 2024; Piccolo et al., 2025) недавно предложили графо-теоретическую формулировку фактор автобуса, не зависящую от пороговых значений. Они представляют проект в виде двудольного графа между людьми и задачами и определяют фактор автобуса как нормированную площадь под кривой робастности, которая измеряет, как деградирует наибольшая связная компонента задач при удалении контрибьюторов в состязательном порядке. Эта нормированная метрика облегчает сравнение проектов различного размера и сложности. Хотя вычисление точной метрики является NP-сложной задачей (Piccolo et al., 2025), авторы предоставляют алгоритм аппроксимации за линейное время на основе структур union-find и предлагают эвристики восхождения к вершине и имитации отжига для оптимизации назначения команд на задачи. Они продемонстрировали, что их метод может улучшить фактор автобуса реального проекта более чем на 40% посредством стратегического перераспределения..

Подводя итог, оценка bus factor эволюционировала от метрик на основе фиксированных порогов и покрытия к более точным, масштабируемым и универсальным подходам, которые также включают подходы машинного обучения и нормализованные показатели, не зависящие от предметной области. Данная статья пополняет эту базу знаний, предлагая быстрые и масштабируемые эвристики для оценки bus factor для мер Avelino et al. (Avelino et al., 2016) и Piccolo et al. (Piccolo et al., 2024; Piccolo et al., 2025).

3. Контекст

В этой статье мы используем двудольные графы в качестве инструментов для моделирования программных проектов и оценки их bus-factor. В разделе 3.1 мы представляем графовые теоретические инструменты и обозначения, которые будем использовать на протяжении всей статьи; в разделе 3.2 мы представляем проблему bus-factor, ее формализации и текущую технику оценки.

3.1. Теория графов

3.1.1. Предварительные сведения

Граф представляет собой пару 𝒢=(V,E)\mathcal{G}=(V,E), где VV — множество вершин, а E⊆V×VE\subseteq V\times V — множество ребер. Граф представляется через свою матрицу смежности AA; причем Ai​j=1A_{ij}=1, если вершины ii и jj соединены, и Ai​j=0A_{ij}=0 в противном случае. Степень kik_{i} вершины ii — это количество соединенных с ней вершин, то есть ki=∑jAi​jk_{i}=\sum_{j}A_{ij}. Подграф графа GG представляет собой граф, индуцированный подмножеством S⊆VS\subseteq V вершин графа GG, и обозначается как G⁡[S]G[S]. Компонента связности графа — это связанный подграф, который не является частью никакого другого связанного подграфа.

3.1.2. Двудольные графы и моделирование программных проектов

Если множество вершин VV может быть разделено на два множества V1V_{1} и V2V_{2} с V1∩V2=∅V_{1}\cap V_{2}=\emptyset и V1∪V2=VV_{1}\cup V_{2}=V, таких что ∀(i,j)∈E​i∈V1∧j∈V2\forall(i,j)\in E\;i\in V_{1}\wedge j\in V_{2}, то граф называется двудольным. Двудольный граф является подходящим инструментом для представления связей между множеством людей и множеством артефактов, таких как файлы исходного кода, документы, модули, задачи и так далее. Без потери общности, в данной статье мы ссылаемся на двудольные графы людей и задач, которые мы обозначаем как 𝒢=(P,T,E)\mathcal{G}=(P,T,E), где PP — это множество людей, TT — множество задач, а EE — множество ребер между людьми и задачами. Мы говорим, что человек ii покрывает задачу jj, если (i,j)∈E(i,j)\in E, и мы говорим, что задача jj покрыта, если с ней связан по крайней мере один человек; то есть если kj>0k_{j}>0. Мы ссылаемся на задачи в компоненте связности как на связанные задачи и ссылаемся на наибольшее количество задач в компоненте связности как на максимальное количество связанных задач, обозначая его как τ⁡(G)\tau(G). Наконец, kP=max⁡∑ii∈P⁡Ai​jk_{P}=\max_{i\in P}\sum_{i}A_{ij} и kT=max⁡∑jj∈T⁡Ai​jk_{T}=\max_{j\in T}\sum_{j}A_{ij} обозначают соответственно наибольшую степень среди людей и наибольшую степень среди задач.

3.1.3. Степенные графы и герои в программных проектах

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

Удобный способ генерации графов с сильно асимметричными распределениями степеней заключается в выборке степеней узлов из степенного распределения, соединяя узлы случайным образом в соответствии с выбранным распределением степеней. Степенное распределение определяется следующей функцией плотности вероятности:

(1) f⁡(x,λ,kmin,kmax)=λkmax​(x−kminkmax)λ−1f(x,\lambda,k_{\min},k_{\max})=\frac{\lambda}{k_{\max}}\left(\frac{x-k_{\min}}{k_{\max}}\right)^{\lambda-1}

где 0<λ<10<\lambda<1 представляет собой параметр, регулирующий асимметрию распределения: чем выше λ\lambda, тем менее асимметрично распределение (при λ=1\lambda=1 мы получаем равномерное распределение); kmink_{\min} и kmaxk_{\max} регулируют носителем ff, который равен [kmin,kmin+kmax][k_{\min},k_{\min}+k_{\max}], и, следовательно, максимальную и минимальную степень в графе степенного закона.

Алгоритм 1 предоставляет процедуру для создания двудольного графа с распределением степеней, подчиняющимся степенному закону. Он работает следующим образом: сначала он выбирает два распределения степеней со степенным законом без изолированных узлов (ни у одного узла нет степени 0). Затем он гарантирует, что эти два распределения степеней имеют одинаковую сумму, и генерирует граф, соединяя случайные узлы в соответствии с заданными степенями и без создания двойных рёбер между одной и той же парой узлов. Наконец, если граф не является связным, выполняется процедура случайного переподключения рёбер, которая не изменяет распределения степеней..

⟦Algorithm 1 Генератор двудольных степенных графов
Входные данные: |P||P|, |T||T|, λP\lambda_{P}, λT\lambda_{T}, kPk_{P}, kTk_{T}
Выходные данные: Связный двудольный граф со степенным законом распределения GG
1 degreesP∼PowerLaw⁡(λP,1,kP−1,|P|)\mathrm{degrees}_{P}\sim\mathrm{PowerLaw}(\lambda_{P},1,k_{P}-1,|P|);
2 degreesT∼PowerLaw⁡(λT,1,kT−1,|T|)\mathrm{degrees}_{T}\sim\mathrm{PowerLaw}(\lambda_{T},1,k_{T}-1,|T|);
3 в то время как ∑degreesP≠∑degreesT\sum\mathrm{degrees}_{P}\neq\sum\mathrm{degrees}_{T} выполнить
    4 Выберите случайный узел со степенью > 1 из большего распределения и уменьшите его степень на единицу;
5 конец цикла
6 G←G\leftarrow КонфигурационнаяМодель(degreesP\mathrm{degrees}_{P}, degreesT\mathrm{degrees}_{T});
7 в то время как GG не является связанный выполнить
    8 Выберите два связных компонента C1,C2C_{1},C_{2} из GG;
    9 Выберите два ребра: (p1,t1)(p_{1},t_{1}) из C1C_{1} и (p2,t2)(p_{2},t_{2}) из C2C_{2};
    10 Перенастройте ребра следующим образом: (p1,t2),(p2,t1)(p_{1},t_{2}),(p_{2},t_{1});
11 end while
12 вернуть GG;

3.2. Фактор автобуса

Фактор автобуса — это мера уязвимости проекта по отношению к потере персонала, которая определяется, неформально, как количество людей, которые должны покинуть проект — как если бы их сбил автобус, — пока проект не застопорится. Определение того, когда проект застопорился, далеко не просто, и различные меры фактора автобуса определяют условие остановки по-разному. Здесь мы представляем проблему фактора автобуса и существующие подходы к ее оценке.

Определение 3.1 (Проблема bus factor).

Пусть G=(P,T,E)G=(P,T,E) представляет собой граф, представляющий проект из |P|=n|P|=n человек и |T|=m|T|=m задач. Пусть S⊆PS\subseteq P — это наименьшее множество людей, потеря которых приведет к остановке проекта. Автобусный фактор GG, обозначаемый как B⁡(G)B(G), определяется мощностью SS: B⁡(G)=|S|B(G)=|S|. Автобусный фактор также может быть выражен в относительных величинах, если его разделить на теоретический максимум.

Из предыдущего определения осталось уточнить условие остановки проекта. Это задача далеко не тривиальная и, возможно, зависящая от конкретной предметной области. На сегодняшний день показатели bus-factor определяют условие остановки либо через покрытие задач, либо через максимальное число задач, связанных в единый компонент.

3.2.1. Метрика автобусного фактора Авелино и соавторов

Наиболее распространенная мера bus-factor происходит от Авелино и др., которые предположили, что проект останавливается, если количество покрытых задач меньше t×mt\times m, где 0<t<10<t<1 является входным параметром. Пусть cov(G)=|{j:kj>0,∀j∈T}|\mathrm{cov}(G)=|\{j:k_{j}>0,\forall j\in T\}| — это количество покрытых задач в GG, тогда bus-factor согласно Авелино и др. выглядит следующим образом:

(2) A⁡(G,t)=minS⊆P⁡|S|,cov⁡(G⁡[P∖S])<t×mA(G,t)=\min_{S\subseteq P}|S|,\quad\mathrm{cov(G[P\setminus S])}<t\times m

Другими словами, A⁡(G)A(G) представляет собой размер наименьшего подмножества людей SS, удаление которого из GG приводит к тому, что более чем t×mt\times m задач оказываются изолированными. Авелино и др. предлагают установить t=0.5t=0.5.

Связанная мера bus-factor, которая использовалась в прошлом до внедрения (2), предложена Зазворкой и др. и определяется следующим образом:

(3) Z⁡(G,t)=arg⁡maxk∈ℕ+​minS⊆P,|S|=k⁡cov⁡(G⁡[P∖S])≥t×mZ(G,t)=\arg\max_{k\in\mathbb{N^{+}}}\min_{S\subseteq P,|S|=k}\mathrm{cov(G[P\setminus S])}\geq t\times m

то есть наибольшее подмножество SS людей такое, что при удалении из GG минимальное количество покрытых задач больше или равно t×mt\times m.

Лемма 3.2.

⟦Z⁡(G,t)=A⁡(G,t)−1Z(G,t)=A(G,t)-1⟧.

Доказательство.

Поскольку A⁡(G,t)A(G,t) является размером наименьшего множества SS такого, что cov⁡(G⁡[P∖S])<t×m\mathrm{cov(G[P\setminus S])}<t\times m, для любого множества X⊆PX\subseteq P размера |S|−1|S|-1 выполняется cov⁡(G⁡[P∖X])≥t×m\mathrm{cov(G[P\setminus X])}\geq t\times m, а |S|−1|S|-1 представляет собой максимально возможный размер для такого множества XX. Таким образом, Z⁡(G,t)=A⁡(G,t)−1Z(G,t)=A(G,t)-1. ∎

Данная лемма подразумевает, что решение для (2) также является решением для (3). Однако решение (2) является NP-трудным; поэтому на практике мы используем аппроксимирующий алгоритм для его оценки. Эвристика, предложенная Авелино и соавторами, заключается в удалении людей в порядке убывания их степени до тех пор, пока количество покрытых задач не станет меньше 50%. Количество людей, удаленных таким образом, является оценкой bus-factor..

3.2.2. Мера bus-factor Пикколо и соавторов

Недавно Пикколо и соавторы предложили новую метрику bus-factor, которая является нормализованной и не зависит от входного порогового значения (Piccolo et al., 2024; Piccolo et al., 2025). Они утверждают, что использование порогового значения является в некоторой степени произвольным и что покрытие задач не отражает степень фрагментации знаний в проекте по мере ухода людей. Например, проект, состоящий из nn несвязных диад (то есть ребра, соединяющего одного человека с одной задачей), имеет все покрытые задачи, но Пикколо и соавторы (Piccolo et al., 2025) утверждают, что он обладает высокой степенью фрагментации и что это должно учитываться метрикой bus-factor..

Следовательно, они заменили покрытие максимальным количеством связанных задач; то есть наибольшим числом задач, содержащихся в связанном компоненте. Чтобы не зависеть от порогового значения, они предложили вычислять площадь под кривой затухания максимального числа связанных задач по мере удаления людей, нормируя ее на теоретический максимум (полученный для соответствующего полносвязного двудольного графа). Поэтому они определяют bus-factor как минимальную площадь под кривой по всем возможным порядкам удаления людей (Piccolo et al., 2024; Piccolo et al., 2025).

Формально, пусть π:P→P\pi:P\rightarrow P будет перестановкой людей в PP, Π⁡(P)\Pi(P) будет пространством всех перестановок PP, а Giπ=G⁡[P∖{π1,π2,…,πi}]G_{i}^{\pi}=G[P\setminus\{\pi_{1},\pi_{2},\dots,\pi_{i}\}] будет остаточным графом, полученным путем удаления всех людей вплоть до i-го человека в перестановке π\pi. Напомним, что τ⁡(G)\tau(G) — это максимальное количество задач, соединенных в компонент GG. Фактор автобуса согласно Piccolo et al. (Piccolo et al., 2025) определяется следующим образом:

(4) 𝒫⁡(G)=minπ∈Π⁡(G)⁡12​n−1​∑i=1nτ⁡(Gi−1π)+τ⁡(Giπ)\mathcal{P}(G)=\min_{\pi\in\Pi(G)}\frac{1}{2n-1}\sum_{i=1}^{n}\tau(G_{i-1}^{\pi})+\tau(G_{i}^{\pi})

where G0π=GG_{0}^{\pi}=G. Note that the term ∑i=1nτ⁡(Gi−1π)+τ⁡(Giπ)\sum_{i=1}^{n}\tau(G_{i-1}^{\pi})+\tau(G_{i}^{\pi}) in (4) is just the standard trapezoid rule for computing the area under the curve and the denominator 2​n−1{2n-1} is the maximum theoretical value, obtained for a fully connected graph with nn people. As such, 𝒫⁡(G)\mathcal{P}(G) takes values in [0,1][0,1].

Piccolo и др. (Piccolo et al., 2025) доказали, что решение (4) является NP-сложным, и поэтому они предлагают аппроксимировать его путем упорядочивания людей в π\pi в порядке убывания степени.

4. Новые эвристики для оценки bus factor

В этом разделе мы представляем эвристики, разработанные нами для достижения превосходной оценки bus factor. В частности, мы разрабатываем две эвристики графового шелушения. Стратегия, описанная в разделе 4.1, под названием Minimum Coverage, итеративно выбирает человека, который покрывает наименьшее количество задач.

Стратегия, описанная в разделе 4.2, названная Maximum Coverage, итеративно выбирает человека, который покрывает наибольшее количество непокрытых задач. Эти стратегии работают очень хорошо как для меры Avelino et al., A⁡(G,t)A(G,t), так и для меры Piccolo et al., 𝒫⁡(G)\mathcal{P}(G)⟧.

Наконец, в разделе 4.3 мы представляем эвристику, которая итеративно выбирает человека, увеличивающего τ⁡(G)\tau(G) на наименьшее количество задач. Это специально разработано для решения 𝒫⁡(G)\mathcal{P}(G) и используется в сочетании с минимальным покрытием и максимальным покрытием для улучшения оценки 𝒫⁡(G)\mathcal{P}(G)⟧.

Наши эвристики принимают на вход граф G=(P,T,E)G=(P,T,E) и выдают порядок удаления участников π\pi, который может быть использован для оценки как A⁡(G,t)A(G,t), так и 𝒫⁡(G)\mathcal{P}(G).⟧.

4.1. Минимальное покрытие с итеративным очищением

Эвристика итеративного отшелушивания с минимальным покрытием представляет собой жадный алгоритм для получения упорядочения вершин в двудольном графе, который отдает приоритет минимальному покрытию задач. Цель состоит в том, чтобы построить упорядочение π\pi людей в PP так, чтобы люди, покрывающие меньше в настоящее время непокрытых задач, появлялись раньше в π\pi.

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

Таким образом, обращение полученного порядка π\pi обеспечивает последовательность, в которой задачи остаются непокрытыми как можно быстрее при удалении людей, что делает его мощным эвристическим методом для оценки bus factor..

4.1.1. Описание алгоритма

Мы начинаем с пустого упорядочивания π\pi. На каждом шаге для каждого человека p∈P∖πp\in P\setminus\pi мы определяем его текущее покрытие как количество задач, которые он покрывает и которые еще не покрыты людьми в π\pi. Человек с наименьшим текущим покрытием добавляется в конец π\pi. Этот процесс продолжается до тех пор, пока все люди не будут добавлены в упорядочивание π\pi⟧.

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

4.1.2. Реализация деталей

Наивная реализация минимального покрытия потребовала бы пересчета эффективного покрытия задач для каждого человека, связанного хотя бы с одной задачей, покрытой последним человеком, добавленным в π\pi. Обновление эффективного покрытия затронутых людей требует O⁡(|E|)O(|E|) операций. Поиск человека с минимальным покрытием требует O⁡(|P|)O(|P|) Поскольку у нас есть |P||P| людей, общая вычислительная сложность наивной реализации составила бы O⁡(|E|×|P|)=O⁡(|P|2×|T|)O(|E|\times|P|)=O(|P|^{2}\times|T|), что не масштабировалось бы на большие графы.

Algorithm 2 Минимальное покрытие
Входные данные: двудольный граф G=(P,T,E)G=(P,T,E)
Выходные данные: Упорядочивание π\pi людей
1 inserted[p]←0,∀p∈P\texttt{inserted[$p$]}\leftarrow 0,\;\forall p\in P;
2 𝒬\mathcal{Q} ←\leftarrow Минимальная куча();
3 для каждого p∈Pp\in P выполнять
    4 𝒬\mathcal{Q}.push((G.degree(p),p)(G.\text{degree}(p),p));
5 π←[]\pi\leftarrow[];
6 в то время как 𝒬\mathcal{Q} не пуст выполнить
    7 (priority,p)←𝒬.pop()(\texttt{priority},p)\leftarrow\mathcal{Q}.\text{pop()};
    8 если вставлено[pp] затем
       9 продолжить;
    10 π\pi.добавить(pp);
    11 вставлено[pp] ←\leftarrow 1;
    12 covered_tasks←G.neighbors​(p)\texttt{covered\_tasks}\leftarrow G.\text{neighbors}(p);
    13 affected←⋃t∈covered_tasksG.neighbors​(t)∖{p}\texttt{affected}\leftarrow\bigcup_{t\in\texttt{covered\_tasks}}G.\text{neighbors}(t)\setminus\{p\};
    14 G.remove_nodes_from​(covered_tasks)G.\text{remove\_nodes\_from}(\texttt{covered\_tasks});
    15 для каждого q∈affectedq\in\texttt{affected} делать
       16 𝒬\mathcal{Q}.пуш((G.degree(q),q)(G.\text{degree}(q),q));
17 вернуть π\pi.обратный( );

Вместо этого мы используем очередь с приоритетами, в которой участники упорядочиваются по эффективному покрытию (Algorithm 2, строки 2—4). Мы итеративно извлекаем участника pp с минимальным покрытием и, если этот участник еще не был обработан нами, добавляем его в π\pi (строки 7—10). Мы отмечаем участника pp как добавленного, получаем множество покрытых задач и множество затронутых участников, то есть участников, связанных хотя бы с одной вновь покрытой задачей (строки 11—13). Мы удаляем покрытые задачи из графа GG и обновляем приоритет, то есть эффективное покрытие, для затронутых участников (строки 14—16). Когда алгоритм завершает работу, мы возвращаем π\pi в обратном порядке, чтобы наиболее влиятельные участники оказались в начале последовательности.

Использование приоритетной очереди, выполнение которой занимает O⁡(log⁡|P|)O(\log|P|) операций для извлечения человека с наименьшим покрытием, обеспечивает Алгоритму 2 вычислительную сложность O⁡(|E|​log⁡|P|)O(|E|\log|P|).

4.2. Максимальное покрытие с итеративным шелушением

Эвристика итеративного отшелушивания с максимальным покрытием представляет собой многослойную стратегию прунинга, предназначенную для итеративного разрежения GG путем последовательного выявления и удаления индивида с наибольшим покрытием. Эвристика итеративно определяет слой людей, которые покрывают все задачи в GG, и добавляет этих людей в π\pi в порядке убывания покрытия. Каждый такой слой можно интерпретировать как решение задачи о покрытии множества, поскольку он состоит из подмножества людей, чьи коллективные ребра покрывают все оставшиеся задачи.

Эта эвристика предназначена для достижения двух одновременных целей: 1) разрежения GG путем итеративного удаления человека с наибольшим покрытием, и 2) изоляции задач с низкой степенью, даже тех, которые связаны только с людьми с низкой степенью, на ранних этапах процесса.

4.2.1. Описание алгоритма

Мы начинаем с пустого списка π\pi и выполняем итеративные раунды жадного удаления. В каждом раунде мы поддерживаем рабочую копию графа и многократно выбираем человека, который покрывает наибольшее количество еще не покрытых задач. Это продолжается до тех пор, пока все оставшиеся задачи в текущем раунде не будут покрыты. Как только покрытие завершено, мы удаляем выбранных людей и все ставшие изолированными задачи, а затем начинаем новый раунд на уменьшенном графе. Процесс продолжается до тех пор, пока не будут обработаны все люди.

4.2.2. Детали реализации

⟦Algorithm 3 Максимальное покрытие
Входные данные: двудольный граф G=(P,T,E)G=(P,T,E)
Результат: Упорядочение π\pi людей
1 π←[]\pi\leftarrow[] ;
2 N←|P|N\leftarrow|P| ;
3 num_inserted ←0\leftarrow 0;
4 while num_inserted << NN делать
    5 G.remove_nodes_from​(π)G.\text{remove\_nodes\_from}(\pi);
    6 covered[t]←0​∀t∈T\texttt{covered[$t$]}\leftarrow 0\;\forall t\in T ;
    7 num_tasks ←|{G.degree(t)>0,∀t∈T}|\leftarrow\left|\{G.\text{degree}(t)>0,\;\forall t\in T\}\right|;
    8 если количество_задач == 0 затем
       9 return [π|P][\pi|P]
    10 количество_покрытых ←0\leftarrow 0;
    11 𝒬\mathcal{Q} ←\leftarrow MinHeap();
    12 для каждого p∈Pp\in P выполнять
       13 𝒬\mathcal{Q}.отправка((−G.degree(p),p)(-G.\text{degree}(p),p));
    14 в то время как num_covered << num_tasks выполнять
       15 (priority,p)←𝒬.p​o​p​()(\texttt{priority},p)\leftarrow\mathcal{Q}.pop();
       16 cov←|{t∈G.neighbors(p)if notcovered[t]}|\texttt{cov}\leftarrow\left|\{{t\in G.\text{neighbors}(p)\;\textbf{if not}\;\texttt{covered[$t$]}}\}\right|;
       17 если −priority≠-\texttt{priority}\neq коэффициент вариации затем
          18 𝒬\mathcal{Q}.отправить((−cov,q)(-\texttt{cov},q));
          19 продолжить;
       20 π\pi.добавить(pp);
       21 num_inserted ←num_inserted+1\leftarrow\texttt{num\_inserted}+1;
       22 для каждого t∈Gt\in G.соседи(pp) выполнять
          23 покрыто[tt] ←1\leftarrow 1;
       24 num_covered ←\leftarrow num_covered ++ покрытие;
25 возврат π\pi;

Мы используем очередь с приоритетами и ленивыми обновлениями, где участники ранжируются по эффективному покрытию, умноженному на -1, чтобы выбирать наибольшее покрытие на каждом раунде (Алгоритм 3, строки 11—13). В начале покрытие каждого участника соответствует его степени. Алгоритм 3 останавливается, когда все участники в GG добавлены в π\pi, который инициализируется пустым списком. На каждом раунде участники, добавленные в π\pi на предыдущем раунде, удаляются из GG, и инициализируется очередь с приоритетами из оставшихся участников (строки 4—13). Затем Алгоритм 3 извлекает из 𝒬\mathcal{Q} участника pp с наибольшим покрытием и проверяет, актуален ли приоритет, связанный с pp (строки 15—17); в этом случае он добавляет pp в π\pi и отмечает задачи, с которыми связан pp, как покрытые (строки 20—24). Если нет, он обновляет приоритет и возвращает pp обратно в очередь (строки 17—19). Это ленивое обновление, поскольку приоритеты участников обновляются только при необходимости.

Подобно Минимальному Покрытию, вычислительная сложность Алгоритма 3 составляет O⁡(|E|​log⁡|P|)O(|E|\log|P|).

4.3. Жадный τ⁡(G)\tau(G) минимизация: стимул для 𝒫⁡(G)\mathcal{P}(G)

Эта эвристика предназначена для поиска порядка удаления, который аппроксимирует оценку bus factor 𝒫⁡(𝒢)\mathcal{P(G)}. Концептуально она похожа на эвристику Minimum Coverage тем, что работает в обратном порядке, добавляя в π\pi человека, который вносит наименьший вклад в рост τ⁡(G)\tau(G). Таким образом, люди, вносящие наибольший вклад в рост τ⁡(G)\tau(G), оказываются одними из последних, кто добавляется в π\pi. Как и в случае с Minimum Coverage, порядок удаления представляет собой π\pi в обратном порядке.

Процесс также может быть остановлен, когда τ⁡(G)\tau(G) достигает определенного порога tt, заданного на входе; таким образом, жадная минимизация τ⁡(G)\tau(G) может быть объединена с Минимальным покрытием или Максимальным покрытием для получения меньших значений 𝒫⁡(G)\mathcal{P}(G).

Эта эвристика не подходит для приближенного вычисления A⁡(G,t)A(G,t), поскольку увеличение τ⁡(G)\tau(G) как можно медленнее может фактически потребовать привлечения человека к задаче для поддержания τ⁡(G)\tau(G) на низком уровне. Такой шаг, однако, позволил бы охватить все задачи на раннем этапе, максимизируя покрытие.

4.3.1. Описание алгоритма

Эвристика принимает граф GG и пороговое значение tt на вход и работает конструктивно. Сначала она инициализирует граф 𝒰\mathcal{U}, который содержит только набор узлов задач и не содержит людей. На каждой итерации выбирается и добавляется в π\pi тот человек pp, включение которого приводит к наименьшему возможному увеличению τ⁡(G)\tau(G). Затем человек pp добавляется в 𝒰\mathcal{U} со всеми своими связями. Процесс повторяется на обновленном 𝒰\mathcal{U} до тех пор, пока добавление еще одного человека в него не сделает τ⁡(G)>t\tau(G)>t.

⟦Algorithm 4 Жадная τ⁡(G)\tau(G) минимизация
Входные данные: двудольный граф G=(P,T,E)G=(P,T,E), порог t≤|T|t\leq|T|
Вывод: Упорядочивание π\pi людей
1 𝒰←UnionFind(|T|)\mathcal{U}\leftarrow\texttt{UnionFind(|T|)};
2 Γ⁡[p]←[]​∀p∈P\Gamma[p]\leftarrow[]\;\forall p\in P;
3 𝒬←MinHeap()\mathcal{Q}\leftarrow\texttt{MinHeap()};
4 π←[]\pi\leftarrow[];
5 для каждого p∈Pp\in P выполнять
    6 (roots,τp)←𝒰.resulting_size(G.neighbors(p))(\text{roots},\tau_{p})\leftarrow\mathcal{U}.\texttt{resulting\_size}(G.\texttt{neighbors($p$)});
    7 Γ⁡[p]←roots\Gamma[p]\leftarrow\texttt{roots};
    8 𝒬.push​((,,,))\mathcal{Q}.\texttt{push}((\tau_{p},p));
9 в то время как 𝒬\mathcal{Q} не пусто делать
    10 (priority,p)←𝒬.pop()(\texttt{priority},p)\leftarrow\mathcal{Q}.\texttt{pop()};
    11 old_roots←Γ⁡[p]\texttt{old\_roots}\leftarrow\Gamma[p] ;
    12 (new_roots,τp)←𝒰.resulting_size​(old_roots)(\texttt{new\_roots},\tau_{p})\leftarrow\mathcal{U}.\texttt{resulting\_size}(\texttt{old\_roots});
    13 если τp>priority\tau_{p}>\texttt{priority} затем
       14 𝒬.push​((,,,))\mathcal{Q}.\texttt{push}((\tau_{p},p));
       15 Γ⁡[p]←new_roots\Gamma[p]\leftarrow\texttt{new\_roots};
       16 продолжить;
    17 если priority>t\texttt{priority}>t затем
       18 разрыв;
    19 𝒰.union​(old_roots)\mathcal{U}.\texttt{union}(\texttt{old\_roots});
    20 π.append(p)\pi.\texttt{append($p$)};
21 вернуть π\pi.обратный( );

4.3.2. Детали реализации

Жадная минимизация τ⁡(G)\tau(G) на каждом шаге порождает серьезные вычислительные трудности. В частности, оценка предельного увеличения τ⁡(G)\tau(G), вызванного добавлением человека, требует вычисления компонент связности GG. Стандартный поиск в глубину (DFS) для компонент связности имеет стоимость O⁡(|P|+|T|+|E|)O(|P|+|T|+|E|). Наивная реализация жадного эвристического алгоритма выполняла бы этот поиск в глубину для каждого оставшегося человека на каждой итерации.

В результате стоимость одной итерации составляет O⁡(|P|⋅(|P|+|T|+|E|))O(|P|\cdot(|P|+|T|+|E|)). Поскольку этот процесс повторяется в течение |P||P| раундов (каждый добавляет по одному человеку), общая временная сложность становится равной: O⁡(|P|2⋅(|P|+|T|+|E|))=O⁡(|P|3+|P|2​|T|+|P|2​|E|)O(|P|^{2}\cdot(|P|+|T|+|E|))=O(|P|^{3}+|P|^{2}|T|+|P|^{2}|E|), что является неприемлемым даже для графов умеренного размера.

Именно поэтому в Алгоритме 4 мы используем структуру данных для поиска объединения с сжатием путей и объединением по рангу для эффективного отслеживания компонентов GG и τ⁡(G)\tau(G). Кроме того, мы используем лениво обновляемую очередь с приоритетами, где мы расставляем приоритеты разработчиков по их вкладу в τ⁡(G)\tau(G) и останавливаем процесс, когда τ⁡(G)>t\tau(G)>t. Функция resulting_size(⋅\cdot) симулирует добавление pp и их связей с 𝒰\mathcal{U} и возвращает компоненты, к которым pp был бы подключен после добавления (new_roots), и результирующее значение τ⁡(G)\tau(G).

Используя структуру union-find, мы можем запросить τ⁡(G)\tau(G) за O⁡(1)O(1) и выполнить операцию union за O⁡(α⁡(|T|))O(\alpha(|T|)), где α\alpha — это обратная функция Аккермана, которая растет очень медленно и на практике может считаться константой. Следовательно, отслеживание связанных компонентов на протяжении всего процесса требует |E||E| операций union. Поэтому вычислительная сложность Алгоритма 4 в среднем составляет O⁡(|E|​log⁡|P|)O(|E|\log|P|). Однако, если GG плотный, добавление человека может привести к обновлению всех оставшихся людей в 𝒬\mathcal{Q}, требуя O⁡(|P|2)O(|P|^{2}) обновлений. Таким образом, в худшем случае вычислительная сложность Алгоритма 4 составляет O⁡(|P|2​log⁡|P|)O(|P|^{2}\log|P|).

Именно поэтому мы предлагаем объединить алгоритм 4 с одной из ранее рассмотренных эвристик, используя небольшой порог tt для приближенной оценки показателя bus factor 𝒫⁡(G)\mathcal{P}(G).

Рисунок, показывающий эффективность объединения жадной минимизации тау с эвристиками минимального покрытия и максимального покрытия.

⟦Figure 2. Анализ пороговых значений для жадной эвристики минимизации τ⁡(G)\tau(G) в сочетании с минимальным покрытием и максимальным покрытием. t=0t=0 означает, что жадная эвристика минимизации τ⁡(G)\tau(G) не применялась. Рисунок, демонстрирующий эффективность сочетания жадной минимизации тау с эвристиками минимального и максимального покрытия..

Мы предлагаем вычислить частичный порядок πr\pi_{r} с помощью алгоритма 4 с небольшим порогом (таким как t=0.01×|T|t=0.01\times|T|), а затем использовать минимальное покрытие или максимальное покрытие на графе G=({P∖πr},T,E)G=(\{P\setminus\pi_{r}\},T,E) для вычисления частичного порядка πl\pi_{l}. Итоговый порядок задается выражением π=[πl|πr]\pi=[\pi_{l}|\pi_{r}]. На рисунке 2 мы показываем эффективность такой стратегии. Мы сгенерировали двудольный степенной граф с помощью алгоритма 1, установив |P|=|T|=1000|P|=|T|=1000, λP=λT=0.5\lambda_{P}=\lambda_{T}=0.5 и kP=kT=10k_{P}=k_{T}=10, и аппроксимировали кривую затухания τ⁡(G)\tau(G) с помощью как минимального покрытия, так и максимального покрытия, варьируя порог tt. Помня, что 𝒫⁡(G)\mathcal{P}(G) представляет собой площадь под кривой затухания τ⁡(G)\tau(G), мы можем заметить, что применение этой смешанной стратегии оправдывает себя для обеих эвристик.

Для t=0t=0, то есть исходной эвристики без применения алгоритма 4, мы наблюдаем наибольшую площадь под кривой (0,4 для минимального покрытия и 0,46 для максимального покрытия). По мере увеличения значения tt можно заметить, что площадь под кривой уменьшается. Например, для t=10t=10 мы получаем площадь под кривой 0,35 для минимального покрытия и 0,37 для максимального покрытия. Однако бесконечное увеличение порогового значения tt не обязательно приводит к улучшениям: для минимального покрытия площадь под кривой остается равной 0,35 как для t=50t=50, так и для t=100t=100, в то время как для максимального покрытия площадь под кривой остается равной 0,36 как для t=50t=50, так и для t=100t=100. Таким образом, выбор слишком высокого порогового значения tt, скорее всего, потребует лишь больших вычислительных затрат, не давая никаких преимуществ по сравнению с меньшими пороговыми значениями..

В заключение отметим, что для t=|T|t=|T| алгоритм 4 завершает работу, когда обработаны все люди из PP; однако, как станет ясно из наших экспериментов в разделе 5, такое неограниченное применение алгоритма 4 уступает предложенной здесь смешанной стратегии..

5. Экспериментальная оценка

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

Accuracy::

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

Scalability::

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

Sensitivity to Structure::

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

Мы реализовали наши эвристики на чистом Python 3.10 с использованием библиотеки networkx для работы с графами и стандартного модуля heapq для реализации очереди с приоритетами. Кроме того, мы реализовали собственную структуру union-find со сжатием путей и объединением по рангу на Python, используя компиляцию с опережением времени через библиотеку numba. Мы провели следующие эксперименты на ноутбуке с 32 ГБ оперативной памяти и процессором 2,9 ГГц.

5.1. Анализ точности

⟦Table 1. Производительность для каждого эвристического метода на синтетическом наборе данных, сгруппированная по метрикам. Коэффициенты разрыва (средний, минимальный, максимальный) вычисляются относительно лучшей стратегии (меньше — лучше)).
Measure Heuristic % 1st ↑\uparrow Gap Ratio (ss∗)\left(\frac{s}{s^{*}}\right) ↓\downarrow
avg min max
Avelino et al.(Avelino et al., 2016) A⁡(G,0.5)A(G,0.5) min_cov 83.6 1.01 1.0 1.40
max_cov 6.6 1.05 1.0 1.21
greedyI 9.8 1.74 1.0 4.64
degree 0 1.15 1.01 2.37
combined 90.2 1.0 1.0 1.02
Piccolo et al.(Piccolo et al., 2024) 𝒫⁡(G)\mathcal{P}(G) min_covτ 78.7 1.0 1.0 1.03
max_covτ 13.2 1.03 1.0 1.07
greedyτ 8.1 1.05 1.0 1.15
degree 0 1.09 1.04 1.28
combined 91.9 1.0 1.0 1.01

Оценка качества наших эвристик сопряжена с определенными трудностями: лежащие в их основе задачи оптимизации являются NP-трудными, а получение оптимальных решений вычислительно невыполнимо даже на графах умеренного размера. Более того, для этой конкретной задачи не существует стандартных эталонных наборов данных. Чтобы преодолеть это, мы создаем большой и разнообразный синтетический набор данных, который отражает асимметричные распределения степеней, обычно наблюдаемые в реальных проектах (Piccolo et al., 2018; Yamashita et al., 2015; Majumder et al., 2019; Torchiano et al., 2011).

5.1.1. Генерация датасета

Мы используем Алгоритм 1 для генерации 1000 двудольных графов, используя процесс выборки по степенному закону с параметрами, выбранными равномерно и случайно из следующих диапазонов:

|P|\displaystyle|P| ∈[1 000,2 000]\displaystyle\in[1\,000,2\,000] |T|\displaystyle|T| ∈[1 000,2 000]\displaystyle\in[1\,000,2\,000]
λP\displaystyle\lambda_{P} ∈[0.3,0.7]\displaystyle\in[0.3,0.7] λT\displaystyle\lambda_{T} ∈[0.3,0.7]\displaystyle\in[0.3,0.7]
kP\displaystyle k_{P} ∈[50,300]\displaystyle\in[50,300] kT\displaystyle k_{T} ∈[50,300]\displaystyle\in[50,300]

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

5.1.2. Условия оценки

Мы оцениваем эвристики как на A⁡(G,t)A(G,t), с t=0.5t=0.5, как указано Avelino et al.(Avelino et al., 2016), так и на 𝒫⁡(G)\mathcal{P}(G). Для A⁡(G,0.5)A(G,0.5) мы сравниваем Minimum Coverage, Maximum Coverage, удаление по степени и базовую жадную эвристику, которая удаляет на каждом шаге человека, изолирующего наибольшее число задач (называемую greedyI). Для 𝒫⁡(G)\mathcal{P}(G) мы сравниваем Minimum Coverage и Maximum Coverage, дополненные жадной минимизацией τ⁡(G)\tau(G) (с t=10t=10), удаление по степени и несвязанную версию жадной минимизации τ⁡(G)\tau(G) (называемую greedyτ). Мы также рассматриваем простой ансамблевый метод: combined=min⁡(min_cov,max_cov)\texttt{combined}=\min(\text{min\_cov},\text{max\_cov}).

Поскольку эти эвристики вычисляют верхние оценки, более низкие значения строго лучше. Чтобы количественно оценить относительную производительность, мы вычисляем: процент графов, для которых каждая эвристика возвращает наилучшую оценку (то есть наименьший показатель), а также среднее, минимальное и максимальное значения коэффициента зазора, где коэффициент зазора определяется как s/s∗s/s^{*}, где ss — это оценка эвристики, а s∗s^{*} — наилучшая оценка, полученная среди всех эвристик для данного экземпляра.

5.1.3. Результаты

В таблице 1 обобщены результаты. Мы наблюдаем, что Минимальное покрытие (min_cov) в целом является наиболее эффективным эвристическим методом, находят наименьшее значение в 83.6% случаев для A⁡(G,0.5)A(G,0.5) и в 78.7% случаев для 𝒫⁡(G)\mathcal{P}(G). Он также характеризуется наименьшим средним соотношением разрывов. Максимальное покрытие (max_cov) находит лучшее решение в 6.6% случаев для A⁡(G,0.5)A(G,0.5) и в 13.2% случаев для 𝒫⁡(G)\mathcal{P}(G), отличаясь наименьшим максимальным соотношением разрывов для A⁡(G,0.5)A(G,0.5). Примечательно, что эвристика степени никогда не находит лучшее решение и характеризуется наибольшим средним соотношением разрывов (за исключением greedyI для A⁡(G,0.5)A(G,0.5)).

Базовый жадный алгоритм greedyI, несмотря на поиск лучшего решения в 9.8% случаев, демонстрирует худшее соотношение разрыва. Также эвристический алгоритм greedyτ не впечатляет на 𝒫⁡(G)\mathcal{P}(G), показывая лишь немного лучшую производительность, чем эвристика степени, несмотря на свои вычислительные затраты. Низкая производительность этих двух жадных эвристик иллюстрирует сложность аппроксимации bus-factor, поскольку две естественные жадные эвристики, разработанные для решения своей конкретной целевой функции, в целом работают хуже (или в лучшем случае наравне) универсальной эвристики, такой как степень.

Наконец, комбинированный подход еще больше повышает производительность и, помимо очевидного увеличения процента случаев, когда он находит наилучшее решение, он также демонстрирует взаимодополняемость между Минимальным Покрытием и Максимальным Покрытием: будучи объединенными вместе, эти две эвристики достигают меньшего максимального отношения разрыва, чем любая из них по отдельности.

5.2. Анализ времени выполнения

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

⟦Figure 3. Анализ времени выполнения. Все эвристики масштабируются до очень больших графов с миллионами узлов и ребер. График времени выполнения эвристик, разработанных в данной работе, который показывает, что наши эвристики являются быстрыми и масштабируемыми.

Для оценки масштабируемости наших эвристик мы проводим серию экспериментов по измерению времени на наборе синтетических двудольных графов увеличивающегося размера. В частности, мы генерируем семь случайных двудольных графов, где количество узлов NN для каждого набора узлов (мы задаем |P|=|T|=N|P|=|T|=N) распределено по логарифмической шкале в диапазоне [103,106][10^{3},10^{6}]. Вероятность соединения установлена равной p=log⁡(5​N)/Np=\log(5N)/N, что гарантирует медленный рост ожидаемой степени с ростом размера графа и сохранение связности графа с высокой вероятностью..

⟦Table 2. Корреляция между структурными свойствами графа и коэффициентом погрешности для каждого эвристического алгоритма. Положительная корреляция указывает на то, что ошибка (коэффициент погрешности) возрастает по мере увеличения значения структурного признака. И наоборот, отрицательный коэффициент корреляции означает, что коэффициент погрешности уменьшается с ростом значения признака. Жирным шрифтом выделено |ρ|>0.3|\rho|>0.3
Structural
property
A⁡(G,t)A(G,t) 𝒫⁡(G)\mathcal{P}(G)
min_cov max_cov greedyI degree min_covτ max_covτ greedyτ degree
|P||P| -0.01 0.14 0.23 -0.02 0.11 0.03 0.06 0.04
|T||T| -0.03 -0.09 -0.22 0 -0.13 -0.06 -0.06 -0.04
λP\lambda_{P} -0.01 -0.03 0.06 -0.09 -0.01 0.14 0.09 0.01
λT\lambda_{T} 0.03 -0.06 -0.19 -0.03 -0.04 -0.17 -0.03 -0.14
kPk_{P} -0.27 0.41 0.49 -0.58 -0.35 0.54 -0.31 -0.73
kTk_{T} 0.21 -0.64 -0.62 0.34 0.22 -0.70 0.39 0.52
δ⁡(G)\delta(G) -0.09 -0.15 -0.27 -0.35 -0.23 -0.10 0.06 -0.26
r⁡(G)r(G) -0.17 0 -0.17 -0.41 -0.52 0.02 0.03 -0.35
# leaf people -0.22 0.65 0.85 -0.34 -0.14 0.75 -0.40 -0.53
# leaf tasks 0.29 -0.61 -0.56 0.68 0.29 -0.73 0.31 0.73

Мы выбираем случайные графы в стиле Эрдёша — Реньи для этого эксперимента потому, что, хотя они и не отражают асимметричные распределения степеней вершин, обычно встречающиеся в реальных проектах, в них отсутствуют структурные паттерны, которые могли бы быть использованы эвристиками, что делает их надежной базовой линией для измерения чистых вычислительных затрат. Полученные графы содержат от примерно 2,0002,000 до 2,000,0002,000,000 вершин и от примерно 8,4008,400 до более чем 15,000,00015,000,000 ребер. На каждом из этих экземпляров мы замеряем время выполнения минимального покрытия и максимального покрытия с жадной минимизацией τ⁡(G)\tau(G) и без нее, с пороговым значением t=10t=10.

Результаты показаны на рисунке 3, представлены в виде функции от количества узлов и в виде функции от количества ребер. Мы наблюдаем, что время выполнения всех эвристик находится в пределах O⁡(|E|​log⁡|P|)O(|E|\log|P|) (черная линия), что согласуется с нашим теоретическим анализом. Мы также обнаруживаем, что базовые эвристики работают немного быстрее, чем эвристики в сочетании с жадной минимизацией τ⁡(G)\tau(G). Наконец, мы отмечаем, что на самом большом графе с |P|=|T|=1,000,000|P|=|T|=1,000,000 узлами и |E|≈15,500,000|E|\approx 15,500,000 ребрами время выполнения эвристик составляет [123,176][123,176] секунд.

Это показывает, что наши эвристики работают быстро и масштабируются до очень больших двудольных графов. Учитывая, что мы написали код на чистом Python без попыток оптимизировать его производительность, мы полагаем, что время выполнения может быть дополнительно улучшено.

5.3. Чувствительность к структуре графа

Для понимания того, как структура входного графа влияет на производительность эвристик, мы анализируем корреляцию между эвристической ошибкой и различными структурными особенностями экземпляров графов. Наш анализ проводится на тех же 1 0001\,000 синтетических двудольных степенных графах, представленных ранее. Каждый граф характеризуется не только своими порождающими параметрами (например, показателями степени распределения и обрезаниями), но и производными структурными особенностями, включая:

  • • Плотность графа δ⁡(G)\delta(G), определяемая как отношение между количеством ребер и |P|×|T||P|\times|T|;
  • ⟦• Количество тупиковых людей и тупиковых задач (узлов со степенью 1);
  • ⟦• Degree assortativity r⁡(G)r(G), measured as the Pearson correlation between the degrees at both ends of each edge.

Мы вычисляем коэффициенты корреляции Пирсона между этими структурными признаками и коэффициентом погрешности для каждой эвристики (определяемым как отношение оценки эвристики к наилучшей оценке среди всех эвристик). В таблице 2 эти корреляции представлены отдельно для мер A⁡(G,t)A(G,t) и 𝒫⁡(G)\mathcal{P}(G).

5.3.1. Структурная устойчивость Минимальное покрытие

Первый заметный результат заключается в том, что минимальное покрытие в значительной степени нечувствительно к структуре графа. Для меры A⁡(G,t)A(G,t) коэффициент несоответствия никогда не демонстрирует корреляцию (по абсолютной величине) более 0,3 ни с одним структурным признаком, что указывает на высокую надежность. Для меры 𝒫⁡(G)\mathcal{P}(G) возникают две умеренные отрицательные корреляции: с ассоритивность степеней r⁡(G)r(G) (по Пирсону p=−0.52p=-0.52) и с максимальной степенью персоны kPk_{P} (p=−0.35p=-0.35). Такое поведение согласуется с предыдущими результатами в литературе по надежности сетей, где более высокая корреляция степеней связана с повышенной надежностью (Newman, 2003; Li et al., 2005; Artime et al., 2024; Piccolo et al., 2025). Отрицательная корреляция с kPk_{P} также отражает тот факт, что минимальное покрытие отдает приоритет узлам с высокой степенью на ранней стадии последовательности удаления, что приводит к меньшей ошибке в графах с индивидами высокой степени..

5.3.2. Максимальное покрытие дополняет Минимальное покрытие

Сравнение между минимальным покрытием и максимальным покрытием выявляет взаимодополняющее поведение. Коэффициент разрыва минимального покрытия положительно коррелирует с количеством листовых задач и максимальной степенью задачи kTk_{T}, а также отрицательно коррелирует с количеством листовых исполнителей и kPk_{P}. Максимальное покрытие, с другой стороны, демонстрирует противоположную закономерность: его ошибка положительно коррелирует с kPk_{P} и количеством листовых исполнителей, а также отрицательно коррелирует с kTk_{T} и количеством листовых задач..

Более того, Maximum Coverage не коррелирует с ассортативностью по степени, что дополнительно отличает его от Minimum Coverage. Эти результаты показывают, что, хотя графы с большим количеством листовых задач и асимметричным распределением степеней задач создают сложности для Minimum Coverage, они благоприятны для Maximum Coverage. И наоборот, конфигурации с большим количеством листовых узлов-людей препятствуют Maximum Coverage, но не Minimum Coverage. Эта структурная взаимодополняемость служит веским доводом в пользу совместного использования данных эвристик..

5.3.3. Structure-Sensitive Behavior of greedy Heuristics

Жадные эвристики проявляют большую чувствительность к структуре: greedyτ работает хорошо, когда количество листовых людей и kPk_{P} велики. В графах, где greedyτ дает наилучшую оценку, количество листовых людей в среднем в три раза больше, чем листовых задач, а kPk_{P} примерно в два раза больше kTk_{T}. Эти условия позволяют greedyτ эффективно изолировать компоненты при удалении узлов.

Напротив, greedyI испытывает трудности в таких сценариях. Наличие большого числа конечных людей, каждый из которых связан с отдельной задачей, ограничивает способность эвристики изолировать несколько задач за итерацию, что приводит к завышенным оценкам bus factor. Мы обнаруживаем, что greedyI работает лучше всего в графах с большим количеством конечных задач и высокой степенью асимметрии степеней задач. В подмножестве с наилучшими результатами число конечных задач в среднем в семь раз превышает число конечных людей, а kTk_{T} более чем в два раза превышает kPk_{P}.

6. Заключение

Понимание и снижение проектных рисков является центральной задачей в практике программной инженерии. В данной статье мы рассмотрели проблему оценки bus-factor программных проектов — ключевого показателя устойчивости проекта к потере разработчиков. Мы сосредоточились на двух устоявшихся формализациях из литературы, предложенных Avelino et al.(Avelino et al., 2016) и Piccolo et al.(Piccolo et al., 2024; Piccolo et al., 2025), каждая из которых создает вычислительные сложности из-за своей NP-трудности..

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

Мы подтвердили наш подход с помощью масштабных экспериментов на синтетических датасетах, которые моделируют асимметричную структуру реальных проектов. Наши эвристики стабильно обеспечивали более точные оценки bus-factor и масштабировались на графы с миллионами вершин и ребер за считанные минуты.

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

Благодарности.
Я благодарен Марио Альвиано, Паскуале Де Мео, Марко Манна, Симоне Перри и Альдо Ричиоппо за плодотворные беседы об идеях, лежащих в основе этой работы. Исследование частично поддержано Министерством университетов и исследований в рамках проекта PNRR, номер гранта H23C22000860006, PE0000013-FAIR, направление 9 - Greenaware AI – WP9.2.

Список литературы

  • ⟦Almarimi et al. (2023) Нури Алмарими, Али Оуни, Моатаз Шучен и Мохамед Вием Мкаоуэр. 2023. Улучшение обнаружения сообщественных запахов посредством социотехнического и сентимент-анализа. Journal of Software: Evolution and Process 35, 6 (2023), e2505. arXiv:https://onlinelibrary.wiley.com/doi/pdf/10.1002/smr.2505 doi:10.1002/smr.2505
  • ⟦Almarimi et al. (2020) Нури Альмарими, Али Оуни и Мохамед Вием Мкаоуэр. 2020. Обучение обнаружению запахов сообщества в проектах программного обеспечения с открытым исходным кодом. Системы, основанные на знаниях, 204 (2020), 106201. doi:10.1016/j.knosys.2020.106201
  • ⟦Artime et al. (2024) Ориол Артайм, Марко Грассия, Манлио Де Доменико, Джеймс П. Глисон, Эрнан А. Максе, Джузеппе Манджиони, Матьяж Перц и Филиппо Радиччи. 2024. Устойчивость и жизнестойкость сложных сетей. Nature Reviews Physics 6, 2 (2024), 114–131.
  • ⟦Avelino et al. (2016) Гильерме Авелино, Леонардо Пассос, Андре Хора и Марко Тулио Валенте. 2016. Новый подход к оценке коэффициентов значимости разработчиков (Truck Factors). В материалах 24-й Международной конференции IEEE по пониманию программ (ICPC) 2016 года. 1–10. doi:10.1109/ICPC.2016.7503718
  • ⟦Catolino et al. (2021) Джемма Католино (Gemma Catolino), Фабио Паломба (Fabio Palomba), Дамиан А. Тамбурри (Damian A. Tamburri) и Александр Серебреник (Alexander Serebrenik). 2021. Понимание изменчивости запахов сообщества: статистический подход. В: Материалы 43-й Международной конференции IEEE/ACM по инженерии программного обеспечения 2021 года: Инженерия программного обеспечения в обществе (ICSE-SEIS). 77–86. doi:10.1109/ICSE-SEIS52602.2021.00017
  • ⟦Catolino et al. (2020) Джемма Католино, Фабио Паломба, Дамиан А. Тамбурри, Александер Серебреник и Филомена Ферруччи. 2020. Рефакторинг технологических запахов сообщества в естественных условиях: полевое руководство практика. В трудах 2020 IEEE/ACM 42-й Международной конференции по программной инженерии: программная инженерия в обществе (ICSE-SEIS). 25–34.
  • ⟦Cosentino et al. (2015) Валерио Косентино, Хавьер Луис Кановас Искьердо и Жорди Кабот. 2015. Оценка фактора автобуса Git-репозиториев. В 2015 IEEE 22nd International Conference on Software Analysis, Evolution, and Reengineering (SANER). 499–503. doi:10.1109/SANER.2015.7081864
  • ⟦Ferreira et al. (2017) Мивиан Феррейра, Марко Тулио Валенте и Кесия Феррейра. 2017. Сравнение трех алгоритмов вычисления truck factors. В: 2017 IEEE/ACM 25th International Conference on Program Comprehension (ICPC). 207–217. doi:10.1109/ICPC.2017.35
  • ⟦Fritz et al. (2014) Томас Фриц, Гейл С. Мерфи, Эмерсон Мерфи-Хилл, Цзинвэнь Оу и Эмили Хилл. 2014. Степень знаний: Моделирование знаний разработчика о коде. ACM Transactions on Software Engineering and Methodology (TOSEM) 23, 2 (2014), 1–42.
  • ⟦Hannebauer and Gruhn (2014) Кристоф Ханнебауэр и Фолькер Грун. 2014. Алгоритмическая сложность расчета фактора автобуса. В сборнике: Улучшение программных процессов, ориентированное на продукт: 15-я международная конференция, PROFES 2014, Хельсинки, Финляндия, 10–12 декабря 2014 г. Труды 15. Springer, 119–133.
  • ⟦Heath and Staudenmayer (2000) Chip Heath and Nancy Staudenmayer. 2000. Coordination neglect: How lay theories of organizing complicate coordination in organizations. Research in organizational behavior 22 (2000), 153–191.
  • ⟦Jabrayilzade et al. (2022) Элгун Джабраилзаде, Михаил Евтихиев, Эрай Тюзюн и Владимир Коваленко. 2022. Фактор автобуса на практике. В Трудах 44-й Международной конференции по программной инженерии: Программная инженерия на практике (Питтсбург, Пенсильвания) (ICSE-SEIP ’22). Ассоциация вычислительной техники, Нью-Йорк, штат Нью-Йорк, США, 97–106. doi:10.1145/3510457.3513082
  • ⟦Lawrence and Lorsch (1986) Пол Р. Лоуренс и Джей Уильям Лорш. 1986. Организация и среда: Управление дифференциацией и интеграцией. Издательство Гарвардской школы бизнеса.
  • ⟦Li et al. (2005) Лун Ли, Дэвид Алдерсон, Джон К. Дойл и Уолтер Виллингер. 2005. К теории масштабируемо-свободных графов: определение, свойства и следствия. Интернет Математикс 2, 4 (2005), 431–523.
  • ⟦Lisan and Norris (2024) Ализа Лисан и Бояна Норрис. 2024. Направление распределения усилий в проектах программного обеспечения с открытым исходным кодом с использованием анализа фактора автобуса. arXiv препринт arXiv:2401.03303 (2024).
  • ⟦Majumder et al. (2019) Суводип Маджумдер, Джоймалья Чакраборти, Амританшу Агравал и Тим Мензис. 2019. Почему программным проектам нужны герои (уроки, извлеченные из более чем 1100 проектов). Препринт arXiv: arXiv:1904.09954 (2019)).
  • ⟦Newman (2003) Mark EJ Newman. 2003. Mixing patterns in networks. Physical review E 67, 2 (2003), 026126.
  • ⟦Palomba et al. (2021) Fabio Palomba, Damian Andrew Tamburri, Francesca Arcelli Fontana, Rocco Oliveto, Andy Zaidman, and Alexander Serebrenik. 2021. Beyond Technical Aspects: How Do Community Smells Influence the Intensity of Code Smells? IEEE Transactions on Software Engineering 47, 1 (2021), 108–129. doi:10.1109/TSE.2018.2883603
  • ⟦Piccolo et al. (2025) Себастиано Пикколо, Паскуале Де Мео, Джорджо Террачина и Джанлуиджи Греко. 2025. Теория и практика расчета фактора автобуса. Рабочий документ SSRN. (2025). doi:10.2139/ssrn.5195361
  • ⟦Piccolo et al. (2024) Себастиано А. Пикколо, Паскуале Де Мео и Джорджо Террачина. 2024. Оценка и улучшение bus-factor проектов: сетевой аналитический подход. In 16th International Conference, ASONAM 2024, Rende, Italy, September 2–5, 2024, Proceedings, Part I (Rende, Italy) (LNCS). Springer.
  • Piccolo et al. (2018) Sebastiano A Piccolo, Sune Lehmann, and Anja Maier. 2018. Design process robustness: a bipartite network analysis reveals the central importance of people. Design Science 4 (2018), e1.
  • ⟦Piccolo et al. (2022) Себастиано А Пикколо, Суне Леманн и Аня М Майер. 2022. Разные сети для разных целей: Сетевой научный взгляд на сотрудничество и коммуникацию в проекте инженерного проектирования. Компьютеры в промышленности 142 (2022), 103745.
  • ⟦Ricca et al. (2011) Филиппо Рикка, Алессандро Маркетто и Марко Торчиано. 2011. О сложности вычисления фактора автобуса. В сборнике трудов 12-й Международной конференции по улучшению процессов разработки ПО, ориентированному на продукт (Торре-Канне, Италия) (PROFES’11). Шпрингер-Ферлаг, Берлин, Хайдельберг, 337–351.
  • Rigby et al. (2016) Peter C. Rigby, Yue Cai Zhu, Samuel M. Donadelli, and Audris Mockus. 2016. Quantifying and Mitigating Turnover-Induced Knowledge Loss: Case Studies of Chrome and a Project at Avaya. In 2016 IEEE/ACM 38th International Conference on Software Engineering (ICSE). 1006–1016. doi:10.1145/2884781.2884851
  • ⟦Torchiano et al. (2011) Marco Torchiano, Filippo Ricca, and Alessandro Marchetto. 2011. Is my project’s truck factor low? theoretical and empirical considerations about the truck factor threshold. In Proceedings of the 2nd International Workshop on Emerging Trends in Software Metrics (Waikiki, Honolulu, HI, USA) (WETSoM ’11). Association for Computing Machinery, New York, NY, USA, 12–18. doi:10.1145/1985374.1985379
  • ⟦Yamashita et al. (2015) Кадзухиро Ямасита, Шейн Макинтош, Ясутака Камей, Ахмед Э. Хассан и Наоясу Убаяси. 2015. Пересмотр применимости принципа Парето к основным командам разработки в проектах открытого программного обеспечения. В: Труды 14-го Международного семинара по принципам эволюции программного обеспечения (Бергамо, Италия) (IWPSE 2015). Ассоциация вычислительной техники, Нью-Йорк, штат Нью-Йорк, США, 46–55. doi:10.1145/2804360.2804366
  • ⟦Zazworka et al. (2010) Нико Зазворка, Кай Штапель, Эрик Кнаусс, Форрест Шулл, Виктор Р. Базили и Курт Шнайдер. 2010. Соблюдают ли разработчики процесс: исследование экстремального программирования. В материалах doi:10.1145/1852786.1852805