有必要对路线进行随机排序

It is necessary to make a random sequence of the route

提问人:user21992995 提问时间:5/31/2023 最后编辑:ravenspointuser21992995 更新时间:6/1/2023 访问量:42

问:

我在 Base(1) 中有 3 个数据库,其中包含有关我需要旅行的城市的数据。为简单起见,我们称它们为 POINTS FROM。还有 Base(2),其中包含我需要旅行的城市。为简单起见,我们称它们为 POINTS TO。还有 Base(3),其中包含可用于在城市之间旅行的公共汽车的名称,但每辆公共汽车都有自己的列表,列出了它可以出发的城市和可以到达的城市。

任务是创建一系列总线,以便使用所有总线,并访问每个 POINT FROM 和 POINT TO。理想情况下,我们应该最多使用一次 BUS,但如有必要,一个 BUS 可以多次使用。初始城市是从 Base(1) 中的列表中随机选择的。在第一次旅行之后,上一轮结束时的城市将作为下一轮的初始城市。顺序应始终尽可能随机,同时努力减少步骤数。如果使用了所有 BUS,并且 Base(1) 中的所有城市 FROM 都留下了,并且到达了 Base(2) 中的所有城市 TO,则认为序列成功。此外,巴士不能从同一城市出发和到达。

下面是数据库中的数据示例:Here's an example of the data from the databases:

Base(1) in the format "City1,City2,City3..." - "CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW,MOONSTONE,RIVERDALE,CEDARVILLE,MAPLEWOOD"
Base(2) in the format "City1,City2,City3..." - "CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW,MOONSTONE,RIVERDALE,CEDARVILLE,MAPLEWOOD"
Base(3) in the format "BusName1:CityFROM1,CityFROM2,CityFROM3...@CityTO1,CityTO2,CityTO3...
BusName2:CityFROM1,CityFROM2,CityFROM3...@CityTO1,CityTO2,CityTO3..." 
"TransLink:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW
GoBus:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW
SwiftRide:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW
SpeedyBus:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE
CityHopper:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW@MOONSTONE
RouteMasters:MOONSTONE@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW
MetroTrans:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW,RIVERDALE,CEDARVILLE@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW,RIVERDALE,CEDARVILLE
MegaBus:MAPLEWOOD,CRYSTALVILLE@MAPLEWOOD,CRYSTALVILLE"

以下是所需序列的一小部分摘录:

Starting with the city CRYSTALVILLE,
CRYSTALVILLE (CityHopper) - MOONSTONE,
MOONSTONE (RouteMasters) - HARMONYVILLE,
HARMONYVILLE (SpeedyBus) - WILLOWBROOK,
WILLOWBROOK (MetroTrans) - RIVERDALE,
RIVERDALE (MetroTrans) - CEDARVILLE,
CEDARVILLE (MetroTrans) - OCEANVIEW,
OCEANVIEW (GoBus) - SILVERLAKE,
and so on until all BUSES and cities from Base(1) and Base(2) are used.

我在创建此类序列或编程方面几乎没有经验。我试图自己解决这个任务,但我总是以无限序列结束,或者它在第 3-11 步中断。据我了解,一切都中断了,因为 BUS 用完了,或者没有可用的城市,因为我使用了一个方案,使用 BUS 或 Base(1) 和 Base(2) 中的城市将它们从基地中删除,并且在没有 1-2 个数据库的情况下,它从其他未更改的基地中获取数据,这些基地完全复制了满足条件的路径开头使用的基地,但随机获取, 这使得序列要么是无限的,要么不满足最小步数的条件,我被卡住了。

数据库 算法 随机 序列 图论

评论


答:

1赞 ravenspoint 5/31/2023 #1

这看起来像是对旅行推销员问题的不寻常表述。“公共汽车”定义了有向边,城市定义了顶点。如果你忽略了使用所有“公共汽车”的要求,那么这就是旅行推销员的问题。

因此,算法将是:

  • 生成有向图(总线定义边,城市是顶点 )
  • 应用旅行推销员算法
  • LOOP over edges in solution
    • 覆盖边缘的 SELECT 总线,如果可能,以前未使用过的总线。

这是您示例中的图表

enter image description here

这是使用公共汽车的路线

MAPLEWOOD ->(MegaBus)-> CRYSTALVILLE ->(MegaBus)-> WILLOWBROOK ->(TransLink)-> HARMONYVILLE ->(GoBus)-> SILVERLAKE ->(SwiftRide)-> OCEANVIEW ->(MetroTrans)-> MOONSTONE ->(CityHopper)-> CRYSTALVILLE ->(RouteMasters)-> RIVERDALE ->(MetroTrans)-> CEDARVILLE ->(MetroTrans)-> MAPLEWOOD

下面是实现此目的的 C++ 代码

main()
{
    std::string buses =
    "TransLink:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW\n"
    "GoBus:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW\n"
    "SwiftRide:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW\n"
    "SpeedyBus:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE\n"
    "CityHopper:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW@MOONSTONE\n"
    "RouteMasters:MOONSTONE@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW\n"
    "MetroTrans:CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW,RIVERDALE,CEDARVILLE@CRYSTALVILLE,WILLOWBROOK,HARMONYVILLE,SILVERLAKE,OCEANVIEW,RIVERDALE,CEDARVILLE\n"
    "MegaBus:MAPLEWOOD,CRYSTALVILLE@MAPLEWOOD,CRYSTALVILLE\n";

    raven::graph::cGraph g;
    g.directed();
    std::map<std::pair<std::string, std::string>, std::vector<std::string>> mpBus;
    std::stringstream ss(buses);
    std::string line;
    while (getline(ss, line))
    {
        // std::cout << line << "\n";
        int p1 = line.find(":");
        int p2 = line.find("@", p1);
        std::string busName = line.substr(0, p1);
        std::string srcs = line.substr(p1 + 1, p2 - p1 - 1);
        std::string dsts;
        dsts = line.substr(p2 + 1);
        auto vs = ParseCSV(srcs);
        auto vd = ParseCSV(dsts);
        for (auto &s : vs)
            for (auto &d : vd)
            {
                // std::cout << s << " -> " << d  << "\n";
                g.add(s, d);
                auto it = mpBus.find(std::make_pair(s, d));
                if (it == mpBus.end())
                {
                    std::vector<std::string> vb{busName};
                    mpBus.insert(
                        std::make_pair(
                            std::make_pair(s, d),
                            vb));
                }
                else
                    it->second.push_back(busName);
            }
    }

    // for( auto& s : g.edgeList() )
    //     std::cout <<"l " << g.userName(s.first) <<" "<< g.userName(s.second) << " 1\n";

    raven::graph::cTourNodes T;
    T.calculate(g);

    std::set<std::string> setUsed;

    std::string src, dst;
    std::string tourText;
    bool first = true;
    for (int v : T.getTour())
    {
        if (first)
        {
            first = false;
            src = g.userName(v);
            continue;
        }
        dst = g.userName(v);
        auto vBus = mpBus.find(std::make_pair(src, dst))->second;
        std::string busUsed;
        for (auto &b : vBus)
        {
            auto itUsed = setUsed.find(b);
            if (itUsed == setUsed.end())
            {
                busUsed = b;
                setUsed.insert(b);
                break;
            }
        }
        if( busUsed.empty() )
            busUsed = vBus[0];

        tourText += g.userName(v) + " ->(" + busUsed + ")-> ";
        src = dst;
    }
    std::cout << tourText << "\n";

    return 0;
}

https://github.com/JamesBremner/so76373906 完成应用程序代码