【网络流】

最大流问题之FF算法与EK算法 目录 问题描述: EK算法: 算法描述: 伪代码: 例子: 控制台对应输出为: 关键定理证明: 最大流最小割定理: 1推2: 2推3: 3推1: 时间复杂度分析 分析 关键边定义: 时间复杂度计算: FF算法: FF算法介绍 FF算法缺陷分析: 问题描述: G=(V,E)是一个有向图,其中每条边(u,v)有一个非负的容量值c(u,v),而且如果E中包含一条边... 阅读详情

放假以来把网络流看来几篇,今天终于有点感觉,网上很多资料,我认为网络流最难理解的是加反向边,这个东西纠结了很久,网上搜到一个blog才领悟到一句真理:“反向边的作用就是给程序一个可以后悔的机会”,详细请看下面的文章,由于自己对网络流还是vegetables bird,所以只好转一下人家写的好文章。

网络流(Network Flow)


     将每条有向边想象成传输物质的管道。每个管道都有一个固定的容量,可以看作是物质能流经该管道的最大速度(譬如可以想象为水流和河槽)。顶点是管道间的连接点,除了源点(S,Source)和汇点(T,Target)以外,物质只流经这些顶点。而不聚集在顶点中。

     注:下文提到的数字,基本都可加单位 “单位流量”来理解。

一、网络流基础

     网络流中的最大流研究的问题是:在不违背容量限制的条件下,把物质从源点传输到汇点的最大速率是多少?上边的图示中,还有些需要说明,设G = (V,E)是一个流网络,其容量函数为c(c(u, v),Capicity)。s 为源点,t 为汇点。G 的流是一个函数 f (Flow)。上图中每条边标记的是流网络的容量 c(u, v),右图中,G中的流 |f| = 19。图中只显示正网络流。如果 f(u,v) > 0,则标记(u,v)为 f(u,v)/ c(u,v)(斜杠仅仅用来区分流和容量,不表示相除)。如果 f(u,v)<= 0,边(u,v)只标记它的容量。譬如(s,v1)这条边,最大流量限制是16,但实际流过11,所以表示为11 / 16。

    网络流算法要基于三种思想:残留网络(Residual Network),增广路径(Augmenting Path)和割(Cut)。

     和开头同一个例子,上图,图(b)就是残留网络,仔细观察一下,应该就可以明白,譬如边(s,v1),从 s 到 v1 流过11,还剩5,所以残余容量是5,当然,流量是守恒的,所以反向从 v1 到 s 流过11。剩余的容量 + 反向平衡的流量共同构成了残留网络。对于名词“残留容量(Residual Capacity)”的定义:在不超过容量c(u,v)的条件下,从 u 到 v 之间可以压入的额外网络流量,就是(u,v)的残留容量(Residual Capacity),公式定义是:cf(u,v) = c(u,v) – f(u,v)。而残留网络Gf = (V,Ef)。

     图(b),阴影覆盖的边为增广路径 p ,其残留容量为 cf(p) = cf(v2,v3) = 4。看图应该就可以大概理解什么是增广路了。看图可以发现 s 到 v2还可以通过 5,v2到v3还可以通过 4,v3到 t 还可以流 5,按照常识,也可得出,这条路径还可以再流过 4 的结论。而从 s 输送 4 到 t 的这条路就是增广路。"增广路径 p”的定义:p 为残留网络Gf中从 s 到 t 的一条简单路径。在不违反边的容量限制条件下,增广路径上的每条边(u,v)可以容纳从 u 到 v 的某额外正网络流。Starvae师兄在讲解增广路时,有一段通俗的描述:

     假如有这么一条路,这条路从源点开始一直一段一段的连到了汇点,并且,这条路上的每一段都满足流量<容量,注意,是严格的<,而不是<=。那么,我们一定能找到这条路上的每一段的(容量-流量)的值当中的最小值delta。我们把这条路上每一段的流量都加上这个delta,一定可以保证这个流依然是可行流。这样我们就得到了一个更大的流,他的流量是之前的流量+delta,而这条路就叫做增广路。

另外,这里得出的,计算增广路流量的公式非常重要:cf(p) = min { cf(u,v):(u,v)在 p 上},因为最大流算法的核心基本也就是寻找增广路了。

