1. 程式人生 > >最大流問題講解(Lingo)

最大流問題講解(Lingo)

            第一節   圖論的基本知識

1. 圖的概念
定義 圖G(V,E)是指一個二元組(V(G),E(G)),其中:
(1)V(G)={v1,v2,…, vn}是非空有限集,稱為頂點集,
(2)E(G)是V(G)中的元素對(vi,vj)組成的集合稱為邊集。
這裡寫圖片描述
圖G:V(G)={v1,v2,v3,v4}
E(G)= {e1,e2,e3,e4,e5,e6}
e3=(v1,v3)

若圖G的邊是有方向的,稱G是有向圖,有向圖的邊稱為有向邊或弧。
常用術語
邊和它的兩端點稱為互相關聯.
與同一條邊關聯的兩個端點稱為相鄰的頂點,
與同一個頂點關聯的兩條邊稱為相鄰的邊.
3)端點重合為一點的邊稱為環.
4) 若一對頂點之間有兩條以上的邊聯結,
則這些邊稱為重邊.

這裡寫圖片描述

5)既沒有環也沒有重邊的圖,稱為簡單圖.
6) 若圖G的每一條邊e 都賦以一個實數w(e),
稱w(e)為邊e的權,
G連同邊上的權稱為賦權圖 ,
記為:G(V,E,W), W={w(e)| e∈E}
這裡寫圖片描述

7) 圖G的中頂點的個數, 稱為圖G的階;
圖中與某個頂點相關聯的邊的數目,稱為該頂點的度。
8)完全圖:若無向圖的任意兩個頂點之間都存在著一條邊,
稱此圖為完全圖。

2.圖的矩陣表示
鄰接矩陣: (以下均假設圖為簡單圖).
圖G的鄰接矩陣是表示頂點之間相鄰關係的矩陣:A=(aij),
其中:這裡寫圖片描述

                            無向圖G

這裡寫圖片描述這裡寫圖片描述
鄰接矩陣
A=(aij)
這裡寫圖片描述 這裡寫圖片描述

有向圖G
這裡寫圖片描述 這裡寫圖片描述
鄰接矩陣
A=(aij)
這裡寫圖片描述 這裡寫圖片描述

                第二節  最大流問題

定義:設G(V,E)為有向圖,若在每條邊e上定義一個非負權c,
則稱圖G為一個網路,稱c為邊e的容量函式,記為c(e)。
若在有向圖G(V,E)中有兩個不同的頂點vs與vt ,
若頂點vs只有出度沒有入度,稱vs為圖G的源,
若頂點vt只有入度沒有出度,
稱vt為G的匯,
若頂點v 既不是源也不是匯,
稱為v中間頂點。
這裡寫圖片描述

設u,v是網路G(V,E)的相鄰頂點,邊(u,v)上定義的函式f(u,v)
稱為邊(u,v)上的實際流量( u到v的流量 );
若對網路G(V,E)的任意相鄰頂點u,v 均成立: 0≤ f(u,v) ≤ c(u,v) ,
稱該網路為相容網路。
若v為網路G(V,E)的中間頂點,
有:這裡寫圖片描述

網路的總流量為從源vs 流出的總流量:這裡寫圖片描述

流入匯vt 總流量:這裡寫圖片描述

這裡寫圖片描述
這裡寫圖片描述

這裡寫圖片描述

例1 分組交換技術在計算機網路中發揮著重要作用,資訊從源節點到目的節點不再需要一條固定的路徑,而是將其分割為幾組,通過不同的路徑傳輸到目的節點,目的節點再重新組合還原檔案。現考察如圖所示的網路,圖中兩節點間的數字表示兩交換機間可用的頻寬,此時從節點1到節點9的最大頻寬為多少?
這裡寫圖片描述

設fij為從vi到vj的實際流量,得一個9階方陣:F=( fij)
記容量矩陣為:
這裡寫圖片描述

這裡寫圖片描述
Lingo程式碼:

sets: node/v1..v9/;
arc(node,node):c,f;
endsets
[OBJ]max=flow;
@for(node(i)|i#ne#1#and#i#ne#9:@sum(node(j):f(i,j))=@sum(node(j):f(j,i)));
@sum(node(j): f(1,j))=flow;
@sum(node(j): f(j,9))=flow;
@for(arc:@bnd(0,f,c));
data:
c=
0  2.5   0  5.6  6.1  0    0    0     0
0  0    7.1  0    0   3.6   0    0     0
0  0      0   0    0     0    0   3.4   0
0  0      0   0    4.9  0   7.4  0     0
0 2.4    0   0    0   7.2  5.7  0     0
0   0    3.8  0   0     0    0   5.3  4.5
0   0     0    0   0   3.8   0    0    6.7
0   0     0    0   0     0    0    0    7.4
0   0     0    0   0     0    0    0    0;
@text()=@table(f);
enddata

Lingo基礎:
這裡寫圖片描述


//圖片中比較抽象,下面我用C語言的結構體類比一下
/*
集  ←→  結構體

整合員  ←→  結構體的域

集屬性  ←→  結構體例項
*/
struct person {//person 相當於 setname
    //sex, age 相當於整合員
    char sex;
    int age;
};
struct person xiaoming;//小明相當於成員屬性
xiaoming.sex = 'M';
xiaoming.age = 20;

這裡寫圖片描述
這裡寫圖片描述


   #ne#  not equal(不等於)若兩邊運算值不相等,返回邏輯值為1;
           否則返回邏輯值為0;

   #and# 僅當兩邊的引數都為1時,結果為1;

   @bnd(L,x,U)    限制L≤x≤U
1@for

該函式用來產生對整合員的約束。基於建模語言的標量需要顯式輸入每個約束,不過@for函式允許只輸入一個約束,然後LINGO自動產生每個整合員的約束。

例4.10 產生序列{1,4,9,16,25}

model:

sets:

  number/1..5/:x;

endsets

  @for(number(I): x(I)=I^2);

end

2@sum

該函式返回遍歷指定的整合員的一個表示式的和。

例4.11 求向量[5134610]前5個數的和。

model:

data:

  N=6;

enddata

sets:

  number/1..N/:x;

endsets

data:

  x = 5 1 3 4 6 10;

enddata

  s=@sum(number(I) | I #le# 5: x);

end

答案:
這裡寫圖片描述