C 如何更改嵌套for循环中的行和列索引?

C 如何更改嵌套for循环中的行和列索引?,c,for-loop,indexing,C,For Loop,Indexing,我正试图找出在这个城市旅行的最短距离。 我已经有了一个起点,城市“0”,然后我们将访问每一个城市,而不必重新访问以前的城市。在这种情况下,我们不需要返回城市0 假设我们有4个城市,那么我们将有一个距离矩阵。 我想做的是迭代每一条可能的路线,并得到每条路线的成本 所以4号城市的所有可能路线都是 city[0][1] + city[1][2] + city[2][3] city[0][1] + city[1][3] + city[3][2] city[0][2] + city[2][1] +

我正试图找出在这个城市旅行的最短距离。 我已经有了一个起点,城市“0”,然后我们将访问每一个城市,而不必重新访问以前的城市。在这种情况下,我们不需要返回城市0

假设我们有4个城市,那么我们将有一个距离矩阵。 我想做的是迭代每一条可能的路线,并得到每条路线的成本

所以4号城市的所有可能路线都是

city[0][1] + city[1][2] + city[2][3] 
city[0][1] + city[1][3] + city[3][2] 

city[0][2] + city[2][1] + city[1][3] 
city[0][2] + city[2][3] + city[3][1] 

city[0][3] + city[3][1] + city[1][2] 
city[0][3] + city[3][2] + city[2][1] 
我的问题是如何为这些方程生成嵌套for循环?
我可以看到有一种模式,“列索引”应该转到下一个“行索引”,以此类推

您正在查找第一个城市固定的所有城市的排列。如果城市数量固定,您可以为循环编写嵌套的meny
,但这很快就会变得很麻烦

相反,递归地排列数组:

  • 按照参观城市的顺序创建一个数组
    路径
    ;从{0,…,N开始− 1}
  • 选择一个起始索引。如果您想要所有可能的起始品脱,请选择0。这里,第一个城市是固定的,所以从索引1开始,因为
    path[1]
    是应该更改的第一个条目
  • 调用置换函数:
    • 现在,如果仍有城市要置换,则依次将每个城市置换到下一个位置,使用下一个索引调用置换函数,然后将城市置换回来。在递归时,跟踪当前距离
    • 如果没有更多的城市,您已到达列表的末尾。打印路径和距离或任何你想做的事情,不要做任何其他事情
下面是代码中可能出现的情况:

#include <stdlib.h>
#include <stdio.h>

enum {
    N = 4           // number of cities
};

const int city[N][N] = {
    {0, 2, 5, 5},
    {2, 0, 3, 4},
    {5, 3, 0, 6},
    {5, 4, 6, 0},
};

/*
 *      Swap array elements at indices i and j
 */
void swap(int a[], int i, int j)
{
    if (i != j) {
        int swap = a[i]; a[i] = a[j]; a[j] = swap;
    }
}

/*
 *      Permute the subarray of length n, starting at index i
 */
void perm(int path[], int i, int n, int weight)
{
    int j;

    if (i == n) {                                   // path is exhausted:
        for (j = 0; j < n; j++) {                   // print path and distance
            printf("%c ", 'A' + path[j]);
        }

        printf("-> %d\n", weight);
    } else {                                        // more cities to visit:
        for (j = i; j < n; j++) {                   // pick each of them as ...
            int w = 0;                              // ... destination

            if (i > 0) {                            // determine distance ...
                w = city[path[i - 1]][path[j]];     // ... from prev. city,
            }                                       // ... if any

            swap(path, i, j);                       // swap city in;
            perm(path, i + 1, n, weight + w);       // recurse;
            swap(path, i, j);                       // swap city back
        }
    }
}

int main()
{
    int path[N];
    int i;

    for (i = 0; i < N; i++) path[i] = i;            // initial path

    perm(path, 1, N, 0);

    return 0;
}
#包括
#包括
枚举{
N=4//城市数量
};
国际城市常数[N][N]={
{0, 2, 5, 5},
{2, 0, 3, 4},
{5, 3, 0, 6},
{5, 4, 6, 0},
};
/*
*交换索引i和j处的数组元素
*/
无效交换(整数a[],整数i,整数j)
{
如果(i!=j){
int swap=a[i];a[i]=a[j];a[j]=swap;
}
}
/*
*从索引i开始排列长度为n的子阵列
*/
void perm(整数路径[],整数i,整数n,整数权重)
{
int j;
如果(i==n){//路径已用尽:
对于(j=0;j%d\n”,重量);
}其他{//更多城市可参观:
对于(j=i;j0){//确定距离。。。
w=城市[path[i-1]][path[j]];/…来自上一个城市,
}//…如果有的话
交换(路径,i,j);//交换中的城市;
perm(路径,i+1,n,权重+w);//递归;
交换(路径,i,j);//交换回城市
}
}
}
int main()
{
int路径[N];
int i;
对于(i=0;i
您不想迭代距离表,因为它不会给您求和。您希望迭代路线,这些是您的城市集的排列。谷歌“排列”。只是一个细节,你不需要检查
if(i>0){
在perm中,它以1开头,并且在递归调用中总是递增。当然,UV^^@bruno:谢谢,但是我想让这个过程更一般,我还提到可以从文本中的某个地方的索引0开始,所以我想排除这种情况。