C++ 在有附加条件的图中求最小加权路径

C++ 在有附加条件的图中求最小加权路径,c++,algorithm,graph,time-complexity,C++,Algorithm,Graph,Time Complexity,我有一个问题如下,我真的被它卡住了,因为它运行的时间超过了我想要的时间(大约1秒)。我真的希望你能帮助我建立一个比我更有效的算法 给定一个无向图G=(V,E),每个边有两个参数的权重w1和w2。该图有N个顶点和M条边。K-基本路径S是G的一个子图,它必须是一个基本图,并且它确实有K条边 找到一条K-基本路径S,所有边的w1之和为最小值,且S所有边的w2之和必须小于给定值Q。如果不存在任何满足要求的路径,则打印出值-1 输入: 5 7 3 6 1 2 1 2 1 4 2 2 1 5 3 6 2 3

我有一个问题如下,我真的被它卡住了,因为它运行的时间超过了我想要的时间(大约1秒)。我真的希望你能帮助我建立一个比我更有效的算法

给定一个无向图G=(V,E),每个边有两个参数的权重w1和w2。该图有N个顶点和M条边。K-基本路径S是G的一个子图,它必须是一个基本图,并且它确实有K条边

找到一条K-基本路径S,所有边的w1之和为最小值,且S所有边的w2之和必须小于给定值Q。如果不存在任何满足要求的路径,则打印出值-1

输入:

5 7 3 6
1 2 1 2
1 4 2 2
1 5 3 6
2 3 3 2
2 4 4 4
3 4 5 1
4 5 4 7

具有四个值N、M、K、Q的第一行(2首先,查找资源受限的最短路径是NPHard。解决此问题的大多数方法都采用标签方案,这是动态规划的一种专门化。您可以使用可用的库来完成此任务。有关增强实现,请参阅。此实现将帮助您查找(可能的)一条从s到t的非基本路径,只要所有的w_2权重都是正的。如果权重w_2是负的,那么有可能使用负w_1权重和正Q,问题是无界的

现在,说到对k-基本最短路径的需要,据我所知,没有现成的算法可以帮助实现这一点。首先,忘记k。找到受额外资源约束的基本最短路径可以使用上面boost链接中提到的论文中提出的标签方案来完成。在这种情况下,动态程序的状态空间应增加,以允许存储路径中所有先前访问的节点的指示向量。这使得该问题比基本的资源受限最短路径问题更难解决

现在,为了满足您对k-基本最短路径的需求,您必须将上述方案嵌入到另一个函数中,该函数不断检查返回的基本路径是否有k条边。如果它有k条边,那么您就完成了。如果没有,您必须以某种方式设置限制关于防止这种特殊路径的算法。这可以通过使用预标记来实现。据我所知,这是第一次在工作中完成


祝你好运,但是这个问题非常困难(因为可能需要多次迭代)。您应该参考boost链接中提到的工作以及该领域的后续论文,以了解最先进的技术。我怀疑最先进的技术无法解决10-15个节点以外的问题。

首先,由于输入约束,您不可能假设w1或w2的值为负值。其次你说过,我们可以使用库boost,但是这个库今天不能使用,或者可能有一些原因导致使用我的编译器的这个库失败。我怎么能使用它或任何替代方法呢?正如我提到的,你没有现成的算法可以使用。你必须自己实现这个算法。论文中以上仅给出了伪代码中算法的步骤,然后你必须自己将这些代码转换成C++代码。
6
#include <bits/stdc++.h>
using namespace std;
#define N 51
#define INF 1e9
int n, m, K, Q;
bool appear[N];
int W1[N][N];
int W2[N][N];
int currentSum1 = 0;
int currentSum2 = 0;
int source = 0;
int res = INF;
int Log[N];
int minElement = INF;
bool check(int k, int v)
{
    return !appear[v] && W1[Log[k - 1]][v] != 0 && W2[Log[k - 1]][v] != 0;
}
void solution()
{
    if(currentSum1 != 0 && currentSum1 < res)
    {
        res = currentSum1;
        // for(int i = 0; i <= K; i++)
        //     cout << Log[i] << " ";
        // cout << endl;
    }
}
void solve(int k)
{
    for(int v = 1; v <= n; v++)
    {
        if(check(k, v) && currentSum2 + W2[source][v] <= Q && currentSum1 + (K - k) * minElement <= res) //Branch-bound condition
        {
            Log[k] = v;
            currentSum2 += W2[Log[k - 1]][v];
            currentSum1 += W1[Log[k - 1]][v];
            appear[v] = true;
            if(k == K)
                solution();
            else
                solve(k + 1);
            currentSum1 -= W1[Log[k - 1]][v];
            currentSum2 -= W2[Log[k - 1]][v];
            appear[v] = false;
        }
    }
}
int main()
{
    fast;
    // freopen("data.txt", "r", stdin);
    cin >> n >> m >> K >> Q;
    for(int i = 0; i < m; i++)
    {
        int x, y, w1, w2;
        cin >> x >> y >> w1 >> w2;
        minElement = min(minElement, w1);
        W1[x][y] = w1;
        W1[y][x] = w1;
        W2[x][y] = w2;
        W2[y][x] = w2;
    }
    for(int v = 1; v <= n; v++)
    {
        source = v;
        currentSum2 = 0;
        currentSum1 = 0;
        Log[0] = v;
        for(int i = 1; i <= n; i++)
            appear[i] = false;
        appear[source] = true;
        solve(1);
    }
    if(res != INF)
        cout << res << endl;
    else 
        cout << -1 << endl;
}