java最大流ford,最大流Ford-Fulkerson算法源代码

源代码如下:

/*

* Graph Algorithm: 有流量上下界的最大流和最小流

* by billjeff

* 2007/Aug/12

*/

#include #include #include using namespace std ;

#define file_io

#define debug

class Graph {

private:

const static int MAXNODE = 100 ;

struct node{

float lower ;

float upper ;

} ;

struct networkNode{

float l, u ; // max volmun, min volumn ;

float curr ; // current volumn ;

} ;

node _matrix[MAXNODE][MAXNODE] ; // Graph edge volumn array, if one edge's lower < 0

// there is no edge from i to j ;

float _newMatrix[MAXNODE+2][MAXNODE+2] ; // store new graph ;

networkNode _flowMatrix[MAXNODE+1][MAXNODE+2] ; // for ford-fulckson algorithm

int _s, _t ; // start and end point ;

int _nodeNum, _edgeNum ;

bool _isFlowExisted ; // return value of isFlowAvailable() ;

protected:

void graphAdjust(){

// put another two nodes into the graph and re-arrange the volumn of edges;

// _nodeNum+1 as new start node, _nodeNum+2 as new end node ;

int tempNodeNum = _nodeNum+2 ;

float tempVol, tempVolSum ;

for ( int i = 0 ; i < tempNodeNum ; ++i )

for ( int j = 0 ; j < tempNodeNum ; ++j ){

if ( i == _nodeNum && j < _nodeNum ){ // new start to other old nodes

tempVolSum = 0 ;

for ( int k = 0 ; k < _nodeNum ; ++k ){

tempVol = _matrix[k][j].lower ;

if ( tempVol != -1 )

tempVolSum += tempVol ;

}

_newMatrix[i][j] = tempVolSum ;

}

else

if ( j == _nodeNum+1 && i < _nodeNum ){

tempVolSum = 0 ;

for ( int k = 0 ; k < _nodeNum ; ++k ){

tempVol = _matrix[i][k].lower ;

if ( tempVol != -1 )

tempVolSum += tempVol ;

}

_newMatrix[i][j] = tempVolSum ;

}

else

if ( i < _nodeNum && j < _nodeNum ){

tempVol = _matrix[i][j].lower ;

_newMatrix[i][j] = ((tempVol == -1) ? -1 : (_matrix[i][j].upper-tempVol)) ;

}

else

_newMatrix[i][j] = -1 ;

}

//_s = _nodeNum ;

//_t = _s+1 ;

_newMatrix[_s][_t] = numeric_limits::max() ;

_newMatrix[_t][_s] = _newMatrix[_s][_t] ;

return ;

}

void graphAdjust2(){ // 根据已经求出的扩展图的最大流,去掉附加节点和边

float tempFlow ;

for ( int i = 0 ; i < _nodeNum ; ++i )

for ( int j = 0 ; j < _nodeNum ; ++j ){

tempFlow = _matrix[i][j].lower ;

if ( tempFlow != -1 ){

_flowMatrix[i][j].l += tempFlow ;

_flowMatrix[i][j].curr += tempFlow ;

_flowMatrix[i][j].u += tempFlow ;

}

}

if ( _matrix[_s][_t].lower != -1 ){

_flowMatrix[_s][_t].l = _matrix[_s][_t].lower ;

_flowMatrix[_s][_t].u = _matrix[_s][_t].upper ;

_flowMatrix[_s][_t].curr += _matrix[_s][_t].upper-_matrix[_s][_t].lower ;

}

else{

_flowMatrix[_s][_t].l = -1 ;

_flowMatrix[_s][_t].u = -1 ;

_flowMatrix[_s][_t].curr = 0 ;

}

if ( _matrix[_t][_s].lower != -1 ){

_flowMatrix[_t][_s].l = _matrix[_t][_s].lower ;

_flowMatrix[_t][_s].u = _matrix[_t][_s].upper ;

_flowMatrix[_t][_s].curr += _matrix[_t][_s].upper-_matrix[_t][_s].lower ;

}

else{

_flowMatrix[_t][_s].l = -1 ;

_flowMatrix[_t][_s].u = -1 ;

_flowMatrix[_t][_s].curr = -0 ;

}

}

int check( bool *c, int *p, int num ){

for( int i = 0 ; i < num ; ++i )

if ( (!c[i]) && (p[i] != (MAXNODE+3)) )

return i ;

return -1 ;

}

bool ford( int s, int t, int num, float &a, int *p ){

bool checked[MAXNODE] ;

//int max = numeric_limits::max() ;

memset( checked, 0, MAXNODE ) ;

for ( int i = 0 ; i < num ; ++i )

p[i] = MAXNODE+3 ;

p[s] = s ;

int flag = 0 ;

while ( true ){

flag = check( checked, p, num ) ;

#ifdef debug1

cout << "s = " << s << ", t = " << t << ", flag = " << flag << endl ;

cout << p[flag] << " " << checked[flag] << endl ;

cout << ( !checked[flag] && (p[flag] != (MAXNODE+3)) ) << endl ;

#endif

if ( flag == t || flag == -1 )

break ;

for ( int i = 0 ; i < num ; ++i )

if ( (p[i] == (MAXNODE+3)) && (_flowMatrix[flag][i].u != -1 || _flowMatrix[i][flag].u != -1) ){

#ifdef debug1

if ( i == 0 ){

cout << "i=0->" << p[i] << endl ;

cout << _flowMatrix[flag][i].u << " " << _flowMatrix[flag][i].u << " " << _flowMatrix[flag][i].curr << endl ;

cout << _flowMatrix[i][flag].u << " " << _flowMatrix[i][flag].l << " " << _flowMatrix[i][flag].curr << endl ;

}

#endif

if ( _flowMatrix[flag][i].u != -1 && _flowMatrix[flag][i].u > _flowMatrix[flag][i].curr ){

p[i] = flag ;

#ifdef debug1

cout << "flag = " << flag << ", i = " << i << endl ;

#endif

}

if ( _flowMatrix[i][flag].u != -1 && _flowMatrix[i][flag].l < _flowMatrix[i][flag].curr ){

p[i] = -flag ;

#ifdef debug1

cout << "-flag = " << flag << ", i = " << i << endl ;

#endif

}

}

checked[flag] = true ;

}

if ( flag != t ) // do not reach the terminal node

return false ;

a = numeric_limits::max() ;

int pc = abs(p[t]), c = t ;

float vol ;

#ifdef debug1

for( int i = 0 ; i < num ; ++i )

cout << p[i] << " " ;

cout << endl ;

#endif

while ( c != s ){

#ifdef debug1

cout << c << endl ;

#endif

if ( p[c] < 0 ) {

vol = _flowMatrix[c][pc].curr - _flowMatrix[c][pc].l ;

}

else

vol = _flowMatrix[pc][c].u - _flowMatrix[pc][c].curr ;

a = (a>vol) ? vol : a ;

c = pc ;

pc = abs(p[c]) ;

}

#ifdef debug1

cout << "a = " << a << endl ;

#endif

return true ;

}

void fulkerson( int s, int t, float a, int *p ){

int c = t ;

int pc = abs(p[c]) ;

while ( c != s ){

if ( p[c] < 0 )

_flowMatrix[c][pc].curr -= a ;

else

_flowMatrix[pc][c].curr += a ;

c = pc ;

pc = abs(p[c]) ;

}

return ;

}

void ford_fulkerson( int s, int t, int num ){

float amount ;

int p[MAXNODE] ;

while ( ford( s, t, num, amount, p ) )

fulkerson( s, t, amount, p ) ;

}

public:

Graph() : _isFlowExisted(false){

}

void readGraph(){

cout << "Enter the number of nodes: " ;

cin >> _nodeNum ;

cout << "Enter the start node and end node: " ;

cin >> _s >> _t ;

--_s ; --_t ;

for ( int i = 0 ; i < _nodeNum ; ++i )

for ( int j = 0 ; j < _nodeNum ; ++j )

_matrix[i][j].lower = -1 ;

// input format: edge's start node, end node, lower, upper ;

cout << "Enter the number of edges: " ;

cin >> _edgeNum ;

for ( int i = 0 ; i < _edgeNum ; ++i ){

int s, t ;

cin >> s >> t ;

--s ; --t ;

if ( s < 0 || s >= _nodeNum || t < 0 || t >= _nodeNum ){

cout << "Error! Invalid input data!" << endl ;

exit(1) ;

}

cin >> _matrix[s][t].lower >> _matrix[s][t].upper ;

}

return ;

}

bool isFlowAvailable(){ // judge that whether there is a available flow route;

int tempNodeNum = _nodeNum + 2 ;

for ( int i = 0 ; i < tempNodeNum ; ++i )

for ( int j = 0 ; j < tempNodeNum ; ++j ){

_flowMatrix[i][j].l = 0 ;

_flowMatrix[i][j].u = _newMatrix[i][j] ;

_flowMatrix[i][j].curr = 0 ;

}

ford_fulkerson( _nodeNum, _nodeNum+1, _nodeNum+2 ) ;

bool flag = true ;

for ( int i = 0 ; i < _nodeNum ; ++i )

if ( _flowMatrix[_nodeNum][i].l > 0 && _flowMatrix[_nodeNum][i].u != _flowMatrix[_nodeNum][i].curr ){

flag = false ;

break ;

}

return flag ;

}

void maxFlow(){

if ( !isFlowAvailable() ){

cout << "There is no available flow existed!" << endl ;

return ;

}

graphAdjust2() ;

#ifdef debug1

cout << "In maxFlow().. After adjusting.." << endl ;

for ( int i = 0 ; i < _nodeNum ; ++i )

for ( int j = 0 ; j < _nodeNum ; ++j )

cout << i

cout << "---------" << endl ;

#endif

ford_fulkerson( _s, _t, _nodeNum ) ;

return ;

}

void minFlow(){ // get the minmum flow

if ( !isFlowAvailable() ){

cout << "There is no available flow existed!" << endl ;

return ;

}

graphAdjust2() ;

ford_fulkerson( _t, _s, _nodeNum ) ;

return ;

}

void printGraph(){

cout << "Start and end node: " ;

cout << _s << " " << _t << endl ;

cout << "Graph edges' info: " << endl ;

for ( int i = 0 ; i < _nodeNum ; ++i )

for ( int j = 0 ; j < _nodeNum ; ++j ){

if ( _matrix[i][j].lower != -1 ){

cout << _matrix[i][j].lower << " " << _matrix[i][j].upper ;

cout << endl ;

}

}

cout << "\nAfter Adjusting..." << endl ;

graphAdjust() ;

#define _matrix _newMatrix

//_nodeNum += 2 ;

cout << "Start and end node: " ;

cout << _nodeNum << " " << _nodeNum+1 << endl ;

cout << "Graph edges' info: " << endl ;

for ( int i = 0 ; i < _nodeNum+2 ; ++i ){

for ( int j = 0 ; j < _nodeNum+2 ; ++j ){

cout << _matrix[i][j] << " " ;

}

cout << endl ;

}

//_nodeNum -= 2 ;

cout << "After Ford-Fulkerson Algorithm..." << endl ;

cout << (isFlowAvailable()? "Yes" : "No") << endl  ;

for ( int i = 0 ; i < _nodeNum+2 ; ++i )

for ( int j = 0 ; j < _nodeNum+2 ; ++j )

cout << i

cout << "---------" << endl ;

/*

cout << "After maxFlow()..." << endl ;

maxFlow() ;

for ( int i = 0 ; i < _nodeNum ; ++i )

for ( int j = 0 ; j < _nodeNum ; ++j )

cout << i

cout << "---------" << endl ;

*/

cout << "After minFlow()..." << endl ;

minFlow() ;

for ( int i = 0 ; i < _nodeNum ; ++i )

for ( int j = 0 ; j < _nodeNum ; ++j )

cout << i

cout << "---------" << endl ;

//return ;

return ;

}

} ;