最大流最小割定理:一个流是最大流,当且仅当它的残留网络不包含增广路径。

    流网络的割(S,T)将V划分为 S 和 T = V – S两部分,使得 s ∈ S,t ∈ T。如果 f 是一个流,则穿过割 (S,T)的净流被定义为 f (S,T)。割(S,T)的容量为 c(S,T)。一个网络的最小割就是网络中所有割中最小容量的割。

     上图中,流网络的割(S = {s,v1,v2},T = {v3,v4,t}),S中的顶点是黑色,T中的顶点是白色。穿越(S,T)的净流量为:f(v1,v3) + f(v2,v3) + f(v2,v4) = 12 + (-4) + 11 = 19;容量为:c(v1,v3) + c(v2,v4) = 12 + 14 = 26。可以看出,割的净流由双向的网络流组成。而割的容量仅由 S 到 T 的边计算而得。

     还有一个很有重要的知识:反向边。如图(a),1是源点,4是汇点。很明显如果第一次迭代找到的增广路是1→2→4和1→3→4,则最大流是2,但是如果第一次迭代找到的增广路是1→2→3→4,那么流量只有1,如图(b)是残留网络,这时候,反向边就起作用了,由于反向边的原因,第二次迭代的时候,又找到一条增广路1→2→3→4。这样下来,总的流量还是2。还是Starvae师兄的解释:

      当我们第二次的增广路走 3→2 这条反向边的时候,就相当于把 2→3 这条正向边已经是用了的流量给“退”了回去,不走 2→3 这条路,而改走从 2 点出发的其他的路也就是 2→4。(有人问如果这里没有 2→4 怎么办,这时假如没有 2→4 这条路的话,最终这条增广路也不会存在,因为他根本不能走到汇点)同时本来在 3→4 上的流量由 1→3→4 这条路来“接管”。而最终 2→3 这条路正向流量1,反向流量1,等于没有流量。反向边的作用就是给程序一个可以后悔的机会。—— 一语中的啊。(这句话我加的^^)


二、Ford-Fulkerson算法 

     Ford-Fulkerson算法在实际中并不常用,但是它提供了一种思想:先找到一条从源点到汇点的增广路径,这条路径的容量是其中容量最小的边的容量。然后,通过不断找增广路,一步步扩大流量,当找不到增广路时,就得到最大流了(最大流最小割定理)。可以看看Ford-Fulkerson算法的伪代码,

FORD-FULKERSON(G, s, t)
1  for each edge (u, v) ∈ E[G]
2       do f[u, v] ← 0
3          f[v, u] ← 0
4  while there exists a path p from s to t in the residual network Gf
5      do cf(p) ← min {cf(u, v) : (u, v) is in p}
6         for each edge (u, v) in p
7             do f[u, v] ← f[u, v] + cf(p)
8                f[v, u] ← -f[u, v]

     从伪代码可以看出,Ford-Fulkerson的核心过程就是:第4~8行的 while 循环反复找出 Gf 中的增广路径 p,并把沿 p 的流 f 加上其残留容量cf(p)。当不再有增广路径时,流 f 就是一个最大流。完整图示:

   (f)最后在 while 循环测试的残留网络,它没有增光路径,所以(e)中显示的流就是最大流。

三、压入重标记push_relabel算法O(VE)

Push-relabel用到一个很有趣的概念一Preflow(前置流)他允许流进的量比流出的量还要多,有水来就先流进来,流不出去再说。

Push-relabel算法的流程如下:  

1 )我们先假定一个高度函数 h ( u ) ,他代表u点的高度,只有

h ( u )比较高的点才能够将水流到h ( u )比较低的点;  


2 ) 在程序一开始的时候,让source node的高度是n ( node数) ,  其它点的高度都是 0 ,这样source node才有足够的高度可以流往其它地方 ;  


3 ) 然后, 让source node往其它所有跟他直接相邻的node ,都流水管宽度的水量 ( 流过去之后当然要计算剩下的网络情形,即计算 residual  edges(残留网络)


4 )对所有active node( 目前有水的 node )做 relabel(重标记)的动作:  在当某个node明明有水,但是他所连出去的所有对象的 h ( u ) 都比他还高, 则让他的h ( u ) 增加为至少有一条水管可以流出去的量,也就是让这个有水的 active node的高度变成比他连往的”高度最小的 n o d e ”+l , ( 流过去之后还是要计算剩下的网络情形


5 )对所有可以做push(压入)动作的node做push的动作。  所谓的Push动作是指 : 当某个node有水,并且他有可以流出去的边, 且他刚好比可以流出去的那个点高度高一点点 ( 高度恰好比他高 1 ) ,那就把某个node 的水流过去,要流多少呢?以下两者取 min。  流出去的水管的量( 也就是说,这个active node的水量很多,  足够把这条水管塞满( 饱和) ,这个时候就叫做saturating Push)(饱和压入)某个 n o d e 现在的水量( 这个 n o d e的水量不足以把流出去的这个水管填满,称作non saturating Push(不饱和压入)  


6 )重复Relabel和Push的工作,一直到没有active node为止,此时从source node所流出的总流量( P r e f l o w) ,就是这个图的最大流量。  

