【问题标题】:Algorithms to find the number of Hamiltonian paths in a graph找出图中哈密顿路径数量的算法
【发布时间】:2011-07-17 00:45:29
【问题描述】:

我正在尝试解决Hamiltonian Path 问题的略微修改版本。它的修改在于将起点和终点提供给我们,而不是确定解决方案是否存在,而是要找到解决方案的个数(可能为 0)。

图形以二维数组的形式提供给我们,节点是数组的元素。此外,我们只能水平或垂直移动,不能沿对角线移动。不用说,我们不能从一个城市去两个城市,因为要这样做,我们需要访问一个城市两次。

我写了一个蛮力解决方案,尝试在每个节点上进行所有 4 次(边缘节点为 3 或 2 次)可能的移动,然后计算解决方案的数量(即当它达到目标并且也看到所有其他节点时) ),但它在中等大小的输入(比如 7x7 数组)上运行了荒谬的时间。

我也想过使用bidirectional search,因为我们知道目标,但这并没有真正帮助,因为我们不仅希望边缘相遇,我们还希望确保所有节点都已被访问。此外,当两个边缘之间的所有节点都用尽时,它们可能会以无法连接的方式结束。

我觉得有一些我不知道的东西让我只能使用蛮力解决方案。我知道问题本身是 NP 完全的,但我想知道是否对蛮力有任何改进。有人可以提出其他建议吗?

--编辑--

我提到使用双向搜索并没有真正的帮助,我想澄清一下我为什么这么认为。考虑一个 2x3 图形,左上角和右下角节点分别是起点和目标。让双向搜索的边缘从起点向右移动,从目标向左移动。在 2 次移动之后,所有节点都会被访问,但无法加入边缘,因为我们只能从一个节点向一个方向前进。但是,正如大卫在下面的回答中指出的那样,可以通过一些修改使算法工作。

【问题讨论】:

    标签: algorithm path np-complete


    【解决方案1】:

    根据Wolfram Alpha

    ...唯一已知的确定方法 给定的一般图是否有 哈密​​顿路径是进行 彻底搜索

    我相信你会想从找到一条汉密尔顿路径开始,然后将它分成两条路径,使分割点尽可能清晰地将两条路径分开。然后你可以在子图中找到排列(当然还有递归!)

    我不知道确切的算法,但我会从这种分而治之的方法开始。

    【讨论】:

    • 这很糟糕,但我想我对此无能为力。感谢您的帮助
    • 你能再详细说明一下最后一部分吗?有什么地方可以开始阅读吗?
    • 我找到了this page,但很多链接似乎已失效。
    【解决方案2】:

    有人在 https://mathoverflow.net/questions/36368/efficient-way-to-count-hamiltonian-paths-in-a-grid-graph-for-a-given-pair-of-vert 上的 Math Overflow 上问了一个与您非常相似的问题,并且 (1) 他们没有得到大量“这里是如何有效地做到这一点”的回答(这可能意味着没有一个简单的方式),(2)Mathematica 显然需要 5 个小时来计算 7x7 网格上对角之间的路径,因此您可能没有做错任何事情,并且(3)答案中有一些有趣的指针。

    【讨论】:

    • 我在放弃之前让我的代码运行了大约 98 分钟,希望我犯了一些愚蠢的错误。我想这完全消除了任何希望。谢谢你为我省去了很多麻烦。
    【解决方案3】:

    您仍然可以使用双向搜索,只需在搜索中添加一个约束,这样之前看到的节点就不会成为搜索的候选对象。

    另一种适合并行解决方案的方法是将搜索分解为更小的搜索。

    例如,尝试通过求解来解决你原来的问题:

    对于每个节点n,它不是开始或结束节点,找到从开始到n(set1)和从n到结束(set2)的所有路径。

    找到set1set2后,可以丢弃它们叉积中除n以外的公共节点的所有元素。

    【讨论】:

    • 这不是问题。即使我们没有访问已经访问过的节点,我们仍然希望边缘访问图中的所有节点。此外,可能无法以合法方式加入边缘。例如,考虑一个 3x2 图形,右上角和左下角节点分别是 start 和 goal。让边缘向右/向左移动。两次移动后,所有节点都会被访问,但无法以合法的方式加入它们,让我们回到暴力搜索。
    • 请您将其添加到问题描述中吗?另外,为什么不直接修改搜索,使其在探索完所有节点后才停止?
    • 在想到双向搜索之前,我已经想到了类似的解决方案,但我放弃了。将它与双向搜索一起使用使它更有用。 +1
    • 因为我们想在最后达到目标。另外,你能告诉我你认为我应该在描述中添加什么吗?我在第一条评论中使用的示例?
    • 我认为,您第一条评论中的示例会大大增加您的问题。你问了一个有趣的问题,干得好!:)
    【解决方案4】:

    在 7x7 数组(即总共 7*7=49 个节点)上,使用 O(n!) 算法或 O(2^n*n^2) 算法都将花费太多时间。

    考虑到这个特定图的特殊特性(例如,每个节点最多有 4 条边),也许有一些方法可以加快这个速度,但是快速解决方案似乎不太可能(除非有人偶然找到了哈密顿量的多项式时间算法路径问题本身)。

    【讨论】:

      【解决方案5】:

      它可以使用带有位掩码的 DP 来解决,我猜 n 的值最多为 20 或更多。创建一个 2d dp 表。 dp[i][j] 表示您在第 i 个顶点的情况的答案,j 存储有关已访问顶点的信息。这是一个 C++ 代码。

      使用的宏:

      #define    oncnt    __builtin_popcount
      typedef    vector<int>   vi;
      

      主线外:

      vi ad[21];
       int n,m;
      
       int dp[20][(1<<19)+1];
      
      int sol(int i,int mask)
      {
          //cout<<i+1<<" "<<oncnt(mask)<<"\n";
      
          if(i==n-1)
          return 1;
      
          if(mask&(1<<i))
          return 0;
      
          int &x=dp[i][mask];
          if(x!=-1)
          return x;
      
          x=0;
      
          for(int j=0;j<ad[i].size();j++)
          {
              int k=ad[i][j];
              if(mask&(1<<k))
              continue;
              if(k==n-1&&oncnt(mask)!=n-2)
              continue;
              if(k!=n-1&&oncnt(mask)==n-2)
              continue;
      // The above two pruning statements are necessary.
              x=madd(x,sol(k,mask|(1<<i)));
      
          }
      
          return x;
      
      }
      

      内部主要:

      cin>>n>>m;
      
      for(int i=0;i<=n-1;i++)
       {
          for(int j=0;j<=(1<<(n-1));j++)
          dp[i][j]=-1;
       }
      
      
      int a,b;
      for(int i=1;i<=m;i++)
      {
          cin>>a>>b;
          a--;
          b--;
          ad[a].pb(b);
      }
      
      
       cout<<sol(0,0);
      

      【讨论】:

        【解决方案6】:

        我发现这种方法非常快,并且我能够将其推广到六边形网格:https://hal.archives-ouvertes.fr/hal-00172308/document。诀窍是通过网格推动边界,同时跟踪可能的路径。我的实现可以在几秒钟内处理 20x20 的网格。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-31
          • 1970-01-01
          • 1970-01-01
          • 2018-08-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多