我应该如何为中国邮递员问题生成分区/对?

发布于 2024-08-30 11:48:10 字数 1305 浏览 2 评论 0原文

我正在编写一个课程程序,涉及解决中国邮递员问题。我们的作业只需要我们编写一个程序来解决硬编码图的问题,但我正在尝试自己解决一般情况。

给我带来麻烦的部分是生成奇数顶点的配对分区。

例如,如果我在图中有以下标记的奇数顶点:

1 2 3 4 5 6

我需要找到可以用这些顶点进行的所有可能的配对/分区。

我发现我将给出 i 个分区:

  n = num of odd verticies  
  k = n / 2  
  i = ((2k)(2k-1)(2k-2)...(k+1))/2^n

因此,鉴于上面的 6 个奇数顶点,我们将知道需要生成 i = 15 分区。

15 个分区看起来像:

1 2   3 4   5 6
1 2   3 5   4 6
1 2   3 6   4 5
...
1 6   ...

然后,对于每个分区,我取出每一对分区,找到它们之间的最短距离,然后为该分区求和。选择其对之间总距离最小的分区,然后将奇数顶点之间的最短路径(在所选分区中找到)之间的所有边加倍。

这些代表邮递员必须走两次的边缘。

起初我以为我已经制定了一个合适的算法来生成这些分区:

  1. 从所有奇数顶点开始按升序排序

    12 34 56

  2. 选择当前具有最大顶点的对后面的对

    12 [34] 56

  3. 将此对中的第二个数字增加 1。将所有内容留给 所选对的左侧相同, 并使一切都在右边 所选对 剩余的 集合中的数字,已排序 增加订单。

    12 35 46

  4. 重复

但是,这是有缺陷的。例如,我意识到当我到达末尾并且选择对位于最左边的位置(即):

[16] .. ..

我计算出的算法将在这种情况下停止,并且不生成以 [16] 开头的其余对,因为它左侧没有要更改的对。

所以,它又回到了绘图板。

以前研究过这个问题的人是否有任何提示可以帮助我指明生成这些分区的正确方向?

I'm working on a program for class that involves solving the Chinese Postman problem. Our assignment only requires us to write a program to solve it for a hard-coded graph but I'm attempting to solve it for the general case on my own.

The part that is giving me trouble is generating the partitions of pairings for the odd vertices.

For example, if I had the following labeled odd verticies in a graph:

1 2 3 4 5 6

I need to find all the possible pairings / partitions I can make with these vertices.

I've figured out I'll have i paritions given:

  n = num of odd verticies  
  k = n / 2  
  i = ((2k)(2k-1)(2k-2)...(k+1))/2^n

So, given the 6 odd verticies above, we will know that we need to generate i = 15 partitions.

The 15 partions would look like:

1 2   3 4   5 6
1 2   3 5   4 6
1 2   3 6   4 5
...
1 6   ...

Then, for each partition, I take each pair and find the shortest distance between them and sum them for that partition. The partition with the total smallest distance between its pairs is selected, and I then double all the edges between the shortest path between the odd vertices (found in the selected partition).

These represent the edges the postman will have to walk twice.

At first I thought I had worked out an appropriate algorithm for generating these partitions:

  1. Start with all the odd verticies sorted in increasing order

    12 34 56

  2. Select the pair behind the pair that currently has the max vertice

    12 [34] 56

  3. Increase the second digit in this pair by 1. Leave everything to the
    left of the selected pair the same,
    and make everything to the right of
    the selected pair the remaining
    numbers in the set, sorted in
    increasing order.

    12 35 46

  4. Repeat

However, this is flawed. For example, I realized that when I reach to the end and the select pair is at the left most position (ie):

[16] .. ..

The algorithm I worked out will stop in this case, and not generate the rest of the pairs that begin [16], because there is no pair to the left of it to alter.

So, it is back to the drawing board.

Does anyone who has studied this problem before have any tips that can help point me in the right direction for generating these partitions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

递刀给你 2024-09-06 11:48:10

您可以使用递归算法构建分区。

采用最低节点,在本例中为节点 1。它必须与其他未配对节点(2 到 6)之一配对。对于每个节点,使用匹配 1 创建,然后对剩余 4 个元素使用相同的算法查找剩余 4 个元素的所有对。

在 Python 中:

def get_pairs(s):
    if not s: yield []
    else:
        i = min(s)
        for j in s - set([i]):
           for r in get_pairs(s - set([i, j])):
               yield [(i, j)] + r

for x in get_pairs(set([1,2,3,4,5,6])):
    print x

这会生成以下解决方案:

[(1, 2), (3, 4), (5, 6)]
[(1, 2), (3, 5), (4, 6)]
[(1, 2), (3, 6), (4, 5)]
[(1, 3), (2, 4), (5, 6)]
[(1, 3), (2, 5), (4, 6)]
[(1, 3), (2, 6), (4, 5)]
[(1, 4), (2, 3), (5, 6)]
[(1, 4), (2, 5), (3, 6)]
[(1, 4), (2, 6), (3, 5)]
[(1, 5), (2, 3), (4, 6)]
[(1, 5), (2, 4), (3, 6)]
[(1, 5), (2, 6), (3, 4)]
[(1, 6), (2, 3), (4, 5)]
[(1, 6), (2, 4), (3, 5)]
[(1, 6), (2, 5), (3, 4)]

You can construct the partitions using a recursive algorithm.

Take the lowest node, in this case node 1. This must be paired with one of the other unpaired nodes (2 to 6). For each of these nodes, create with match 1, then find all of the pairs of the remaining 4 elements using the same algorithm on the remaining four elements.

In Python:

def get_pairs(s):
    if not s: yield []
    else:
        i = min(s)
        for j in s - set([i]):
           for r in get_pairs(s - set([i, j])):
               yield [(i, j)] + r

for x in get_pairs(set([1,2,3,4,5,6])):
    print x

This generates the following solutions:

[(1, 2), (3, 4), (5, 6)]
[(1, 2), (3, 5), (4, 6)]
[(1, 2), (3, 6), (4, 5)]
[(1, 3), (2, 4), (5, 6)]
[(1, 3), (2, 5), (4, 6)]
[(1, 3), (2, 6), (4, 5)]
[(1, 4), (2, 3), (5, 6)]
[(1, 4), (2, 5), (3, 6)]
[(1, 4), (2, 6), (3, 5)]
[(1, 5), (2, 3), (4, 6)]
[(1, 5), (2, 4), (3, 6)]
[(1, 5), (2, 6), (3, 4)]
[(1, 6), (2, 3), (4, 5)]
[(1, 6), (2, 4), (3, 5)]
[(1, 6), (2, 5), (3, 4)]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文