Push-relabel  algorithm 提供了最大流另一方向的思考,且就效率而言,Push -Relabel的复杂度为 o (vE )

这里以POJ 1459为例

#define MIN INT_MIN
#define MAX INT_MAX
#define N 110
int min(int a,int b){return a>b?b:a;}
int c[N][N];//残留容量
int ef[N];//顶点余流
int h[N];//顶点高度
int n;
int push_relabel(int s,int t){
    int i,j;
    int ans = 0;
    memset(h,0,sizeof(h));
    h[s] = t+1;//源点初始高度
    memset(ef,0,sizeof(ef));
    ef[s] = MAX;//源点初始余流
    queue<int> qq;
    qq.push(s);
    while(!qq.empty()){
        int u = qq.front();
        qq.pop();
        for(i=0;i<=t;i++){
            int p;
            int v = i;
            if(c[u][v]<ef[u])p = c[u][v];
            else p = ef[u];
            if(p>0 && (u==s || h[u] == h[v] +1)){
                c[u][v] -= p;
                c[v][u] += p;
                if(v==t)ans+=p;//如果到达了汇点,就将流值加入到最大流中
                ef[u] -= p;
                ef[v] += p;
                if(v!=s && v!=t)qq.push(v);//只有既不是源点也不是汇点才进队
            }
        }
        //如果不是源点且仍有余流,则重标记高度再进队。
        //这里只是简单的将高度增加了一个单位,也可以像上面所说的一样赋值为最低的相邻顶点的高度高一个单位
        if(u!= s && u!=t && ef[u]>0) {
            h[u]++;
            qq.push(u);
        }
    }
    return ans;
}
int main(){
    int np,nc,m;
    while(scanf("%d%d%d%d",&n,&np,&nc,&m) != -1){
        int s = n,t = n+1;
        int i,j;
        memset(c,0,sizeof(c));
        char ss[30];
        for(i=0;i<m;i++){
            int u,v,w;
            scanf("%s",ss);
            sscanf(ss,"(%d,%d)%d",&u,&v,&w);
            c[u][v] += w;
        }
        for(i=0;i<np;i++){
            int u,w;
            scanf("%s",ss);
            sscanf(ss,"(%d)%d",&u,&w);
            c[s][u] += w;
        }
        for(i=0;i<nc;i++){
            int v,w;
            scanf("%s",ss);
            sscanf(ss,"(%d)%d",&v,&w);
            c[v][t] += w;
        }
        printf("%d\n",push_relabel(s,t));
    }
    return 0;
}

四、Edmonds-Karp(EK)算法  O(V*E*E)

     EK算法基于Ford-Fulkerson算法,唯一的区别是将第 4 行用BFS(广度优先搜索)来实现对增广路径 p 的计算。EK算法伪代码基本和上边的Ford-Fulkerson算法一样。类似用DFS实现的还有Dinic算法。它们都属于SAP(Shortest Augmenting Path)算法,从英文即可看出,它们每次都在寻找最短增广路。对于EK算法,每次用一遍 BFS 寻找从源点 s 到终点 t 的最短路作为增广路径,然后增广流量 f 并修改残量网络,直到不存在新的增广路径。E-K 算法的时间复杂度为 O(VE^2),适用于稀疏边,由于 BFS 要搜索全部小于最短距离的分支路径之后才能找到终点,因此频繁的 BFS 效率是比较低的。实践中此算法使用的机会较少。

这里以 POJ 1273为例,这里可以作为EK模板,也是我的第一道网络流,mark一下

#define MIN INT_MIN
#define MAX INT_MAX
#define N 204