int main( void ){

#ifdef file_io

freopen( "in.txt", "r", stdin ) ;

freopen( "out.txt", "w", stdout ) ;

#endif

Graph g ;

g.readGraph() ;

g.printGraph() ;

#ifdef file_io

fclose( stdin ) ;

fclose( stdout ) ;

#endif

return 0 ;

}

一组测试数据如下:

6

1 6

8

1 2 1 3

1 3 0 10

2 4 5 7

3 5 2 8

4 3 1 3

4 6 3 5

5 2 2 4

5 6 2 6

按上面代码输出如下:

Enter the number of nodes: Enter the start node and end node: Enter the number of edges: Start and end node: 0 5

Graph edges' info:

1 3

0 10

5 7

2 8

1 3

3 5

2 4

2 6

After Adjusting...

Start and end node: 6 7

Graph edges' info:

-1 2 10 -1 -1 3.40282e+038 -1 1

-1 -1 -1 2 -1 -1 -1 5

-1 -1 -1 -1 6 -1 -1 2

-1 -1 2 -1 -1 2 -1 4

-1 2 -1 -1 -1 4 -1 4

3.40282e+038 -1 -1 -1 -1 -1 -1 0

0 3 1 5 2 5 -1 -1

-1 -1 -1 -1 -1 -1 -1 -1

