【圖論】網絡流算法入門

(決定狠狠加訓圖論了,從一直想學但沒啟動的網絡流算法開始。)

網絡流問題

? 問題定義:在帶權有向圖 G = ( V , E ) G=(V, E) G=(V,E) 中,每條邊 e = ( u , v ) e=(u, v) e=(u,v) 有容量 c ( u , v ) c(u, v) c(u,v),求從源點 s s s 到匯點 t t t 的最大流量。

1. 最大流 = 最小割定理

? 最小割的定義
割(Cut)是將圖 G G G 的頂點分為兩個不相交集合 S S S T T T,其中 s ∈ S s \in S sS t ∈ T t \in T tT
割的容量是 所有從 S S S T T T 的邊的容量之和,即: 容量 ( S , T ) = ∑ u ∈ S , v ∈ T c ( u , v ) \text{容量}(S, T) = \sum_{u \in S, v \in T} c(u, v) 容量(S,T)=uS,vT?c(u,v)
? 最大流-最小割定理
在任何網絡中,最大流的值等于最小割的容量
直觀理解
? 流量受限于網絡中“最窄的瓶頸”,即最小割的容量。
? 最大流無法超過任何割的容量,而存在至少一個割的容量等于最大流。

? 證明思路

  1. 弱對偶性:最大流 ≤ 最小割(顯然成立)。
  2. 強對偶性:通過構造殘留網絡,證明存在一個割的容量等于最大流。
    當算法終止時,殘留網絡中 s s s 能到達的頂點集合 S S S,其余為 T T T,此時 S S S T T T 的邊流量飽和,容量等于最大流。

2. 殘留網絡與反向邊

? 殘留網絡 G f G_f Gf?
? 對每條邊 e = ( u , v ) e=(u, v) e=(u,v),定義其反向邊 e ′ = ( v , u ) e'=(v, u) e=(v,u),容量為當前流量 f ( u , v ) f(u, v) f(u,v)
? 殘留容量:
c f ( u , v ) = c ( u , v ) ? f ( u , v ) , c f ( v , u ) = f ( u , v ) c_f(u, v) = c(u, v) - f(u, v), \quad c_f(v, u) = f(u, v) cf?(u,v)=c(u,v)?f(u,v),cf?(v,u)=f(u,v)
? 作用:允許“退回”流量,尋找更優路徑。

? 增廣路徑
在殘留網絡 G f G_f Gf? 中找到一條從 s s s t t t 的路徑,路徑上的最小殘留容量稱為 增廣量
通過增加該路徑的流量,逐步逼近最大流。


3. 費用流問題

? 問題定義
在最大流問題的基礎上,每條邊 e = ( u , v ) e=(u, v) e=(u,v) 有一個單位流量費用 w ( u , v ) w(u, v) w(u,v),求在最大流的前提下,總費用最小的流。

? 關鍵思想
? 最小費用最大流:優先選擇費用最小的增廣路徑。
? 算法擴展
? Successive Shortest Path (SSP):每次用SPFA/Bellman-Ford找最短路增廣。
? Primal-Dual:結合Dijkstra和勢函數處理負權邊。
? Cost-Scaling:通過縮放費用值優化效率。

? 費用流的反向邊處理
反向邊的費用為 ? w ( u , v ) -w(u, v) ?w(u,v),表示退回流量時費用被抵消。


算法模板:

1. Dinic算法

? 原理

  1. 分層圖:通過BFS構建層次圖(將節點按到源點的最短距離分層)。
  2. 阻塞流:在分層圖上用DFS找增廣路徑,并通過“當前弧優化”跳過無效邊。
  3. 多路增廣:允許一次DFS找到多條增廣路徑,減少遞歸次數。
    ? 時間復雜度 O ( n 2 m ) O(n^2 m) O(n2m),實際表現優秀,適合大多數場景。
    ? 適用問題最大流問題,在稠密圖和稀疏圖中均表現良好。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define int long long