int c[N][N];//边容量
int f[N][N];//边实际流量
int pre[N];//记录增广路径
int res[N];//残余网络
queue<int> qq;
void init(){
    while(!qq.empty())qq.pop();
    memset(c,0,sizeof(c));
    memset(f,0,sizeof(f));
}
int EK(int s,int t){
    int i,j;
    int ans=0;
    while(1){
        memset(res,0,sizeof(res));
        res[s] = MAX;//源点的残留网络要置为无限大!否则下面找增广路出错
        pre[s] = -1;
        qq.push(s);
        //bfs找增广路径
        while(!qq.empty()){
            int x = qq.front();
            qq.pop();
            for(i=1;i<=t;i++){
                if(!res[i] && f[x][i] < c[x][i]){
                    qq.push(i);
                    pre[i] = x;
                    res[i] = min(c[x][i] - f[x][i], res[x]);//这里类似dp,如果有增广路,那么res[t]就是增广路的最小权
                }
            }
        }
        if(res[t]==0)break;//找不到增广路就退出
        int k = t;
        while(pre[k]!=-1){
            f[pre[k]][k] += res[t];//正向边加上新的流量
            f[k][pre[k]] -= res[t];//反向边要减去新的流量,反向边的作用是给程序一个后悔的机会
            k = pre[k];
        }
        ans += res[t];
    }
    return ans;
}
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m) != -1){
        int i,j;
        init();
        while(n--){
            int a,b,v;
            scanf("%d%d%d",&a,&b,&v);
            c[a][b]+=v;
        }
        printf("%d\n",EK(1,m));
    }
    return 0;
}

四、Improved SAP(ISAP)算法

      ISAP字面意思是改良的最短增广路算法。关于ISAP,一位叫 DD_engi 的神牛讲非常清楚,引用一下:

     SAP算法(by dd_engi):求最大流有一种经典的算法,就是每次找增广路时用BFS找,保证找到的增广路是弧数最少的,也就是所谓的 Edmonds-Karp 算法。可以证明的是在使用最短路增广时增广过程不超过 V * E次,每次 BFS 的时间都是O(E),所以 Edmonds-Karp 的时间复杂度就是O(V * E^2)。

     如果能让每次寻找增广路时的时间复杂度降下来,那么就能提高算法效率了,使用距离标号的最短增广路算法就是这样的。所谓距离标号,就是某个点到汇点的最少的弧的数量(另外一种距离标号是从源点到该点的最少的弧的数量,本质上没什么区别)。设点 i 的标号为D[i],那么如果将满足D[i] = D[j] + 1的弧(i,j))叫做允许弧,且增广时只走允许弧,那么就可以达到“怎么走都是最短路”的效果。每个点的初始标号可以在一开始用一次从汇点沿所有反向边的BFS求出,实践中可以初始设全部点的距离标号为0,问题就是如何在增广过程中维护这个距离标号。

     维护距离标号的方法是这样的:当找增广路过程中发现某点出发没有允许弧时,将这个点的距离标号设为由它出发的所有弧的终点的距离标号的最小值加一。这种维护距离标号的方法的正确性我就不证了。由于距离标号的存在,由于“怎么走都是最短路”,所以就可以采用DFS找增广路,用一个栈保存当前路径的弧即可。当某个点的距离标号被改变时,栈中指向它的那条弧肯定已经不是允许弧了,所以就让它出栈,并继续用栈顶的弧的端点增广。为了使每次找增广路的时间变成均摊O(V),还有一个重要的优化是对于每个点保存“当前弧”:初始时当前弧是邻接表的第一条弧;在邻接表中查找时从当前弧开始查找,找到了一条允许弧,就把这条弧设为当前弧;改变距离标号时,把当前弧重新设为邻接表的第一条弧,还有一种在常数上有所优化的写法是改变距离标号时把当前弧设为那条提供了最小标号的弧。当前弧的写法之所以正确就在于任何时候我们都能保证在邻接表中当前弧的前面肯定不存在允许弧。

    还有一个常数优化是在每次找到路径并增广完毕之后不要将路径中所有的顶点退栈,而是只将瓶颈边以及之后的边退栈,这是借鉴了Dinic算法的思想。注意任何时候待增广的“当前点”都应该是栈顶的点的终点。这的确只是一个常数优化,由于当前边结构的存在,我们肯定可以在O(n)的时间内复原路径中瓶颈边之前的所有边。

优化:

1.邻接表优化:

如果顶点多的话,往往N^2存不下,这时候就要存边:
存每条边的出发点,终止点和价值,然后排序一下,再记录每个出发点的位置。以后要调用从出发点出发的边时候,只需要从记录的位置开始找即可(其实可以用链表)。优点是时间加快空间节省,缺点是编程复杂度将变大,所以在题目允许的情况下,建议使用邻接矩阵。

2.GAP优化:

如果一次重标号时,出现距离断层,则可以证明ST无可行流,此时则可以直接退出算法。

3.当前弧优化:

为了使每次找增广路的时间变成均摊O(V),还有一个重要的优化是对于每个点保存“当前弧”:初始时当前弧是邻接表的第一条弧;在邻接表中查找时从当前弧开始查找,找到了一条允许弧,就把这条弧设为当前弧;改变距离标号时,把当前弧重新设为邻接表的第一条弧。

另外,ISAP简化的描述是:程序开始时用一个反向 BFS 初始化所有顶点的距离标号,之后从源点开始,进行如下三种操作:(1)当前顶点 i 为终点时增广 (2) 当前顶点有满足 dist[i] = dist[j] + 1 的出弧时前进 (3) 当前顶点无满足条件的出弧时重标号并回退一步。整个循环当源点 s 的距离标号 dist[s] >= n 时结束。对 i 点的重标号操作可概括为 dist[i] = 1 + min{dist[j] : (i,j)属于残量网络Gf}。

借用庄神的模板 http://www.zlinkin.com/?p=34 ,用它来过POJ 3469简直无敌!比Dinic快好几倍

const int MAXN=20010;
const int MAXM=500010;
int n,m;//n为点数 m为边数
int h[MAXN];
int gap[MAXN];
 int p[MAXN],ecnt;
int source,sink;
struct edge{
    int v;//边的下一点
    int next;//下一条边的编号
    int val;//边权值
}e[MAXM];

inline void init(){memset(p,-1,sizeof(p));eid=0;}
 
//有向
inline void insert1(int from,int to,int val){
	e[ecnt].v=to;
	e[ecnt].val=val;
	e[ecnt].next=p[from];
	p[from]=eid++;
 
	swap(from,to);
 
	e[ecnt].v=to;
	e[ecnt].val=0;
	e[ecnt].next=p[from];
	p[from]=eid++;
}
 
//无向
inline void insert2(int from,int to,int val){
	e[ecnt].v=to;
	e[ecnt].val=val;
	e[ecnt].next=p[from];
	p[from]=eid++;
 
	swap(from,to);
 
	e[ecnt].v=to;
	e[ecnt].val=val;
	e[ecnt].next=p[from];
	p[from]=eid++;
}
 

inline int dfs(int pos,int cost){
	if (pos==sink){
		return cost;
	}
 
	int j,minh=n-1,lv=cost,d;
 
	for (j=p[pos];j!=-1;j=e[j].next){
		int v=e[j].v,val=e[j].val;
		if(val>0){
			if (h[v]+1==h[pos]){
				if (lv<e[j].val) d=lv;
				else d=e[j].val;
 
				d=dfs(v,d);
				e[j].val-=d;
				e[j^1].val+=d;
				lv-=d;
				if (h[source]>=n) return cost-lv;
				if (lv==0) break;
			}
 
			if (h[v]<minh)	minh=h[v];
		}
	}
 
	if (lv==cost){
		--gap[h[pos]];
		if (gap[h[pos]]==0) h[source]=n;
		h[pos]=minh+1;
		++gap[h[pos]];
	}
 
	return cost-lv;
 
}
 
int sap(int st,int ed){
 
	source=st;
	sink=ed;
	int ans=0;
	memset(gap,0,sizeof(gap));
	memset(h,0,sizeof(h));
 
	gap[st]=n;
 
	while (h[st]<n){
		ans+=dfs(st,INT_MAX);
	}
 
	return ans;
}

对于EK算法与ISAP算法的区别:

     EK算法每次都要重新寻找增广路,寻找过程只受残余网络的影响,如果改变残余网络,则增广路的寻找也会随之改变;SAP算法预处理出了增广路的寻找大致路径,若中途改变残余网络,则此算法将重新进行。EK处理在运算过程中需要不断加边的最大流比SAP更有优势。

*****************************************************************************************************************************************************

