【问题标题】:How to create an algorithm to find all possible pairings (referring to the chinese postman problem)?如何创建一个算法来找到所有可能的配对(参考中国邮递员问题)?
【发布时间】:2021-10-21 21:52:46
【问题描述】:

当尝试解决中国邮递员问题时,您将必须找到图中所有奇数顶点的所有可能配对的最小成本,并添加找到的边(配对),我的问题几乎就是这样。

如何实现返回所有可能配对的算法? 或者如何解决我的问题。

我有一个起点,但无法进一步思考。

我尝试查看以下主题,但不幸的是它们并没有帮助我。 How should I generate the partitions / pairs for the Chinese Postman problem?Find the pairings such that the sum of the weights is minimized?

std::vector<std::vector<int>> Postman::pairOdd(std::vector<int> vertices)
{   
    std::vector<std::vector<int>> pairs;
    if (vertices.empty()) {
        return std::vector<std::vector<int>>();
    }
    else {
        auto it = std::min_element(vertices.begin(), vertices.end());
        int i = *it;
        vertices.erase(it);
        for (int index = 0; index < vertices.size(); index++) {
            int j = vertices[index];
            vertices.erase(vertices.begin() + index);
            pairs.push_back(std::vector<int>{i, j});
            std::vector<std::vector<int>> returnValue = pairOdd(vertices);
            pairs.insert(pairs.end(), returnValue.begin(), returnValue.end());
            vertices.insert(vertices.begin(), j);
        }
        vertices.insert(vertices.begin(), i);
    }
    return pairs;
}

输出

std::vector<std::vector<int>> res = pairOdd(std::vector<int>{1,2,3,4,5,6});
for (auto v : res) {
    for (auto u : v) {
        std::cout << u;
    }
    std::cout << std::endl;
}

应该是:

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

但是:

12
34
56
35
46
36
45
13
24
56
25
46
26
45
14
23
56
25
36
26
35
15
24
36
23
46
26
34
16
25
34
24
35
23
45

我无法完全解决插入向量的方式。查看输出时,您可以看到它几乎是正确的(忽略格式)。第一行12 34 45 是正确的。第二个35 46,当它必须是12 35 36时,似乎只有第一对丢失了,你会注意到它适用于每个配对。


更新: 所以我想出了另一种似乎很有希望的算法,但我没有丢失一些配对,而是得到了重复。高度赞赏解决方案。如果我自己找到一个,我会发布它。

std::vector<std::vector<int>> Postman::aaa(std::vector<int> vertices, std::vector<int> list, int in1, int in2)
{
    std::vector<std::vector<int>> pairs;
    if (vertices.empty()) {
        list.push_back(in1);
        list.push_back(in2);
        pairs.push_back(list);
        return pairs;
    }
    else {
        auto it = std::min_element(vertices.begin(), vertices.end());
        int i = *it;
        vertices.erase(it);
        for (int index = 0; index < vertices.size(); index++) {
            int j = vertices[index];
            vertices.erase(vertices.begin() + index);

            if (in1 != 0 && in2 != 0) {
                list.push_back(in1);
                list.push_back(in2);
            }

            std::vector<std::vector<int>> returnValue = aaa(vertices, list, i, j);
            pairs.insert(pairs.end(), returnValue.begin(), returnValue.end());

            vertices.insert(vertices.begin(), j);
        }
        vertices.insert(vertices.begin(), i);
    }
    return pairs;
}

输出:

123456
12123546
1212123645
132456
13132546
1313132645
142356
14142536
1414142635
152436
15152346
1515152634
162534
16162435
1616162345

【问题讨论】:

  • 你没有显示完整的代码,但我猜有一个operator&lt; 没有正确实现严格的弱排序。
  • 您正在从特定索引中删除一个元素,然后将其放回开头。这会改变元素的顺序,因此后续的递归调用将以不同的顺序生成对。
  • @1201ProgramAlarm 但是顺序是对的,还是我错了?你可以说第一对是12 34 56第一行。第二对是[12] 35 46,第一对丢失,第三对也一样。然后再次以正确的配对13 24 56 开始,继续这种模式。
  • 如果您查看代码,您的初始对 (1 2) 只会添加到 pairs 一次,但您的预期结果需要多次。这就是结果中缺失的 10 对。
  • @1201ProgramAlarm 我明白你的意思了。你有什么解决方案吗,而我正在为自己寻找一个?

标签: c++ chinese-postman


【解决方案1】:

所以我找到了我提到的第二种算法的解决方案。 问题是我将这对发送到下一个递归步骤,然后在此步骤中添加。因此,当您从递归步骤返回时,配对仍然存在。 所以我只是删除了这对,所以可以添加新的。 我不只是返回一个 int 向量,而是创建了一个对向量。更好地可视化返回值。 我愿意听取对此算法的任何改进或任何好的做法。

  • 我愿意听取对此算法的任何改进或任何好的做法。
std::vector<std::vector<std::pair<int, int>>> Postman::pairing(std::vector<int> vertices, std::vector<std::pair<int, int>> list)
{
    std::vector<std::vector<std::pair<int, int>>> pairs;
    if (vertices.empty()) {
        pairs.push_back(list);
        return pairs;
    }
    else {
        auto it = std::min_element(vertices.begin(), vertices.end());
        int i = *it;
        vertices.erase(it);
        for (int index = 0; index < vertices.size(); index++) {
            int j = vertices[index];
            vertices.erase(vertices.begin() + index);

            std::pair<int, int> pair(i, j);
            list.push_back(pair);

            std::vector<std::vector<std::pair<int, int>>> r = pairing(vertices, list);

            list.erase(list.end() - 1);

            pairs.insert(pairs.end(), r.begin(), r.end());

            vertices.insert(vertices.begin(), j);
        }
    }
    return pairs;
}
std::vector<std::vector<std::pair<int, int>>> a = pairing(vertices, std::vector<std::pair<int, int>>());
for (auto v : a) {
    for (auto p : v) {
        std::cout << '(' << p.first << ' ' << p.second << ')';
    }
    std::cout << std::endl;
}

【讨论】:

    猜你喜欢
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    • 1970-01-01
    相关资源
    最近更新 更多