#define pb push_back
#define pii pair<int, int>
#define FU(i, a, b) for (int i = (a); i <= (b); ++i)
#define FD(i, a, b) for (int i = (a); i >= (b); --i)
const int MOD = 1e9 + 7;const int inf = 1e18;      // 表示無窮大的容量
const int maxn = 1e5 + 10; // 最大節點數// 邊的結構體
struct edge {int from, to; // 邊的起點和終點int cap;      // 邊的容量int flow;     // 邊當前的流量edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {}
};// Dinic算法實現類
struct Dinic {int n, m;           // 節點數、邊數int s, t;           // 源點、匯點vector<edge> edges; // 所有邊的集合,邊數兩倍(包含反向邊)vector<int> G[maxn]; // 鄰接表,G[i]保存節點i的所有邊在edges中的索引bool vis[maxn]; // BFS使用的訪問標記數組int d[maxn];    // 層次網絡中各節點的層次(距離)int cur[maxn]; // 當前弧優化數組,記錄每個節點當前處理的邊void init(int n) { // 初始化,n為節點數this->n = n;for (int i = 0; i < n; i++)G[i].clear();edges.clear();}// 清空所有邊的流量,用于多次計算不同流的情況void clear() {for (int i = 0; i < edges.size(); i++)edges[i].flow = 0;}// 將邊的容量減去已使用的流量,用于調整殘余網絡void reduce() {for (int i = 0; i < edges.size(); i++)edges[i].cap -= edges[i].flow;}// 添加一條從from到to,容量為cap的有向邊及其反向邊void addedge(int from, int to, int cap) {edges.push_back(edge(from, to, cap, 0)); // 正向邊,初始流量0edges.push_back(edge(to, from, 0, 0)); // 反向邊,初始容量0,流量0m = edges.size();G[from].push_back(m - 2); // 記錄正向邊在edges中的索引G[to].push_back(m - 1);   // 記錄反向邊在edges中的索引}// BFS構建層次網絡,返回是否存在從s到t的路徑bool BFS() {memset(vis, 0, sizeof(vis));queue<int> Q;Q.push(s); // 源點入隊vis[s] = true;d[s] = 0;while (!Q.empty()) {int x = Q.front();Q.pop();for (int i = 0; i < G[x].size(); i++) { // 遍歷x的所有鄰接邊edge &e = edges[G[x][i]];// 若邊的終點未訪問,且仍有剩余容量if (!vis[e.to] && e.cap > e.flow) {vis[e.to] = true;d[e.to] = d[x] + 1; // 層次+1Q.push(e.to);}}}return vis[t]; // 返回匯點是否可達}// DFS尋找增廣路徑,x為當前節點,a為當前路徑上的最小剩余容量int DFS(int x, int a) {if (x == t || a == 0) // 若到達匯點或剩余容量為0,直接返回return a;int flow = 0, f;// 使用當前弧優化,避免重復訪問已經處理過的邊for (int &i = cur[x]; i < G[x].size(); i++) {edge &e = edges[G[x][i]];// 層次遞增且存在剩余容量if (d[x] + 1 == d[e.to] &&(f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {e.flow += f;                  // 更新正向邊流量edges[G[x][i] ^ 1].flow -= f; // 反向邊流量減少(允許反向增廣)flow += f;                    // 累加到總流量a -= f;                       // 剩余容量減少if (a == 0)break; // 剩余容量為0,無需繼續搜索}}if (flow == 0)d[x] = -2; // 炸點優化return flow;}// 計算從s到t的最大流int Maxflow(int s, int t) {this->s = s;this->t = t;int flow = 0;while (BFS()) {                  // 每次BFS構建層次網絡memset(cur, 0, sizeof(cur)); // 重置當前弧flow += DFS(s, inf);         // 進行多路增廣,累加流量}return flow;}// 返回最小割的邊集合(需在Maxflow之后調用)vector<int> Mincut() {vector<int> ans;for (int i = 0; i < edges.size(); i++) {edge &e = edges[i];// 若邊的起點在層次網絡中可達,終點不可達,且為原始正向邊if (vis[e.from] && !vis[e.to] && e.cap > 0)ans.push_back(i);}return ans;}
} dinic;signed main() {cin.tie(0)->ios::sync_with_stdio(0);int n, m, s, t;cin >> n >> m >> s >> t;dinic.init(n + 5); // 初始化Dinic結構體while (m--) {int s, t, u;cin >> s >> t >> u;dinic.addedge(s, t, u); // 添加邊}// 計算從節點s到節點t的最大流cout << dinic.Maxflow(s, t);return 0;
}

2. ISAP算法(Improved Shortest Augmenting Path)

