6#include "Algo/Unique.h"
7#include "Containers/Array.h"
8#include "Containers/ArrayView.h"
9#include "Containers/Map.h"
10#include "Containers/Set.h"
11#include "Misc/EnumClassFlags.h"
12#include "Templates/Invoke.h"
13#include "Templates/UnrealTemplate.h"
14#include "Traits/ElementType.h"
19
20
21
45 template <
typename RangeType,
typename GetElementDependenciesType>
47 GetElementDependenciesType GetElementDependencies, TSet<FKahnHandle>& OutInitialIndependents);
62 template <
typename RangeType,
typename GetElementDependenciesType>
161
162
163
164 template <
typename RangeType,
typename GetElementDependenciesType>
166 GetElementDependenciesType GetElementDependencies, TSet<FKahnHandle>& OutInitialIndependents)
220
221
222
225 if (!Context.MRVSContext.IsSet())
227 int32 NumVertices = Context.RemainingVertices.Num();
229 InitContext.VisitedReferences.Reserve(NumVertices);
230 InitContext.VisitedDependencies.Reserve(NumVertices);
231 InitContext.Culprits.Reserve(NumVertices);
232 InitContext.Stack.Reserve(NumVertices);
233 InitContext.Cycle.Reserve(NumVertices);
235 const TArray<TArray<FKahnHandle>>& Dependencies = Context.Dependencies;
236 const TArray<TArray<FKahnHandle>>& Referencers = Context.Referencers;
238 TSet<FKahnHandle>& VisitedReferences = MRVSContext.VisitedReferences;
239 TSet<FKahnHandle>& VisitedDependencies = MRVSContext.VisitedDependencies;
240 TSet<FKahnHandle>& MaximalMRVS = MRVSContext.MaximalMRVS;
241 TSet<FKahnHandle>& Culprits = MRVSContext.Culprits;
242 TArray<FKahnHandle>& Stack = MRVSContext.Stack;
243 TArray<FKahnHandle>& Cycle = MRVSContext.Cycle;
248 Culprits.Append(Context.RemainingVertices);
251 check(!Culprits.IsEmpty());
252 FKahnHandle StartingVertex = *Culprits.CreateIterator();
254 int32 StartingVertexLoopCount = 0;
258 VisitedReferences.Reset();
260 VisitedReferences.Add(StartingVertex);
261 Stack.Add(StartingVertex);
263 bool bCycleWitnessWasAlreadyInStack =
false;
264 while (!bCycleWitnessWasAlreadyInStack)
267 for (FKahnHandle Dependency : Dependencies[CycleWitnessVertex])
269 if (Culprits.Contains(Dependency))
271 NextVertex = Dependency;
276 check(NextVertex != INDEX_NONE);
277 CycleWitnessVertex = NextVertex;
278 VisitedReferences.Add(CycleWitnessVertex, &bCycleWitnessWasAlreadyInStack);
279 Stack.Add(CycleWitnessVertex);
285 check(Stack.Num() >= 2);
288 int32 StartIndex = Stack.Num() - 1;
289 while (StartIndex >= 0 && Stack[StartIndex] != CycleWitnessVertex)
293 check(StartIndex >= 0);
295 Cycle.Append(TArrayView<FKahnHandle>(Stack).Mid(StartIndex));
302 while (!Stack.IsEmpty())
304 FKahnHandle Vertex = Stack.Pop(
false );
305 for (FKahnHandle Referencer : Referencers[Vertex])
307 if (Culprits.Contains(Referencer))
309 bool bAlreadyVisited;
310 VisitedReferences.Add(Referencer, &bAlreadyVisited);
311 if (!bAlreadyVisited)
313 Stack.Add(Referencer);
320 VisitedDependencies.Reset();
322 for (FKahnHandle Vertex : Cycle)
324 VisitedDependencies.Add(Vertex);
327 while (!Stack.IsEmpty())
329 FKahnHandle Vertex = Stack.Pop(
false );
330 for (FKahnHandle Dependency : Dependencies[Vertex])
332 if (Culprits.Contains(Dependency))
334 bool bAlreadyVisited;
335 VisitedDependencies.Add(Dependency, &bAlreadyVisited);
336 if (!bAlreadyVisited)
338 Stack.Add(Dependency);
344 MaximalMRVS = VisitedDependencies.Intersect(VisitedReferences);
351 for (FKahnHandle Vertex : VisitedReferences)
353 Culprits.Remove(Vertex);
357 for (FKahnHandle Vertex : MaximalMRVS)
359 for (FKahnHandle Dependency : Dependencies[Vertex])
361 if (Culprits.Contains(Dependency))
363 StartingVertex = Dependency;
367 if (StartingVertex != INDEX_NONE)
375 checkf(StartingVertexLoopCount++ < Context.RemainingVertices.Num(), TEXT(
"Infinite loop in FindMostIndependentMutuallyReachableVertexSet"));
#define checkf(expr, format,...)
#define ENUM_CLASS_FLAGS(Enum)
bool KahnTopologicalSort(RangeType &UniqueRange, GetElementDependenciesType GetElementDependencies, ETopologicalSort Flags)
void KahnTopologicalSort_CreateWorkingGraph(FKahnContext &Context, RangeType &UniqueRange, GetElementDependenciesType GetElementDependencies, TSet< FKahnHandle > &OutInitialIndependents)
const TSet< FKahnHandle > & FindMostIndependentMutuallyReachableVertexSet(FKahnContext &Context)
TArray< int32 > DependencyCount
TArray< TArray< FKahnHandle > > Dependencies
TSet< FKahnHandle > RemainingVertices
TArray< TArray< FKahnHandle > > Referencers
TOptional< FMutuallyReachableVertexSetContext > MRVSContext
TSet< FKahnHandle > VisitedDependencies
TSet< FKahnHandle > VisitedReferences
TSet< FKahnHandle > MaximalMRVS
TArray< FKahnHandle > Stack
TSet< FKahnHandle > Culprits
TArray< FKahnHandle > Cycle