上下文:我有一个奇怪的问题:让我们考虑2个元组,其中一个是另一个大小为N-1的子集。
node = (40, 50, 60, 80)
adj_node = (40, 50, 60)
如您所见,我将这些组合称为网络图中的节点。前缀adj_
代表adjacent
。该算法正在为图形着色,即它为每个节点找到一个替代值。后缀alt_
代表alternative
。
在容差范围内,node
和adj_node
都提供了一种替代方法。此函数的目的是计算两个替代方案之间的偏差。
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)
。
公差带可以重叠,例如。对于60
,55
和59
都在公差带内。
该代码的问题部分:我试图实现的步骤是我所说的识别步骤:找出哪个替代值对应于哪个输入值。为此,我计算了两个值之间的距离,并返回替代值所在的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:已将每个值标识为一个替代值。例如,node
就是这种情况,其中输出为{40: [0], 50: [1], 60: [2], 80: [3]}
。
方案2:将某些输入值标识为2个或更多不同的可能替代值。这可能是因为公差带重叠。例如
adj_node = (40, 50, 60)
adj_node_alt = (42, 55, 54)
55
和54
的公差带中都包含50
和60
。
输出为(如果节点为(40, 50, 60, 80)
):
adj_alt_identification Out [66]:{40:[0],50:[1、2],60:[1、2],80:[]}
场景3:adj_alt
的上一示例就是这种情况:
adj_node = (40, 50, 60)
adj_node_alt = (42, 55, 59)
55
和59
包含在60
的公差带中。
55
的公差带中仅包含50
。
当前输出为:
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: []}
如果有人对如何改进此代码以及如何在每种情况下获得正确的输出有任何想法,我将很高兴听到它:)我觉得我的识别过程笨拙且效率低下...
>答案 0 :(得分:0)
当前代码可产生正确的输出:这是一团糟,效率低下...
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