? 原理

  1. 動態分層:初始BFS分層后,逆向維護層次值(從匯點開始更新)。
  2. 重貼標簽:當某層節點耗盡時,調整節點層次(類似最大流中的GAP優化)。
  3. 單次BFS:僅需一次BFS初始化,后續通過回溯調整層次,減少重復分層。
    ? 時間復雜度 O ( n 2 m ) O(n^2 m) O(n2m),常數優于Dinic,適合大規模稀疏圖。
    ? 適用問題最大流問題,尤其適合邊數較多的圖。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <queue>
#include <ctime>
using namespace std;
const int maxn = 1100;
const int maxedges = 51000;
const int inf = 1 << 30;
struct edge {int to, flow;edge *next, *pair;edge() {}edge(int to, int flow, edge *next) : to(to), flow(flow), next(next) {}void *operator new(unsigned, void *p) { return p; }
};
struct ISAP {int gap[maxn], h[maxn], n, s, t;edge *cur[maxn], *first[maxn], edges[maxedges * 2], *ptr;void init(int n) {this->n = n;ptr = edges;memset(first, 0, sizeof(first));memset(gap, 0, sizeof(gap));memset(h, 0, sizeof(h));gap[0] = n;}void add_edge(int from, int to, int cap) {first[from] = new(ptr++)edge(to, cap, first[from]);first[to] = new(ptr++)edge(from, 0, first[to]);first[from]->pair = first[to];first[to]->pair = first[from];}int augment(int x, int limit) {if (x == t)return limit;int rest = limit;for (edge*& e = cur[x]; e; e = e->next) if (e->flow && h[e->to] + 1 == h[x]) {int d = augment(e->to, min(rest, e->flow));e->flow -= d, e->pair->flow += d, rest -= d;if (h[s] == n || !rest)return limit - rest;}int minh = n;for (edge *e = cur[x] = first[x]; e; e = e->next) if (e->flow)minh = min(minh, h[e->to] + 1);if (--gap[h[x]] == 0)h[s] = n;else++gap[h[x] = minh];return limit - rest;}int solve(int s, int t, int limit = inf) {this->s = s; this->t = t;memcpy(cur, first, sizeof(first)); // memcpy!int flow = 0;while (h[s] < n && flow < limit)flow += augment(s, limit - flow);return flow;}
}isap;
int main()
{freopen("D:\\in.txt", "r", stdin);int n, m;scanf("%d %d", &n, &m);isap.init(n + 5);while (m--){int s, t, u;scanf("%d %d %d", &s, &t, &u);isap.add_edge(s, t, u);}auto start = clock();printf("%d\n", isap.solve(1, n));double tot = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;printf("Isap: %f\n", tot);return 0;
}

3. HLPP算法(Highest Label Preflow Push)

? 原理

