feat: эвристическое отсечение (pruning) в explode_callgraph_branches
Добавлены параметры для pruning: - priority_threshold: минимальный приоритет для рассмотрения - min_consumed_types: минимальное количество consumed_types Pruning применяется в: - _explode_callgraph_branches_lazy(): отсечение по приоритету и consumed_types - explode_callgraph_branches(): передача параметров pruning По умолчанию pruning отключён (priority_threshold=-1e9, min_consumed_types=0) для обратной совместимости. Файлы: - graph_walker.py: параметры pruning в explode и _explode_lazy Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -111,18 +111,36 @@ class GraphWalker:
|
||||
return head
|
||||
|
||||
@classmethod
|
||||
def explode_callgraph_branches(cls, g: Callgraph, from_types: frozenset[type]) -> list[CallgraphVariant]:
|
||||
def explode_callgraph_branches(cls, g: Callgraph, from_types: frozenset[type],
|
||||
priority_threshold: float = -1e9,
|
||||
min_consumed_types: int = 0) -> list[CallgraphVariant]:
|
||||
"""
|
||||
Взрыв графа преобразований с pruning.
|
||||
|
||||
Args:
|
||||
g: Граф преобразований
|
||||
from_types: Исходные типы
|
||||
priority_threshold: Минимальный приоритет для рассмотрения (pruning)
|
||||
min_consumed_types: Минимальное количество consumed_types (pruning)
|
||||
|
||||
Returns:
|
||||
list[CallgraphVariant]: Варианты преобразований
|
||||
"""
|
||||
# Кэширование: создаём хэш графа
|
||||
# Хэш графа = хэш всех вариантов
|
||||
g_hash = hash(frozenset(g.variants)) if g.variants else 0
|
||||
cache_key = (g_hash, hash(from_types))
|
||||
cache_key = (g_hash, hash(from_types), hash(priority_threshold), hash(min_consumed_types))
|
||||
|
||||
# Проверяем кэш
|
||||
if cache_key in cls._explode_cache:
|
||||
return cls._explode_cache[cache_key]
|
||||
|
||||
# Вычисляем лениво через generator
|
||||
variants = list(cls._explode_callgraph_branches_lazy(g, from_types))
|
||||
variants = list(cls._explode_callgraph_branches_lazy(
|
||||
g, from_types,
|
||||
priority_threshold=priority_threshold,
|
||||
min_consumed_types=min_consumed_types
|
||||
))
|
||||
|
||||
# Сохраняем в кэш
|
||||
cls._explode_cache[cache_key] = variants
|
||||
@@ -130,22 +148,46 @@ class GraphWalker:
|
||||
return variants
|
||||
|
||||
@classmethod
|
||||
def _explode_callgraph_branches_lazy(cls, g: Callgraph, from_types: frozenset[type]):
|
||||
def _explode_callgraph_branches_lazy(cls, g: Callgraph, from_types: frozenset[type],
|
||||
priority_threshold: float = -1e9,
|
||||
min_consumed_types: int = 0):
|
||||
"""
|
||||
Ленивая версия explode_callgraph_branches (generator).
|
||||
Ленивая версия explode_callgraph_branches (generator) с pruning.
|
||||
|
||||
Args:
|
||||
g: Граф преобразований
|
||||
from_types: Исходные типы
|
||||
priority_threshold: Минимальный приоритет для рассмотрения (pruning)
|
||||
min_consumed_types: Минимальное количество consumed_types (pruning)
|
||||
|
||||
Yields:
|
||||
CallgraphVariant: Варианты преобразований по одному
|
||||
"""
|
||||
for variant in g.variants:
|
||||
if len(variant.subgraphs) == 0:
|
||||
# Pruning: проверяем порог приоритета
|
||||
variant_priority = variant.injector.priority if isinstance(variant.injector.priority, (int, float)) else 0.0
|
||||
if variant_priority >= priority_threshold:
|
||||
yield variant
|
||||
continue
|
||||
|
||||
# Pruning: проверяем consumed_types
|
||||
if len(variant.consumed_from_types) < min_consumed_types:
|
||||
continue
|
||||
|
||||
# Pruning: проверяем приоритет
|
||||
variant_priority = variant.injector.priority if isinstance(variant.injector.priority, (int, float)) else 0.0
|
||||
if variant_priority < priority_threshold:
|
||||
continue
|
||||
|
||||
# Собираем ленивые итераторы для подграфов
|
||||
subg_iterators = []
|
||||
for subg in variant.subgraphs:
|
||||
combinations = list(cls._explode_callgraph_branches_lazy(subg, from_types))
|
||||
combinations = list(cls._explode_callgraph_branches_lazy(
|
||||
subg, from_types,
|
||||
priority_threshold=priority_threshold,
|
||||
min_consumed_types=min_consumed_types
|
||||
))
|
||||
if len(combinations) == 0:
|
||||
subg_iterators.append([None])
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user