本文只介绍基础的网络流知识,网络流非常强大,许多问题都可以转化为网络流模型,进一步的,可以去看看Starfall大神的这篇《【网络流】总结》,这篇只是一个目录性质,里边很多超链接,后面资源更丰富。其中提到了6篇国家集训队论文,正好电脑里都有,就打包传到优快云了,点击跳转到下载页面。我只看过其中的两三篇,这帮高中生写的实在牛叉。

      记得当年看时,觉得这篇《最大流在信息学竞赛中应用的一个模型》当做入门非常好,看完后会发现,原来组合数学都可以用最大流来解,还有什么不可以的。另外,最经典,最全面的要数胡波涛这篇的《最小割模型在信息学竞赛中的应用》,如果想深入学习网络流,这帮家伙的论文绝对不能错过。

以上转自http://mindlee.net/2011/11/19/network-flow/ 有删改














图论-网络流①-什么是网络流 图论-网络流 参考文献: https://www.cnblogs.com/DuskOB/p/11216861.html https://blog.youkuaiyun.com/yjr3426619/article/details/82808303 https://blog.youkuaiyun.com/lym940928/article/details/90209172 https://baike.baidu.com... 阅读详情

相关推荐

从零开始学嵌入式之STM32——1.什么是STM32

它是ST公司推出的一系列单片机的统称。ST----指的是ST公司----意法半导体。意法半导体,成立于1987年,是由意大利的SGS微电子公司和法国的Thomson半导体公司合并而成。ARM目前主要是ARM架构处理器及外围组件的电路设计方案,知识产权授权的形式收取费用,其他公司根据ARM的方案设计出CPU产品。,它以应用为核心,软硬件可裁剪,旨在实现对设备的控制、监测或辅助功能,区别于通用计算机(如 PC、服务器)的 “一机多用” 属性。在嵌入式领域,目前主流的是cortex-M3内核推出的芯片。

qshdyy的博客 1854

网络流 (讲解 + 模板) ----- 详细

文章目录网络流Dinic算法 网络流 感谢博主 : https://www.cnblogs.com/rmy020718/p/9546071.html 感谢博主 : https://www.cnblogs.com/hyserendipity/p/8560525.html 感谢博主 : https://blog.youkuaiyun.com/weixin_43907802/article/details/84705855 感谢博主 : https://www.cnblogs.com/passione-123456/p/12

沐白白的博客 3741

从OVITO可视化到LAMMPS计算:ATOMSK堆垛层错模型的全流程避坑指南

本文提供了一份从ATOMSK建模、OVITO可视化诊断到LAMMPS计算的堆垛层错模型全流程实战指南。重点解析了构建“计算友好”模型的核心矛盾,并详细演示了如何通过添加真空层、原子包裹和能量最小化等关键步骤,规避周期性边界条件带来的非物理相互作用,确保广义层错能计算的可靠性与可复现性。

v4w5x6的博客 266

网络流(一) 最大流问题

在一个有向图上选择一个源点,一个汇点,每一条边上都有一个流量上限(以下称为容量),即经过这条边的流量不能超过这个上界,同时,除源点和汇点外,所有点的入流和出流都相等,而源点只有流出的流,汇点只有汇入的流。这样的图叫做网络流。

这里是阿安的博客 5519

深入解析FOC电流环PI参数整定:从理论到实践

本文深入解析了FOC(磁场定向控制)中电流环PI参数整定的核心原理与实践方法。文章从永磁同步电机模型出发,详细阐述了基于带宽与零极点对消的工程法及考虑逆变器延迟的二阶系统整定法两种经典策略,并提供了从理论计算到安全上电调试的完整步骤与常见问题解决方案,帮助工程师精准调校电机控制性能。

weixin_29164497的博客 450

稳定性性能系列之五——Native Crash深度分析:工具实战

深入理解Native Crash的机制与分析方法,掌握addr2line、ndk-stack、gdb等核心工具的实战使用,学会从Tombstone文件中快速定位问题根因

Cheson的专栏 1547

网络流(Flow Network)

网络流。

KaiserWilheim的博客 3230

30分钟用 Restful ABAP Programming(RAP)模型开发一个支持增删改查的 Fiori 应用

2016年时,Jerry曾经写过一系列关于SAP Fiori Smart Template(现在更名为Fiori Elements了)的博客,介绍了所谓的MDD开发方法论 - Metadata Driven Development,即通过开发维护了对应annotation(注解)的CDS view,结合SAP WebIDE,能够花费最少的编程代价,就能够在短时间内获得一个支持增删改查的Fiori应......

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5952

[网络流]学习笔记:一次理解网络流!

