识别哪个接近的数字对应于哪个输入



上下文:我有一个奇怪的问题:让我们考虑 2 个元组,其中一个是另一个大小为 N-1 的元组的子集。

node = (40, 50, 60, 80)
adj_node = (40, 50, 60)

如您所见,我将这些组合称为网络图中的节点。前缀adj_代表adjacent。该算法正在为图形着色,即它为每个节点找到一个替代值。后缀alt_将代表alternative

nodeadj_node均在公差范围内提供 1 种备选方案。此函数的目标是计算两个备选方案之间的偏差。

def compute_deviation_between_node_alternative_and_adj_node_alternative(node,
node_alt, adj_node, adj_node_alt):
"""
4 tuples in input, the node, the node alternative, the adjacent node, and 
the adjacent node alternatives.
"""
# Compute
return deviation

让我们考虑以下输入:

node = (40, 50, 60, 80)
node_alt = (39, 48, 59, 87)
adj_node = (40, 50, 60)
adj_node_alt = (42, 55, 59)

来自节点或adj_node的每个值都替换为 +/- 10% 容差范围内的替代值。因此,40成为节点备择中的39,并在相邻node_alternative中42。 可能无法订购替代品。即node_alt本来可以(48, 39, 87, 59). 公差带可以重叠,例如对于605559都在公差带内。

代码中存在问题的部分:我尝试实现的步骤是我所说的识别步骤:找出哪个替代值对应于哪个输入值。为此,我计算值之间的距离并返回替代值所在的 id(或 idx)。

tolerances = [0.1 if x <= 100 else 0.2 for x in node]
distance = dict()
alt_identification = dict()
for k, x in enumerate(node):
distance[k] = [abs(elt-1) for elt in [alt_x/x for alt_x in node_alt]]
alt_identification[x] = list(np.where([elt <= tolerances[k]+0.00001 for elt in distance[k]])[0])

对于上面的示例,输出为:

alt_identification
Out[67]: {40: [0], 50: [1], 60: [2], 80: [3]}

对相邻节点备选方案执行相同的操作。

distance = dict()
adj_alt_identification = dict()
for k, x in enumerate(node):
distance[k] = [abs(elt-1) for elt in [alt_x/x for alt_x in adj_node_alt]]
adj_alt_identification[x] = list(np.where([elt <= tolerances[k]+0.00001 for elt in distance[k]])[0])

输出:

adj_alt_identification
Out[66]: {40: [0], 50: [1], 60: [1, 2], 80: []}

问题:我可能会发生不同的情况。

场景 1:每个值都已标识为一个替代值。例如,输出{40: [0], 50: [1], 60: [2], 80: [3]}node就是这种情况。

场景 2:某些输入值被标识为 2 个或更多不同的可能替代值。这可能是由于公差带重叠而发生的。例如

adj_node = (40, 50, 60)
adj_node_alt = (42, 55, 54)

5554都包含在5060的公差范围内。 输出将是(如果节点(40, 50, 60, 80)):

adj_alt_identification 出[66]: {40: [0], 50: [1, 2], 60: [1, 2], 80: []}

场景 3:上一个示例中的情况是adj_alt

adj_node = (40, 50, 60)
adj_node_alt = (42, 55, 59)

5559包含在60的公差范围内。50的公差带中仅包括55

当前输出为:

adj_alt_identification
Out[66]: {40: [0], 50: [1], 60: [1, 2], 80: []}

相应的输出会发现60不能取值55,因为它已经被50取了。因此,输出应为:

adj_alt_identification
Out[66]: {40: [0], 50: [1], 60: [2], 80: []}

如果有人对如何改进此代码以及如何在每种情况下获得正确的输出有任何想法,我很乐意听到它:)我觉得我的识别过程笨拙且效率低下......

当前代码导致正确的输出: 这是一团糟,显然效率低下...

def traceback(tuple_node, tuple_node_alt):
"""
Compute which value from tuple_node_alt comes from which value from tuple_node.
tuple_node is the input
tuple_node_alt is the "output"
"""
# Compute the tolerances based on the node
tolerances = [0.1 if f <= 100 else 0.2 for f in tuple_node]
# Traceback
distance = dict()
alt_identification = dict()
for k, x in enumerate(tuple_node):
distance[k] = [abs(elt-1) for elt in [alt_x/x for alt_x in tuple_node_alt]]
alt_identification[x] = list(np.where([elt <= tolerances[k]+0.00001 for elt in distance[k]])[0])
len_values = {key: len(val) for key, val in alt_identification.items()}
if all([x <= 1 for x in len_values.values()]):
return alt_identification
else:
for key, value in alt_identification.items():
if len(value) <= 1:
continue
else:
other_values = [val for k, val in alt_identification.items() if k != key]
if value in other_values:
continue
else:
for val in other_values:
set1 = set(value)
intersec = set1.intersection(set(val))
if len(intersec) == 0:
continue
else:
alt_identification[key] = [v for v in value if v not in intersec]
return alt_identification

相关内容

最新更新