After Ford-Fulkerson Algorithm...

Yes

0->0: base-0, max--1, curr-0

0->1: base-0, max-2, curr-2

0->2: base-0, max-10, curr-2

0->3: base-0, max--1, curr-0

0->4: base-0, max--1, curr-0

0->5: base-0, max-3.40282e+038, curr-0

0->6: base-0, max--1, curr-0

0->7: base-0, max-1, curr-1

1->0: base-0, max--1, curr-0

1->1: base-0, max--1, curr-0

1->2: base-0, max--1, curr-0

1->3: base-0, max-2, curr-0

1->4: base-0, max--1, curr-0

1->5: base-0, max--1, curr-0

1->6: base-0, max--1, curr-0

1->7: base-0, max-5, curr-5

2->0: base-0, max--1, curr-0

2->1: base-0, max--1, curr-0

2->2: base-0, max--1, curr-0

2->3: base-0, max--1, curr-0

2->4: base-0, max-6, curr-2

2->5: base-0, max--1, curr-0

2->6: base-0, max--1, curr-0

2->7: base-0, max-2, curr-2

3->0: base-0, max--1, curr-0

3->1: base-0, max--1, curr-0

3->2: base-0, max-2, curr-1

3->3: base-0, max--1, curr-0

3->4: base-0, max--1, curr-0