  1. 預流推進:允許節點暫時超額流量,通過“推進”操作將流量推向匯點。
  2. 最高標號優先:優先處理層次高的活躍節點,用優先隊列維護。
  3. GAP優化:當層次出現斷層時,直接標記斷層上方節點為不可達。
    ? 時間復雜度 ( O ( n 2 m ) ) (O(n^2 \sqrt{m})) (O(n2m ?)),理論最優,適合超大規模數據。
    ? 適用問題最大流問題,在特定題目中比Dinic/ISAP快數倍。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <ctime>
using namespace std;
const int maxn = 2e5 + 5, maxedges = 4e6 + 5, inf = 0x3f3f3f3f;
int n, m, s, t, tot;
int v[maxedges * 2], w[maxedges * 2], first[maxn], nxt[maxedges * 2];
int h[maxn], e[maxn], gap[maxn * 2], inq[maxn];//節點高度是可以到達2n-1的
struct cmp{inline bool operator()(int a, int b) const {return h[a] < h[b];//因為在優先隊列中的節點高度不會改變,所以可以直接比較}
};
queue<int> Q;
priority_queue<int, vector<int>, cmp> heap;
inline void add_edge(int from, int to, int flow) {tot += 2;v[tot + 1] = from; v[tot] = to; w[tot] = flow; w[tot + 1] = 0;nxt[tot] = first[from]; first[from] = tot;nxt[tot + 1] = first[to]; first[to] = tot + 1;return;
}
inline bool bfs() {memset(h + 1, 0x3f, sizeof(int) * n);h[t] = 0; Q.push(t);while (!Q.empty()){int now = Q.front(); Q.pop();for (int go = first[now]; go; go = nxt[go])if (w[go ^ 1] && h[v[go]] > h[now] + 1)h[v[go]] = h[now] + 1, Q.push(v[go]);}return h[s] != inf;
}
inline void push(int now) {for (int go = first[now]; go; go = nxt[go]) {if (w[go] && h[v[go]] + 1 == h[now]) {int d = min(e[now], w[go]);w[go] -= d; w[go ^ 1] += d; e[now] -= d; e[v[go]] += d;if (v[go] != s && v[go] != t && !inq[v[go]])heap.push(v[go]), inq[v[go]] = 1;if (!e[now])//已經推送完畢可以直接退出break;}}
}
inline void relabel(int now) {h[now] = inf;for (int go = first[now]; go; go = nxt[go])if (w[go] && h[v[go]] + 1 < h[now])h[now] = h[v[go]] + 1;return;
}
inline int hlpp() {int now, d;if (!bfs()) //s和t不連通return 0;h[s] = n;memset(gap, 0, sizeof(int) * (n * 2));for (int i = 1; i <= n; i++)if (h[i] < inf)++gap[h[i]];for (int go = first[s]; go; go = nxt[go]) {if (d = w[go]) {w[go] -= d; w[go ^ 1] += d; e[s] -= d; e[v[go]] += d;if (v[go] != s && v[go] != t && !inq[v[go]])heap.push(v[go]), inq[v[go]] = 1;}}while (!heap.empty()) {inq[now = heap.top()] = 0; heap.pop(); push(now);if (e[now]) {if (!--gap[h[now]]) //gap優化,因為當前節點是最高的所以修改的節點一定不在優先隊列中,不必擔心修改對優先隊列會造成影響for (int i = 1; i <= n; i++)if (i != s && i != t && h[i] > h[now] && h[i] < n + 1)h[i] = n + 1;relabel(now); ++gap[h[now]];heap.push(now); inq[now] = 1;}}return e[t];
}
int main()
{freopen("D:\\in.txt", "r", stdin);scanf("%d %d", &n, &m); s = 1; t = n;while (m--){int s, t, u;scanf("%d %d %d", &s, &t, &u);add_edge(s, t, u);}auto start = clock();printf("%d\n", hlpp());double tot = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;printf("HLPP: %f\n", tot);return 0;
}

4. MCMF-SPFA

? 原理

  1. SPFA找最短路:每次用SPFA(隊列優化的Bellman-Ford)找費用最小的增廣路。
  2. 沿最短路增廣:在最短路徑上調整流量并更新殘余網絡。
    ? 特點
    ? 支持負權邊,但SPFA可能被卡到 O ( n m ) O(nm) O(nm)
    ? 適合費用流中存在負權但邊數較少的圖。
    ? 適用問題最小費用最大流問題(費用流)。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <ctime>
using namespace std;
const int maxn = 20100;
const int inf = 1 << 30;
struct edge {int from, to, cap, flow, cost;edge(int u, int v, int c, int f, int w) : from(u), to(v), cap(c), flow(f), cost(w) {}
};
struct MCMF {int n, m;vector<edge> edges;vector<int> G[maxn];int inq[maxn];int d[maxn];int p[maxn];int a[maxn];void init(int n) {this->n = n;for (int i = 0; i < n; ++i)G[i].clear();edges.clear();}void add_edge(int from, int to, int cap, int cost) {edges.push_back(edge(from, to, cap, 0, cost));edges.push_back(edge(to, from, 0, 0, -cost));m = edges.size();G[from].push_back(m - 2);G[to].push_back(m - 1);}bool BellmanFord(int s, int t, int &flow, int &cost, int limit) {for (int i = 0; i < n; ++i)d[i] = inf;memset(inq, 0, sizeof(inq));d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = inf;queue<int> Q;Q.push(s);while (!Q.empty()) {int u = Q.front(); Q.pop();inq[u] = false;for (unsigned i = 0; i < G[u].size(); ++i) {edge &e = edges[G[u][i]];if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {d[e.to] = d[u] + e.cost;p[e.to] = G[u][i];a[e.to] = min(a[u], e.cap - e.flow);if (!inq[e.to]) {Q.push(e.to);inq[e.to] = true;}}}}if (d[t] == inf)return false;a[t] = min(a[t], limit - flow);flow += a[t];cost += d[t] * a[t];for (int u = t; u != s; u = edges[p[u]].from) {edges[p[u]].flow += a[t];edges[p[u] ^ 1].flow -= a[t];}return true;}int solve(int s, int t, int limit = inf) {int flow = 0, cost = 0;while (flow < limit && BellmanFord(s, t, flow, cost, limit));return cost;}
}mcmf;
int main()
{freopen("D:\\in.txt", "r", stdin);int n, m, k;scanf("%d %d %d", &n, &m, &k);mcmf.init(n + 10);for (int i = 1; i <= m; ++i) {int x, y, c, w;scanf("%d %d %d %d", &x, &y, &c, &w);mcmf.add_edge(x, y, c, w);}auto start = clock();printf("%d\n", mcmf.solve(1, n, k));double tot = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;printf("MCMF-spfa: %f\n", tot);return 0;
}

5. MCMF-Dijkstra

? 原理

  1. 勢函數去負權:通過勢函數 h ( u ) h(u) h(u)調整邊權,使得所有邊權非負。
  2. Dijkstra找最短路:用Dijkstra代替SPFA,時間復雜度更穩定。
  3. 勢函數更新:每次增廣后更新勢函數,保持邊權非負。
    ? 時間復雜度 O ( f m log ? n ) O(f m \log n) O(fmlogn) f f f為最大流量,適合正權圖。
    ? 適用問題最小費用最大流問題,且圖中無負權或通過勢函數消除負權。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <ctime>
using namespace std;
const int maxn = 21000;
const int inf = 1 << 30;
struct edge {int to, cap, cost, rev;edge() {}edge(int to, int cap, int cost, int rev) : to(to), cap(cap), cost(cost), rev(rev) {}
};
struct MCMF {int n, h[maxn], d[maxn], pre[maxn], num[maxn];vector<edge> G[maxn];void init(int n) {this->n = n;for (int i = 0; i <= n; ++i)G[i].clear();}void add_edge(int from, int to, int cap, int cost) {G[from].push_back(edge(to, cap, cost, G[to].size()));G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));}//flow是自己傳進去的變量,就是最后的最大流,返回的是最小費用int solve(int s, int t, int &flow, int limit = inf) {int cost = 0; memset(h, 0, sizeof(h));while (limit) {priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> > Q;for (int i = 0; i <= n; ++i)d[i] = inf;d[s] = 0; Q.emplace(0, s);while (!Q.empty()) {auto now = Q.top(); Q.pop();int u = now.second;if (d[u] < now.first) continue;for (int i = 0; i < G[u].size(); ++i) {edge &e = G[u][i];if (e.cap > 0 && d[e.to] > d[u] + e.cost + h[u] - h[e.to]) {d[e.to] = d[u] + e.cost + h[u] - h[e.to];pre[e.to] = u;num[e.to] = i;Q.emplace(d[e.to], e.to);}}}if (d[t] == inf) break;for (int i = 0; i <= n; ++i)h[i] += d[i];int a = limit;for (int u = t; u != s; u = pre[u])a = min(a, G[pre[u]][num[u]].cap);limit -= a; flow += a; cost += a * h[t];for (int u = t; u != s; u = pre[u]) {edge &e = G[pre[u]][num[u]];e.cap -= a;G[u][e.rev].cap += a;}}return cost;}
}mcmf;
int main()
{freopen("D:\\in.txt", "r", stdin);int n, m, k, flow = 0;scanf("%d %d %d", &n, &m, &k);mcmf.init(n + 10);for (int i = 1; i <= m; ++i) {int x, y, c, w;scanf("%d %d %d %d", &x, &y, &c, &w);mcmf.add_edge(x, y, c, w);}auto start = clock();printf("%d\n", mcmf.solve(1, n, flow, k));printf("flow: %d\n", flow);double tot = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;printf("MCMF-dijkstra: %f\n", tot);return 0;
}

(代碼來自孫明志大佬的xcpc算法模板)


總結

? 最大流問題:優先選擇DinicISAP(代碼簡單),超大規模數據用HLPP
? 費用流問題
? 含負權邊 → MCMF-SPFA
? 無負權邊 → MCMF-Dijkstra(更高效)。
? 關鍵區別
? Dinic/ISAP/HLPP解決最大流,MCMF類解決費用流。
? SPFA允許負權但慢,Dijkstra需正權但快;HLPP通過預流推進優化最大流。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73508.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73508.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73508.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

遞歸、搜索與回溯第四講:floodfill算法

遞歸、搜索與回溯第四講&#xff1a;floodfill算法 1.Floodfill算法介紹2.圖像渲染3.島嶼數量4.島嶼的最大面積5.被圍繞的區域6.太平洋大西洋水流問題7.掃雷游戲8.衣櫥整理 1.Floodfill算法介紹 2.圖像渲染 3.島嶼數量 4.島嶼的最大面積 5.被圍繞的區域 6.太平洋大西洋水流問題…

【深度學習與實戰】2.3、線性回歸模型與梯度下降法先導案例--最小二乘法(向量形式求解)

為了求解損失函數 對 的導數&#xff0c;并利用最小二乘法向量形式求解 的值? 這是?線性回歸?的平方誤差損失函數&#xff0c;目標是最小化預測值 與真實值 之間的差距。 ?損失函數?&#xff1a; 考慮多個樣本的情況&#xff0c;損失函數為所有樣本的平方誤差之和&a…

氣象可視化衛星云圖的方式:方法與架構詳解

氣象衛星云圖是氣象預報和氣候研究的重要數據來源。通過可視化技術,我們可以將衛星云圖數據轉化為直觀的圖像或動畫,幫助用戶更好地理解氣象變化。本文將詳細介紹衛星云圖可視化的方法、架構和代碼實現。 一、衛星云圖可視化方法 1. 數據獲取與預處理 衛星云圖數據通常來源…

瀏覽器渲染原理與優化詳解

一、瀏覽器渲染基礎原理 瀏覽器渲染流程主要包括以下步驟&#xff08;也稱為"關鍵渲染路徑"&#xff09;&#xff1a; 構建DOM樹&#xff1a;將HTML解析為DOM&#xff08;文檔對象模型&#xff09;樹構建CSSOM樹&#xff1a;將CSS解析為CSSOM&#xff08;CSS對象模…

基于Spring Boot的成績管理系統后臺實現

下面是一個完整的成績管理系統后臺實現&#xff0c;使用Spring Boot框架&#xff0c;包含學生管理、課程管理和成績管理功能。 1. 項目結構 src/main/java/com/example/grademanagement/ ├── config/ # 配置類 ├── controller/ # 控制器 ├── dto/ …

實現極限網關(INFINI Gateway)配置動態加載

還在停機更新 Gateway 配置&#xff0c;OUT 了。 今天和大家分享一個 Gateway 的功能&#xff1a;動態加載配置&#xff08;也稱熱更新或熱加載&#xff09;。 這個功能可以在 Gateway 不停機的情況下更新配置并使之生效。 配置樣例如下&#xff1a; path.data: data path.…

Mean Shift 圖像分割與 Canny 邊緣檢測教程

1. Mean Shift 簡介 Mean Shift 是一種聚類算法&#xff0c;通過尋找圖像中顏色相似的區域來實現分割。它非常適合用于場景分割或物體檢測等任務。本教程將它與 Canny 邊緣檢測結合&#xff0c;突出分割區域的邊界。 2. 圖像分割流程 我們將按照以下步驟完成圖像分割和邊緣檢…

Day15 -實例 端口掃描工具 WAF識別工具的使用

一、端口掃描工具 1、zenmap 我這里user是漢字名&#xff0c;沒有解析成功。等后續換一個英文賬戶試一試。 魔改kali的nmap nmap -p8000-9000 8.140.159.19 2、masscan cmd啟動&#xff0c;拖入exe文件。然后先寫ip&#xff0c;會報錯給提示 尋路犬系統 我們去找一下他的…

如何解決高并發場景下的性能瓶頸?實踐分享

解決高并發性能瓶頸的核心方法包括優化系統架構、合理使用緩存技術、數據庫優化及擴展策略、負載均衡設計。 其中&#xff0c;優化系統架構是根本解決性能問題的關鍵所在。良好的系統架構能夠有效支撐業務高效穩定運行&#xff0c;避免性能瓶頸帶來的損失。企業可通過微服務架構…

自動駕駛背后的數學:ReLU,Sigmoid, Leaky ReLU, PReLU,Swish等激活函數解析

隨著自動駕駛技術的飛速發展&#xff0c;深度學習在其中扮演著至關重要的角色。而激活函數作為神經網絡中的關鍵組件&#xff0c;直接影響著模型的性能和效果。前面幾篇博客 自動駕駛背后的數學&#xff1a;特征提取中的線性變換與非線性激活 , 「自動駕駛背后的數學&#xff1…

性能測試、負載測試、壓力測試的全面解析

在軟件測試領域&#xff0c;性能測試、負載測試和壓力測試是評估系統穩定性和可靠性的關鍵手段。?它們各自關注不同的測試目標和應用場景&#xff0c;理解這些差異對于制定有效的測試策略至關重要。 本文對性能測試、負載測試和壓力測試進行深入分析&#xff0c;探討其定義、…

責任鏈模式-java

1、spring依賴注入模式 @Configuration public class ChainConfig {@Beanpublic ChainSpringFactory chainSpringFactory(List<IHandler<DemoOne,Boolean>> handlerList){return new ChainSpringFactory(handlerList);}} public class DemoOne { }public abstract…

學習本地部署DeepSeek的過程(基于LM Studio)

除了使用Ollama部署DeepSeek&#xff0c;還可以使用LM Studio部署DeepSeek&#xff0c;后者是一款允許用戶在本地計算機上運行大型語言模型&#xff08;LLMs&#xff09;的桌面應用程序&#xff0c;旨在簡化本地模型的使用&#xff0c;無需云端連接或復雜配置即可體驗 AI 功能。…

CSS 尺寸 (Dimension)

CSS 尺寸 (Dimension) 在網頁設計中&#xff0c;CSS&#xff08;層疊樣式表&#xff09;的尺寸屬性是控制元素大小和位置的關鍵。本文將詳細介紹CSS尺寸相關的概念、屬性及其應用。 1. CSS 尺寸概述 CSS尺寸主要包括寬度和高度&#xff0c;這些屬性可以應用于各種HTML元素&a…

【自學筆記】ELK基礎知識點總覽-持續更新

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 ELK基礎知識點總覽1. ELK簡介2. Elasticsearch基礎Elasticsearch配置示例&#xff08;elasticsearch.yml&#xff09; 3. Logstash基礎Logstash配置示例&#xff08…

等差數列公式推導

前言&#xff1a; 通過實踐而發現真理&#xff0c;又通過實踐而證實真理和發展真理。從感性認識而能動地發展到理性認識&#xff0c;又從理性認識而能動地指導革命實踐&#xff0c;改造主觀世界和客觀世界。實踐、認識、再實踐、再認識&#xff0c;這種形式&#xff0c;循環往…

【MySQL】用戶賬戶、角色、口令、PAM

目錄 查看用戶賬戶設置 連接 1.本地連接 2.遠程連接 賬戶 角色 操作用戶賬戶和角色 配置口令和賬戶有效期限 手工使口令過期 配置口令有效期限 PAM身份驗證插件 客戶端連接&#xff1a;使用 PAM 賬戶登錄 在連接到MySQL服務器并執行查詢時&#xff0c;會驗證你的身…

5種生成模型(VAE、GAN、AR、Flow 和 Diffusion)的對比梳理 + 易懂講解 + 代碼實現

目錄 1 變分自編碼器&#xff08;VAE&#xff09;? 1.1 概念 1.2 訓練損失 1.3 VAE 的實現 2 生成對抗網絡&#xff08;GAN&#xff09;? 2.1 概念 2.2 訓練損失 a. 判別器的損失函數 b. 生成器的損失函數 c. 對抗訓練的動態過程 2.3 GAN 的實現 3 自回歸模型&am…

印刷電路板 (PCB) 的影響何時重要?在模擬環境中導航

我和我的同事們經常被問到關于 PCB 效應的相同問題&#xff0c;例如&#xff1a; 仿真何時需要 PCB 效果&#xff1f; 為什么時域仿真需要 PCB 效應&#xff1f; 當 PCB 效應必須包含在仿真中時&#xff0c;頻率是否重要&#xff1f; 設計人員應該在多大程度上關注 VRM 模型中包…

2024跨境電商挑戰:AI反檢測技術在避免封號中的作用

2024跨境電商挑戰&#xff1a;AI反檢測技術在避免封號中的作用 跨境電商的浪潮席卷全球&#xff0c;為商家打開了通往世界各地的大門。然而&#xff0c;隨著平臺監管的加強&#xff0c;合規性問題成為商家不得不面對的挑戰。在電商平臺的嚴格監控下&#xff0c;任何違規行為都…