Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 旅行商问题的编译器优化_C++_Compiler Optimization - Fatal编程技术网

C++ 旅行商问题的编译器优化

C++ 旅行商问题的编译器优化,c++,compiler-optimization,C++,Compiler Optimization,我正在研究旅行推销员问题,并正在研究以下版本: 城镇是二维空间中的点,从每个城镇到所有其他城镇都有路径,长度是点之间的距离。因此,很容易实现简单的解决方案,即检查n个点的所有排列并计算路径长度 然而,我发现,对于n>=10,编译器执行了一些魔术,并打印出一个肯定不是实际最短路径的值。我使用MicrosoftVisualStudio编译器以默认设置的发布模式进行编译。对于值10,30,它会思考30秒,然后返回一些看起来可能是正确的数字,但不是我用不同的方法检查的。对于n>40,它会立即计算结果,并

我正在研究旅行推销员问题,并正在研究以下版本: 城镇是二维空间中的点,从每个城镇到所有其他城镇都有路径,长度是点之间的距离。因此,很容易实现简单的解决方案,即检查n个点的所有排列并计算路径长度

然而,我发现,对于n>=10,编译器执行了一些魔术,并打印出一个肯定不是实际最短路径的值。我使用MicrosoftVisualStudio编译器以默认设置的发布模式进行编译。对于值10,30,它会思考30秒,然后返回一些看起来可能是正确的数字,但不是我用不同的方法检查的。对于n>40,它会立即计算结果,并且始终为2.14748e+09

我想解释一下编译器在不同的情况下会做什么10,30的情况非常有趣。还有一个例子,在这个例子中,这些优化比仅仅旋转到世界末日的程序更有用

vector<pair<int,int>> points;
void min_len()
{
    // n is a global variable with the number of points(towns)
    double min = INT_MAX;
    // there are n! permutations of n elements
    for (auto j = 0; j < factorial(n); ++j)
    {
        double sum = 0;
        for (auto i = 0; i < n - 1; ++i)
        {
            sum += distance_points(points[i], points[i + 1]);
        }
        if (sum < min)
        {
            min = sum;
            s_path = points;
        }
        next_permutation(points.begin(), points.end());
    }

    for (auto i = 0; i < n; ++i)
    {
        cout << s_path[i].first << " " << s_path[i].second << endl;
    }
    cout << min << endl;
}

unsigned int factorial(unsigned int n)
{
    int res = 1, i;
    for (i = 2; i <= n; i++)
        res *= i;
    return res;
}

你的阶乘函数溢出了。尝试将其替换为一个返回int64_t的代码,并看到您的代码需要3年时间才能在n>20时终止

constexpr uint64_t factorial(unsigned int n) {
  return n ? n * factorial(n-1) : 1;
}

而且,你根本不需要计算这个。当所有排列都从排序位置开始时,std::next_排列函数返回0。

您的阶乘函数溢出。尝试将其替换为一个返回int64_t的代码,并看到您的代码需要3年时间才能在n>20时终止

constexpr uint64_t factorial(unsigned int n) {
  return n ? n * factorial(n-1) : 1;
}

而且,你根本不需要计算这个。当所有排列都从排序位置开始时,std::next_permutation函数返回0。

factorialn的实现是什么?它可能已经溢出了。你为什么还要用阶乘呢?您应该只查看中的返回值,而不是责怪那些在定义行为时不允许返回错误结果的优化,您应该尝试一些调试。对于初学者,在每次迭代结束时跟踪min的值。确保next_permutation执行您认为它应该执行的操作-可能执行,但这属于调试时要验证的标准事项。额外积分:请注意,2.14748e+09很可能是INT_MAX的值@JaMiT我知道这要看情况而定,但我应该期望在30分钟内得到8分!置换?你对factorialn的实现是什么?它可能已经溢出了。你为什么还要用阶乘呢?您应该只查看中的返回值,而不是责怪那些在定义行为时不允许返回错误结果的优化,您应该尝试一些调试。对于初学者,在每次迭代结束时跟踪min的值。确保next_permutation执行您认为它应该执行的操作-可能执行,但这属于调试时要验证的标准事项。额外积分:请注意,2.14748e+09很可能是INT_MAX的值@JaMiT我知道这要看情况而定,但我应该期望在30分钟内得到8分!排列?