学一个新算法,总要翻多而杂的blog,收获不多。所以我就致力于把学习笔记总结,希望一遍看懂。 简单入门 (但是不全) 一、从概念入手 网络流用于解决流量问题 网络流:所有弧上流量的集合f={f(u,v)},称为该容量网络的一个网络流. 定义:带权的有向图G=(V,E),满足以下条件,则称为网络流图(flow network): 仅有一个入度为0的顶点s,称s为源点 仅有一个出...

A_Comme_Amour的博客 4万+

ADS电路仿真方法综述:原理与应用

在射频与微波电路设计中,精确的仿真技术是验证性能的关键。ADS(Advanced Design System)作为行业标准工具,集成了多种仿真方法,适用于不同场景。本文将系统解析瞬态分析、谐波平衡(HB)、交流分析(AC)、直流分析(DC)、S参数、大信号SP(LSSP)及包络分析的原理、实现机制与应用场景。

u014344410的博客 481

通信原理 | python调制识别数据及代码

数据集包含了从-20dB 到+18dB 总共 20 个信噪比(步长为 2)下的 11 种调制信号, 包括 AM-DSB、 AM-SSB 和 WBFM 三种模拟调制信号,以及 BPSK、 QPSK、 8PSK、 CPFSK、 GFSK、 PAM4、 QAM16 和 QAM64 八种数字调制信号。其中信号的中心频率为 200KHz,采样频率为 1Msamp/s,且每个信噪比下每种调制信号包含 1000 个信号。其中每个信号包含 IQ 两路数据,且每一路数据都包含有 128 个采样点。

若北辰 1758

网络流模板 网络流题型大荟萃

以HDU4560为例,整理了很多网络流的题目—— #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; void fre() { freopen("c://test//inpu

snowy_smile的博客 1263

【博文汇总】I2C总线学习

将这一周学习I2C总线的文章汇总一下。 基础知识学习 触发器的建立时间和保持时间 如何学习总线技术 TTL电平和CMOS电平 深入理解 关于I2C和SPI总线协议 I2C总线深入浅出 I2C总线信号时序总结 对I2C总线协议的一些理解 对I2C总线的时钟同步和总线仲裁的深入理解 I2C总线学习终结,开始SPI总线的学习 深入理解IIC总线时序

ce123的技术博客 6215

网络流初步

由于图论学习总结内容过多,全放在一篇博客过于冗长现进行拆分,本文是图论学习总结(For XCPC)的网络流初步部分

ChuanhuaYu的博客 1426

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

网络流量分析与网络流量采集:深入了解与实用指南

网络流量分析是指对通过计算机网络传输的数据包进行检测、解析和解读的过程。监控网络性能:通过分析网络流量,可以识别网络瓶颈和性能问题,从而优化网络配置,提高整体网络性能。故障排除:当网络出现问题时,网络流量分析可以帮助快速定位故障点,缩短修复时间。安全防护:通过分析异常流量模式,可以检测网络攻击、数据泄露等安全威胁,并及时采取防护措施。

Johnstons的博客 2630

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

网络流(1)——网络、流网络和网络流

  在现实世界中,我们的生活受到大量网络的支配。网络流可以表示很多模型,比如管道中的石油、高压线中电流,或者计算机网络中的数据。网络流也可以解决很多问题,比如如何进行道路交通管控,以便有效地缓解早高峰的拥堵;在物流网运输中,在满足供需关系的同时,怎样使渠道成本最低;在轰炸机执行轰炸任务时,怎样才能给敌军补给线造成更严重的打击。这些问题都有现成的网络流算法,别再以为网络流仅仅是网络中的比特流。 网...

我是8位的 1776

网络流总结

上下界网络流 上下界可行流 考虑把每条边必须经过的流量拆出来,那么就变成了某些边必须满流,求一组可行流。我们把必须满流的边拉出来,假想一个源汇 s,t,每条边起点连向 s,t 连向终点,跑 s 到 t 的最大流,若拉出来的边满流就找到了一组可行流。如果本来就有源汇,那么从 t 向 s 连流量正无穷的边,就转成无源汇网络流了。 上下界最大流 先求出一个可行流,把连向超级源汇的边删掉,再从 s 到 t...

Hellsegamosken 956

网络流C++

网络流C++

缪语博的博客 1296

网络流

