2016-05-16 58 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