代表节点树作为列表

时间:2018-06-12 08:23:07

标签: python arrays python-3.x list

我有两组数据A和B,A是起始节点,B是结束节点。在每个集合中,存在节点的编号,该节点的X坐标和Y坐标,如下所示。读取该表,因为节点0连接到节点1,节点1连接到节点2,节点0也连接到节点3,依此类推。

$investments_details_sum=array();
$results = $wpdb->get_results("SELECT meta_key, meta_value, post_id FROM $wpdb->postmeta WHERE meta_key like 'investments_details'");
foreach($results as $result){
 $investments_details=unserialize($result->meta_value);
$investments_details_sum[$result->post_id] = $investments_details['funding'] + $investments_details['ownContribution'];
}
var_dump($investments_details_sum);

每个列表都是一个数组,所以总共有六个数组。

我想提取数据,以便我可以通过坐标读取每一段线。一段线由一组节点定义,这些节点的起点和终点是交叉点节点或终点节点:交叉点节点连接到两个以上的其他节点,而末端节点仅连接到另一个节点。

在此示例中,最终结果应为:

  A          X_A           Y_A             B            X_B            Y_B
 --------------------------------------------------------------------------
 0           x_0           y_0             1            x_1            y_1
 1           x_1           y_1             2            x_2            y_2
 0           x_0           y_0             3            x_3            y_3
 2           x_2           y_2             4            x_4            y_4
 0           x_0           y_0             5            x_5            y_5
 3           x_3           y_3             6            x_6            y_6
 1           x_1           y_1             7            x_7            y_7

我很惊讶如何用python做这件事,感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

似乎一个简单的DFS就可以解决这个问题。我将中间节点定义为thoses 谁有两个邻居。您定义了两个规则:

  • 我们不能从中间节点开始,我们不能停止使用中间节点。
  • 每个段至少有两个节点(隐式)。

代码:

class SegmentFinder():
    def __init__(self, A, B):
        # create the adjacency lists
        self.__d = {}
        self.__reverse_d = {}
        for a,b in zip(A,B):
            self.__d.setdefault(a, []).append(b)
            self.__reverse_d.setdefault(b, []).append(a)

    def find(self):
        for n in self.__d:
            if not self.__is_middle_node(n): # we can't start with a middle node
                yield from self.__dfs([n])

    def __dfs(self, segment):
        # We don't need to store the visited nodes, since we start with a non middle
        # node. If it has 1 neighbour, we won't be back. If it has more than 2,
        # then it will end the search.
        n = segment[-1]
        if len(segment) == 1 or self.__is_middle_node(n): # we can't stop with a middle node
            for n2 in self.__d[n]:
                yield from self.__dfs(segment + [n2])
        else: # a segment has at least two nodes
            yield segment

    def __is_middle_node(self, n):
        """Exactly two neighbours"""
        return len(self.__d.get(n, [])) == 1 and len(self.__reverse_d.get(n, [])) == 1

s = SegmentFinder(A, B)
list(s.find())
# [[1, 2, 4], [1, 7], [0, 3, 6], [0, 1], [0, 5]]

要添加坐标,只需使用x,y映射路径中的节点。对于任何图形算法,通常只在节点id上工作并在以下后添加“ornements”更容易:

coords = dict(zip(A+B, zip(xa+xb,ya+yb)))
[coords[n] for path in s.find() for n in path]