2016-05-16 77 views
0

我正在处理一个类的任务,并且遇到了一个我一直无法解决的问题。我正在使用BFS实现Ford-Fulkerson算法来查找最大流量。但在试图将我的剩余容量矩阵设置为给定容量时,我遇到了分段错误。在我们收到的测试代码中,我可以看到原始容量矩阵是通过地址值传递的,但是我有一种感觉,在我的代码中,我没有像我认为的那样与它交互?这导致我相信我可能会在其他地方发生同样的问题。我曾用gdb,看到我打分割故障在这条线在这里我对嵌套循环:实现Ford-Fulkerson的函数中的分段错误

resCap[i][j] = *(capacity + i*n + j); 

然而,没有什么我曾尝试为我的工作虽然让我很为难。

void maximum_flow(int n, int s, int t, int *capacity, int *flow) 
{ 
    int i, j, resCap[n][n], path[n]; // residual capacity and BFS augmenting path 
    int min_path = INT_MAX; // min of the augmenting path 

    // Assign residual capacity equal to the given capacity 
    for (i = 0; i < n; i++) 
     for (j = 0; j < n; j++) 
     { 
      resCap[i][j] = *(capacity + i*n + j); 
      *(flow + i*n + j) = 0; // no initial flow 
     } 

    // Augment path with BFS from source to sink 
    while (bfs(n, s, t, &(resCap[0][0]), path)) 
    { 
     // find min of the augmenting path 
     for (j = t; j != s; j = path[j]) 
     { 
      i = path[j]; 
      min_path = min(min_path, resCap[i][j]); 
     } 

     // update residual capacities and flows on both directions 
     for (j = t; j != s; j = path[j]) 
     { 
      i = path[j]; 
      if(*(capacity + i*n + j) > 0) 
      *(flow + i*n + j) += min_flow_path; 
      else 
      *(flow + j*n + i) -= min_flow_path; 

      resCap[i][j] -= min_flow_path; 
      resCap[j][i] += min_flow_path; 
     } 
    } 
} 

这里是在情况下提供给我们的测试代码就需要:

int main(void) 
{ int cap[1000][1000], flow[1000][1000]; 
    int i,j, flowsum; 
    for(i=0; i< 1000; i++) 
    for(j =0; j< 1000; j++) 
     cap[i][j] = 0; 

    for(i=0; i<499; i++) 
    for(j=i+1; j<500; j++) 
     cap[i][j] = 2; 
    for(i=1; i<500; i++) 
    cap[i][500 + (i/2)] =4; 
    for(i=500; i < 750; i++) 
    { cap[i][i-250]=3; 
    cap[i][750] = 1; 
    cap[i][751] = 1; 
    cap[i][752] = 5; 
    } 
    cap[751][753] = 5; 
    cap[752][753] = 5; 
    cap[753][750] = 20; 
    for(i=754; i< 999; i++) 
    { cap[753][i]=1; 
     cap[i][500]=3; 
     cap[i][498]=5; 
     cap[i][1] = 100; 
    } 
    cap[900][999] = 1; 
    cap[910][999] = 1; 
    cap[920][999] = 1; 
    cap[930][999] = 1; 
    cap[940][999] = 1; 
    cap[950][999] = 1; 
    cap[960][999] = 1; 
    cap[970][999] = 1; 
    cap[980][999] = 1; 
    cap[990][999] = 1; 
    printf("prepared capacity matrix, now executing maxflow code\n"); 
    maximum_flow(1000,0,999,&(cap[0][0]),&(flow[0][0])); 
    for(i=0; i<=999; i++) 
    for(j=0; j<=999; j++) 
    { if(flow[i][j] > cap[i][j]) 
     { printf("Capacity violated\n"); exit(0);} 
    }  
    flowsum = 0; 
    for(i=0; i<=999; i++) 
    flowsum += flow[0][i]; 
    printf("Outflow of 0 is %d, should be 10\n", flowsum); 
    flowsum = 0; 
    for(i=0; i<=999; i++) 
    flowsum += flow[i][999]; 
    printf("Inflow of 999 is %d, should be 10\n", flowsum); 

    printf("End Test\n"); 
} 
+0

一个调试器,或打印的中间步骤,检查你收到什么线分段错误。这个过程称为调试。如果你不知道要调试你的代码,那么你的其他编程技巧就没用了。 – user31264

+0

对不起!我忘了在我的帖子中提到,我确实使用gdb来查找我的分段错误的位置,我在“resCap [i] [j] = *(capacity + i * n + j)”处点击它;“我相信我的问题是我如何将原始容量矩阵复制到剩余容量矩阵中,然而我没有做任何尝试似乎是正确的。 –

+0

在循环的每次迭代中都会打印'i'。你会知道你会得到分段错误。那么,对于这个'i',在最内层循环的每一次迭代处打印'j'。 – user31264

回答

0

此行很可能将段错误,但它使用锵。

int i, j, resCap[n][n], path[n]; 

你正在声明一个非常大的数组。当您尝试使用calloc分配它时,可看到多大。试试这个,不要忘记free它使用相同的循环。

int **resCap2 = calloc(1, n * sizeof(int *)); 
assert(resCap2); 
for (i = 0; i < n; i++) { 
    resCap2[i] = calloc(1, n * sizeof(int)); 
    assert(resCap2[i]); 
} 

这是使用了大量的空间,即

(1000 * sizeof(int*) * (1000 * n * sizeof(int))) 
+1

它导致段错误,它可能是由一个计算器引起的。 http://stackoverflow.com/questions/2685413/what-is-the-difference-between-a-segmentation-fault-and-a-stack-overflow – Harry