Ford-Fulkerson 准确来说,这是一个方法不是具体的算法 主要思路,找增广路,更新边,但是这个方法并没有规定怎么找增广路 时间复杂度O((V+E)*maxflow) dfs邻接矩阵 #include<cstdio> #include<cstring> using namespace std; const int N=205; const long long int MAX=0x7FFFFFFFFFFFFFFF; long long int edge[N][N].

思维缜密的博客 1372

网络流算法

网络流最大流算法 网络流是图论里面最难,也只最有有魅力的分支,事实上图论中很多问题都可以转化为求解最大流的问题,比如说求解最小割的问题,使用网络流算法会使得求解最小割的时间复杂度降低很多,并且网络流算法还具有很大的普适性。 这里我就不多介绍网络流是什么了,相信关于网络流的具体模型,定义有很多科普文章进行了详细的介绍,这里只是给出两种具体的实现算法,以及思想原理。 Edmonds-Krap算法   该算法是一种在网络流残余图上寻找增光路的算法,寻找增广路的过程其实就是DFS或者BFS从源点搜索图都可以,但是关

qq_37957064的博客 2242

[网络流]一篇文章搞定网络流

最大流算法: (2)Edmonds-Karp算法(EK算法) 基于邻接矩阵实现的EK算法: #include<stdio.h> #include<queue> #include<string.h> #include<algorithm> using namespace std; const int maxn = 300;///邻接矩阵适合点比较小的图 const int MAX = ((1<<31)-1); int n; int pre[max

IT博客-wusheng_z 542

网络流衍生物——有上下界网络流の板子

颓废去颓废去明天就要上学了qwq

ADP+Pi==ATP 1127

网络流!

网络流!网络流模型最小割模型二分图最大匹配二分图的最小点覆盖二分图的最大独立集二分图的最大团两个集合!最大权闭合子图DAG上的最小路径覆盖有上下限的网络流费用流模型有递增费用的费用流 网络流好难啊! 整理一下网络流的常见模型。 网络流模型 网络流的模型很多很难想,但是如果知道建图方式后就会发现建图很显然。 最小割模型 我们已经知道了最大流是什么东西,那么最小割就是在这个图上删掉若干的边,使得不存在一条从源点到汇点的路径,并且删掉的边权值和最小。 做法就是直接对原图跑最大流即可,求出来的最大流就是最小割。 这

u014435641的博客 265

图论-网络流

撸了今年阿里、头条和美团的面试,我有一个重要发现.......>>> 前言 大家好,祝大家2017年身体健康,万事如意,开年第一篇blog网路流,希望大家指正。 网路流问题介绍 描述 设给定有向图G=(V,E),其边的容量为cvw.(这些容量可以代表通过一个管道的水的流量或者马路上的交通流量) s为发点,t为收点,最大网络流问题是求从s到t可以通过的最大流量。 性...

温安适的专栏 977

网络流复习

网络流复习 1.前言 几个月没碰过网络流了,想她了,所以捡起来,这么好的东西怎么能不用? 2.前置知识 网络流是啥? ​ 网络流是给定一个有向图,每条边有一个容量,这个图还有一个起点叫源点,一个终点叫汇点。把有向图想象成有多条路径的水流管道图,每条边的容量就是能经过该边的最大水流的流量。 最大流是啥? 最大流就是从源点能流向汇点的最大流量和。 增广路径是啥? 从源点到汇点的一条可行流路径。 3.算法 1.EKEKEK算法 思想:每次bfsbfsbfs找到一条增广路,然后建立反边权(使其具有反悔的贪心

Harris-H的博客 557

浅谈网络流

的路径 , 该路径上的所有边都有潜力 , 我们显然可以将这条路径上的流增加这些边中最小的潜力值 , 该操作称为增广. 可用 dfs 或 bfs 判断网络上是否存在可增广的路径.. 根据上文的代码 , 满足平衡条件的情况下保证了流量最大 , 因此如果最大流达到了所有。在反悔机制的基础上 , 保证了该策略的正确性 , 该算法称为。在一张网络上 , 从源点流出 , 最终流入汇点的流.的容量. 特别的 , 图上有源点。我们称这条边是有潜力的 ,的上限) , 方程一定有解.在一张网络上 , 给定源点。

William_Wang_的博客 645
上一篇: 【转】POJ 图论、网络流题目
下一篇: 【网络流EK算法&压入重标记算法】POJ 1459
leolin_
博客等级 码龄16年 96粉丝 411原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值