3->5: base-0, max-2, curr-0

3->6: base-0, max--1, curr-0

3->7: base-0, max-4, curr-4

4->0: base-0, max--1, curr-0

4->1: base-0, max-2, curr-0

4->2: base-0, max--1, curr-0

4->3: base-0, max--1, curr-0

4->4: base-0, max--1, curr-0

4->5: base-0, max-4, curr-0

4->6: base-0, max--1, curr-0

4->7: base-0, max-4, curr-4

5->0: base-0, max-3.40282e+038, curr-5

5->1: base-0, max--1, curr-0

5->2: base-0, max--1, curr-0

5->3: base-0, max--1, curr-0

5->4: base-0, max--1, curr-0

5->5: base-0, max--1, curr-0

5->6: base-0, max--1, curr-0

5->7: base-0, max-0, curr-0

6->0: base-0, max-0, curr-0

6->1: base-0, max-3, curr-3

6->2: base-0, max-1, curr-1

6->3: base-0, max-5, curr-5

6->4: base-0, max-2, curr-2

6->5: base-0, max-5, curr-5

6->6: base-0, max--1, curr-0

6->7: base-0, max--1, curr-0

7->0: base-0, max--1, curr-0

7->1: base-0, max--1, curr-0

7->2: base-0, max--1, curr-0

7->3: base-0, max--1, curr-0

7->4: base-0, max--1, curr-0

7->5: base-0, max--1, curr-0

7->6: base-0, max--1, curr-0

7->7: base-0, max--1, curr-0

---------

After minFlow()...

0->0: base-0, max--1, curr-0

0->1: base-1, max-3, curr-3

0->2: base-0, max-10, curr-2

0->3: base-0, max--1, curr-0

0->4: base-0, max--1, curr-0

0->5: base--1, max--1, curr-0

1->0: base-0, max--1, curr-0

1->1: base-0, max--1, curr-0

1->2: base-0, max--1, curr-0

1->3: base-5, max-7, curr-5

1->4: base-0, max--1, curr-0

1->5: base-0, max--1, curr-0

2->0: base-0, max--1, curr-0

2->1: base-0, max--1, curr-0

2->2: base-0, max--1, curr-0

2->3: base-0, max--1, curr-0

2->4: base-2, max-8, curr-4

2->5: base-0, max--1, curr-0

3->0: base-0, max--1, curr-0

3->1: base-0, max--1, curr-0

3->2: base-1, max-3, curr-2

3->3: base-0, max--1, curr-0

3->4: base-0, max--1, curr-0

3->5: base-3, max-5, curr-3

4->0: base-0, max--1, curr-0

4->1: base-2, max-4, curr-2

4->2: base-0, max--1, curr-0

4->3: base-0, max--1, curr-0

4->4: base-0, max--1, curr-0

4->5: base-2, max-6, curr-2

5->0: base--1, max--1, curr-0

5->1: base-0, max--1, curr-0

5->2: base-0, max--1, curr-0

5->3: base-0, max--1, curr-0

5->4: base-0, max--1, curr-0

5->5: base-0, max--1, curr-0

---------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值