「网络流浅谈」最大流的应用

更好的阅读体验

二分图匹配

考虑如何将二分图匹配问题,转化为流网络。设置 1 1 1 个汇点和源点,从源点向二分图一侧的每一个点连边,从另一侧向汇点连边,边权均为 1 1 1,二分图中的边也全部加入,权值设为 1 1 1。这样,二分图的最大匹配等于流网络的最大流。

P2756 飞行员配对方案问题

题意:给定 1 1 1 个二分图,求最大匹配。

匈牙利算法是可以求二分图最大匹配的,不过太慢了。不妨,使用上述的方式建立出流网络,并使用 Dinic 求解出该网络的最大流即可。

举个例子:左图为样例的二分图,而右图为建立的流网络。

浅析流网络最大流与二分图最大匹配的相等性:

对于网络流的题目,只需要考虑对于任意的一个最大匹配,都能对应到一个可行流;而对于任意一个可行流都能对应到一个最大匹配。

对于任意的一个最大匹配,都能对应到一个可行流:若选择边 E 1 , E 2 , … , E k E_1,E_2, \dots ,E_k E1,E2,,Ek,则可行流中的这些边均为 1 1 1,且令这些边左端的顶点分别为 V 1 , V 2 , … , V t V_1,V_2,\dots,V_t V1,V2,,Vt,右端的为 V 1 ′ , V 2 ′ , … , V t ′ V'_1,V'_2,\dots, V'_t V1,V2,,Vt,则可行流的 s → V i s\rightarrow V_i sVi 这些边均为 1 1 1 V i ′ → t V'_i\rightarrow t Vit 这些边也均为 1 1 1。由于匹配不存在 2 2 2 条边有公共顶点,所以一定满足容量限制与流量守恒。

对于任意的一个可行流,都能对应到一个最大匹配:可行流中流量为 1 1 1 的没有 s s s t t t 的边即为最大匹配,由于流量守恒,最多有 1 1 1 条边流向一个点,所以满足对于任意 2 2 2 条边,都不存在公共点。

故,只需要用 Dinic 跑一遍最大流即可,输出方案就是找出所有反向边流量为 1 1 1(或正向边流量为 0 0 0)的边即可。

注意:二分图下的 Dinic 算法极为特殊,时间复杂度为 O ( n 2 n ) O(n^2\sqrt n) O(n2n )

#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

const int N = 1e2 + 10, M = 1e5 + 10;

int n, m, s, t;
int h[N], e[M], ne[M], f[M], idx;
int d[N], cur[N];

void add(int a, int b, int c) {
	e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
	e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}
bool bfs() {
	memset(d, -1, sizeof d);
	queue<int> q;
	q.emplace(s), cur[s] = h[s], d[s] = 0;
	while (q.size()) {
		auto u = q.front();
		q.pop();

		for (int i = h[u]; ~i; i = ne[i]) {
			int j = e[i];
			if (d[j] == -1 && f[i]) {
				d[j] = d[u] + 1, cur[j] = h[j];
				if (j == t) return 1;
				q.emplace(j);
			}
		}
	}
	return 0;
}
int find(int u, int lim) {
	if (u == t) return lim;

	int flow = 0;
	for (int i = cur[u]; ~i && flow < lim; i = ne[i]) {
		int j = e[i];
		if (d[j] == d[u] + 1 && f[i]) {
			int tmp = find(j, min(lim - flow, f[i]));
			if (!tmp) d[j] = -1;
			f[i] -= tmp, f[i ^ 1] += tmp, flow += tmp;
		}
	}
	return flow;
}
int dinic() {
	int res = 0, flow;
	while (bfs()) while (flow = find(s, 1e18)) res += flow;
	return res;
}

signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);

	memset(h, -1, sizeof h);

	cin >> m >> n;

	s = 0, t = n + 1;
	int u, v;
	while (cin >> u >> v && u != -1) {
		add(u, v, 1);
	}
	for (int i = 1; i <= m; i ++)
		add(s, i, 1);
	for (int i = m + 1; i <= n; i ++)
		add(i, t, 1);

	cout << dinic() << endl;
	for (int i = 0; i < idx; i += 2)
		if (e[i] != t && e[i ^ 1] != s && !f[i])
			cout << e[i ^ 1] << " " << e[i] << endl;

	return 0;
}
习题

P3254 圆桌问题,与原建图方式有略微差异。

参考代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

const int N = 5e2 + 10, M = 1e5 + 10;

int m, n, s, t;
int a[N], b[N];
int h[N], e[M], f[M], ne[M], idx;
int d[N], cur[N];

void add(int a, int b, int c) {
	e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
	e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}
bool bfs() {
	memset(d, -1, sizeof d);
	queue<int> q;
	q.emplace(s), d[s] = 0, cur[s] = h[s];
	while (q.size()) {
		int u = q.front();
		q.pop();

		for (int i = h[u]; ~i; i = ne[i]) {
			int j = e[i];
			if (d[j] == -1 && f[i]) {
				d[j] = d[u] + 1;
				cur[j] = h[j];
				if (j == t) return 1;
				q.emplace(j);
			}
		}
	}
	return 0;
}
int find(int u, int lim) {
	if (u == t) return lim;

	int flow = 0;
	for (int i = cur[u]; ~i && flow < lim; i = ne[i]) {
		cur[u] = i;
		int j = e[i];
		if (d[j] == d[u] + 1 && f[i]) {
			int tmp = find(j, min(lim - flow, f[i]));
			if (!tmp) d[j] = -1;
			f[i] -= tmp, f[i ^ 1] += tmp, flow += tmp;
		}
	}

	return flow;
}
int dinic() {
	int res = 0, flow;
	while (bfs()) while (flow = find(s, 1e18)) res += flow;
	return res;
}

signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);

	memset(h, -1, sizeof h);
	cin >> m >> n;

	s = 0, t = n + m + 1;
	int tot = 0;
	for (int i = 1; i <= m; i ++)
		cin >> a[i], add(s, i, a[i]), tot += a[i];
	for (int i = 1; i <= n; i ++)
		cin >> b[i], add(i + m, t, b[i]);
	for (int i = 1; i <= m; i ++)
		for (int j = m + 1; j <= n + m; j ++)
			add(i, j, 1);

	if (dinic() == tot) {
		cout << 1 << endl;
		std::vector<vector<int>> way(m + 1);
		for (int i = 0; i < idx; i += 2)
			if (e[i] != t && e[i ^ 1] != s && !f[i])
				way[e[i ^ 1]].emplace_back(e[i] - m);
		for (int i = 1; i <= m; i ++) {
			for (auto v : way[i])
				cout << v << " ";
			cout << endl;
		}
	} else {
		cout << 0 << endl;
	}

	return 0;
}

多源汇最大流

本质上只不过是源点不是 1 1 1 个,汇点也不是 1 1 1 个了,那么其实只需要再设一个超级源点连向所有源点,边权为 + ∞ +\infty +,表示向这些源点可以流任意多流量,也就是说从这些源点可以流出任意多流量;同样的,从每一个汇点向超级汇点连一条 + ∞ +\infty + 的边,表示这些汇点可以流向超级汇点任意多流量,也就是说这些汇点都可以接纳任意多的流量。

这样的新流网络的最大流就是源网络的最大流,所以只需要对于新网络跑一遍 Dinic 即可。

习题

AcWing 2234. 多源汇最大流,模版题

参考代码
#include <iostream>
#include <cstring>
#include <queue>
#define int long long

using namespace std;

typedef pair<int, int> PII;

const int SIZE = 5e5 + 10;

int N, M, Sc, Tc, S, T;
int h[SIZE], e[SIZE], ne[SIZE], f[SIZE], idx;
int D[SIZE], Current[SIZE];

void add(int a, int b, int c) {
    e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
    e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}

bool BFS() {
    memset(D, -1, sizeof D);
    queue<int> Q;

    Q.push(S), D[S] = 0, Current[S] = h[S];
    while (Q.size()) {
        int u = Q.front();
        Q.pop();

        for (int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if (D[j] == -1 && f[i]) {
                D[j] = D[u] + 1;
                Current[j] = h[j];
                if (j == T) return true;
                Q.push(j);
            }
        }
    }

    return false;
}

int Find(int u, int limit) {
    if (u == T) return limit;

    int flow = 0;
    for (int i = Current[u]; ~i && flow < limit; i = ne[i]) {
        Current[u] = i;
        int j = e[i];
        if (D[j] == D[u] + 1 && f[i]) {
            int T = Find(j, min(f[i], limit - flow));
            if (!T) D[j] = -1;
            f[i] -= T, f[i ^ 1] += T, flow += T;
        }
    }

    return flow;
}

int Dinic() {
    int Result = 0, flow;
    while (BFS()) while (flow = Find(S, 1e18)) Result += flow;
    return Result;
}

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    memset(h, -1, sizeof h);

    cin >> N >> M >> Sc >> Tc;

    S = 0, T = N + 1;
    while (Sc --) {
        int u;
        cin >> u;
        add(S, u, 1e18);
    }

    while (Tc --) {
        int u;
        cin >> u;
        add(u, T, 1e18);
    }

    while (M --) {
        int a, b, c;

        cin >> a >> b >> c;

        add(a, b, c);
    }

    cout << Dinic() << endl;

    return 0;
}

关键边

POJ3204 Ikki’s Story I - Road Reconstruction

题意:给定 1 1 1 个流网络,求有多少条边,满足增加该边边权后能使最大流增加。

考虑一条边满足什么条件使得增加容量后会使得最大流增加,回顾求最大流的过程:每一次在残留网络中找增广路径,并加到最大流中。

那么,如果容量增加后,最大流增加,那么必然是增加流量后产生 1 1 1 条增广路径。所以,对于每一条边 ( u , v ) (u,v) (u,v),只需要判断是否存在 1 1 1 条增广路径 s → u s\rightarrow u su 以及 1 1 1 增广路径 v → t v\rightarrow t vt。判断的方法就是在最大流的残留网络中 DFS,记录每次走 > 0 >0 >0 的边能到达那些点即可。

#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

const int N = 5e2 + 10, M = 2e4 + 10;

int n, m, s, t;
int h[N], e[M], ne[M], f[M], idx;
int d[N], cur[N], vis[2][N];

void add(int a, int b, int c) {
	e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
	e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}
bool bfs() {
	memset(d, -1, sizeof d);
	queue<int> q;
	q.emplace(s), d[s] = 0, cur[s] = h[s];

	while (q.size()) {
		int u = q.front();
		q.pop();

		for (int i = h[u]; ~i; i = ne[i]) {
			int j = e[i];
			if (d[j] == -1 && f[i]) {
				d[j] = d[u] + 1, cur[j] = h[j];
				if (j == t) return 1;
				q.emplace(j);
			}
		}
	}
	return 0;
}
int find(int u, int lim) {
	if (u == t) return lim;

	int flow = 0;
	for (int i = cur[u]; ~i && flow < lim; i = ne[i]) {
		cur[u] = i;
		int j = e[i];
		if (d[j] == d[u] + 1 && f[i]) {
			int tmp = find(j, min(lim - flow, f[i]));
			if (!tmp) d[j] = -1;
			f[i] -= tmp, f[i ^ 1] += tmp, flow += tmp;
		}
	}

	return flow;
}
int dinic() {
	int res = 0, flow;
	while (bfs()) while (flow = find(s, 1e18)) res += flow;
	return res;
}
void dfs(int u, int k) {
	vis[k][u] = 1;
	for (int i = h[u]; ~i; i = ne[i]) {
		int j = e[i];
		if (!vis[k][j] && f[i ^ k])
			dfs(j, k);
	}
}

signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);

	memset(h, -1, sizeof h);
	cin >> n >> m;

	s = 0, t = n - 1;
	while (m --) {
		int u, v, w;
		cin >> u >> v >> w;
		add(u, v, w);
	}
	dinic();
	dfs(s, 0), dfs(t, 1);

	int res = 0;
	for (int i = 0; i < idx; i += 2)
		if (vis[0][e[i ^ 1]] && vis[1][e[i]])
			res ++;

	cout << res << endl;

	return 0;
}

拆点

POJ3281 Dining

题意:有 n n n 头奶牛, F F F 个食物和 D D D 个饮料,每头奶牛可以吃某些食物和饮料,但都只能吃食物和饮料各一个。求最多能满足多少头奶牛。(三分图匹配

考虑继续使用类似二分图的建网络流的方式,举个例子:

不过,这样真的能够求出最终的答案吗?答案是否定的。

考虑局部的这样一个位置,最大流得到话会流出 2 2 2 的,也就是这个奶牛会贡献 2 2 2,而应该是 1 1 1

所以,就要拆点了!

通过,流量守恒,就可以使得通过每一个点的流量最多为 $1$,也就满足了题意。
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

const int N = 4e2 + 10, M = 1e5 + 10;

int n, m, k, s, t;
int h[N], e[M], ne[M], f[M], idx;
int d[N], cur[N];

void add(int a, int b, int c) {
    e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
    e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}
bool bfs() {
    memset(d, -1, sizeof d);
    queue<int> q;
    q.emplace(s), d[s] = 0, cur[s] = h[s];
    while (q.size()) {
        int u = q.front();
        q.pop();

        for (int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if (d[j] == -1 && f[i]) {
                d[j] = d[u] + 1, cur[j] = h[j];
                if (j == t) return 1;
                q.emplace(j);
            }
        }
    }
    return 0;
}
int find(int u, int lim) {
    if (u == t) return lim;

    int flow = 0;
    for (int i = cur[u]; ~i && flow < lim; i = ne[i]) {
        cur[u] = i;
        int j = e[i];
        if (d[j] == d[u] + 1 && f[i]) {
            int tmp = find(j, min(lim - flow, f[i]));
            if (!tmp) d[j] = -1;
            f[i] -= tmp, f[i ^ 1] += tmp, flow += tmp;
        }
    }
    return flow;
}
int dinic() {
    int res = 0, flow;
    while (bfs()) while (flow = find(s, 1e18)) res += flow;
    return res;
}

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    memset(h, -1, sizeof h);
    cin >> n >> m >> k;

    s = 0, t = n * 2 + m + k + 1;
    for (int i = 1; i <= n; i ++) {
        int cf, cd, x;
        cin >> cf >> cd;
        for (int j = 1; j <= cf; j ++)
            cin >> x, add(x, i + m, 1);
        for (int j = 1; j <= cd; j ++)
            cin >> x, add(i + m + n, x + m + n + n, 1);
    }
    for (int i = 1; i <= m; i ++)
        add(s, i, 1);
    for (int i = m + n * 2 + 1; i < t; i ++)
        add(i, t, 1);
    for (int i = m + 1; i <= m + n; i ++)
        add(i, i + n, 1);

    cout << dinic() << endl;

    return 0;
}
习题

P2766 最长不下降子序列问题

参考代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

const int N = 1e3 + 10, M = 4e5 + 10;

int n, s, t;
int a[N], dp[N];
int h[N], e[M], ne[M], f[M], idx;
int d[N], cur[N];
void add(int a, int b, int c) {
    e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
    e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}
bool bfs() {
    memset(d, -1, sizeof d);
    queue<int> q;
    q.emplace(s), d[s] = 0, cur[s] = h[s];
    while (q.size()) {
        int u = q.front();
        q.pop();

        for (int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if (d[j] == -1 && f[i]) {
                d[j] = d[u] + 1, cur[j] = h[j];
                if (j == t) return 1;
                q.emplace(j);
            }
        }
    }
    return 0;
}
int find(int u, int lim) {
    if (u == t) return lim;

    int flow = 0;
    for (int i = cur[u]; ~i && flow < lim; i = ne[i]) {
        cur[u] = i;
        int j = e[i];
        if (d[j] == d[u] + 1 && f[i]) {
            int tmp = find(j, min(lim - flow, f[i]));
            if (!tmp) d[j] = -1;
            f[i] -= tmp, f[i ^ 1] += tmp, flow += tmp;
        }
    }
    return flow;
}
int dinic() {
    int res = 0, flow;
    while (bfs()) while (flow = find(s, 1e18)) res += flow;
    return res;
}

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    memset(h, -1, sizeof h);
    cin >> n;
    for (int i = 1; i <= n; i ++)
        cin >> a[i];
    s = 0, t = 2 * n + 1;

    for (int i = 1; i <= n; i ++) {
        dp[i] = 1, add(i, i + n, 1);
        std::vector<int> opt;
        for (int j = 1; j < i; j ++)
            if (a[j] <= a[i] && dp[j] + 1 > dp[i])
                opt.clear(), opt.emplace_back(j), dp[i] = dp[j] + 1;
            else if (a[j] <= a[i] && dp[j] + 1 == dp[i])
                opt.emplace_back(j);
        for (auto v : opt)
            add(n + v, i, 1);
    }
    int res = 0;
    for (int i = 1; i <= n; i ++)
        res = max(res, dp[i]);
    cout << res << endl;

    for (int i = 1; i <= n; i ++) {
        if (dp[i] == res)
            add(i + n, t, 1);
        if (dp[i] == 1)
            add(s, i, 1);
    }
    res = dinic();
    cout << res << endl;

    for (int i = 0; i < idx; i += 2) {
        if (e[i ^ 1] == 1 && e[i] == 1 + n || e[i ^ 1] == 1 + n && e[i] == t || e[i ^ 1] == s && e[i] == 1)
            f[i] = 1e18;
        else if (e[i ^ 1] == n && e[i] == n + n || e[i ^ 1] == n + n && e[i] == t || e[i ^ 1] == s && e[i] == n)
            f[i] = 1e18;
    }
    res += dinic();
    cout << min(res, n) << endl;

    return 0;
}

POJ3498 March of the Penguins

参考代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

const int N = 2e2 + 10, M = 2e4 + 10;

int n, s, t;
double ld;
int h[N], e[M], ne[M], f[M], idx;
int d[N], cur[N];
struct Node {
    int x, y;
    int tot, cnt;
    double operator- (const Node &tmp)const {
        int a = x - tmp.x, b = y - tmp.y;
        return sqrt(a * a * 1.0 + b * b * 1.0);
    }
}pg[N];
void add(int a, int b, int c) {
    e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
    e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}
bool bfs() {
    memset(d, -1, sizeof d);
    queue<int> q;
    q.emplace(s), d[s] = 0, cur[s] = h[s];
    while (q.size()) {
        int u = q.front();
        q.pop();

        for (int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if (d[j] == -1 && f[i]) {
                d[j] = d[u] + 1, cur[j] = h[j];
                if (j == t) return 1;
                q.emplace(j);
            }
        }
    }
    return 0;
}
int find(int u, int lim) {
    if (u == t) return lim;

    int flow = 0;
    for (int i = cur[u]; ~i && flow < lim; i = ne[i]) {
        cur[u] = i;
        int j = e[i];
        if (d[j] == d[u] + 1 && f[i]) {
            int tmp = find(j, min(lim - flow, f[i]));
            if (!tmp) d[j] = -1;
            f[i] -= tmp, f[i ^ 1] += tmp, flow += tmp;
        }
    }
    return flow;
}
int dinic() {
    int res = 0, flow;
    while (bfs()) while (flow = find(s, 1e18)) res += flow;
    return res;
}

void solve() {
    cin >> n >> ld;

    int sum = 0;
    for (int i = 1; i <= n; i ++)
        cin >> pg[i].x >> pg[i].y >> pg[i].tot >> pg[i].cnt, sum += pg[i].tot;

    s = 0;
    std::vector<int> res;
    for (t = 1; t <= n; t ++) {
        memset(h, -1, sizeof h);
        idx = 0;
        for (int i = 1; i <= n; i ++) {
            add(s, i, pg[i].tot), add(i, i + n, pg[i].cnt);
            for (int j = 1; j <= n; j ++)
                if (i != j && pg[j] - pg[i] <= ld)
                    add(i + n, j, 1e18);
        }
        if (dinic() == sum)
            res.emplace_back(t);
    }

    if (res.empty())
        cout << -1 << endl;
    else {
        for (auto v : res)
            cout << v - 1 << " ";
        cout << endl;
    }
}

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int dt;

    cin >> dt;

    while (dt --)
        solve();

    return 0;
}
  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大数据在生活中的应用全文共5页,当前为第1页。大数据在生活中的应用全文共5页,当前为第1页。大数据在生活中的应用 大数据在生活中的应用全文共5页,当前为第1页。 大数据在生活中的应用全文共5页,当前为第1页。 当今世界,正处于一个信息化的重大发展时代。只要你稍有关注热点时事,总能看到"大数据"、"云计算"两个高频词。稍加了解,你会发现,大数据在许多行业中起着至关重要的作用,甚至在我们的生活中也有着非常多的应用。那么什么是大数据呢?大数据的概念到底又是什么?大数据的具体应用又有哪些? 大约从2009年开始"大数据"成为互联网信息技术行业的行词汇,甚至连普通的网页上都可见到大数据云计算等高大上的字样,但是大数据到底是什么呢?作为一个普通人,并不是展业IT人才,怎样了解大数据?大数据和云计算是不是一样的,它们两个有区别吗?这样那样的疑问很多,可是又听说大数据在生活中的应用很多,随处可见,就连的吃喝住行都有它的影子。那么大数据在我们日常生活中又有哪些应用呢?大数据给我们的生活带来了哪些影响?下面我们就来浅谈一下"大数据"在我们日常生活中的应用和影响。 社交网络,为大数据提供了信息汇集、分析的第一手资料。大数据的价值主要就是,从庞杂的数据背后挖掘、分析用户的行为习惯和喜好,找出更符合用户口味或需求的产品和服务,并结合用户需求有针对性地调整和优化自身。简单的说,如果我拥有了客户大量的信息,我就能从收集到的信息中知道客户的消费习惯和消费方向,通过这些数据分析出自身产品有哪些缺失,可以及时改变策略,而不是盲目的生产一些客户并不喜欢的产品增加自身成本。大数据的核心价值就是,提升决策准确性,降低风险,提升运营精准度,降低成本。最简单的例子,每天我们打开一些带有广告性的网页,网页的两侧总会弹出一些商品推荐,而这些推荐正是由于大数据通过你平时在淘宝、天猫等交易网站上搜索过的商品信息,再提供给商家,广告商从而给你推送与你相关的商品。 大数据最本质的应用就在于预测,即从海量数据中分析出一定的特征,进而预测未来可能会发生什么。在数据足够"大"的情况下,你生活中几乎所有的需求都可能会被预测出来。例如,从数据分析出你可能会约会,于是会向你推荐衣服;从数据推测出你会出去旅游,于是向你推荐相关装备及旅行方式等。 进而言之,这是由于浏览器缓存cookie,你通过浏览器浏览任意网站内容时,都会在你的计算机缓存文件夹内生成一个缓存文件,其记录了你什么时间,通过什么渠道,访问了什么内容,做了些什么,等等一系列的信息。然后当你访问一些特定的网站时,其有广告位,而这些广告位(后台)就会去读取你的缓存文件,根据你的缓存文件内容,广告位就会为你推送相关的内容。实例:你通过百度搜索 "贷款",之后,这个信息就会被记录, 当你访问一些网站其带有 百度广告位,那这些广告位 就会显示和 "贷款"相关的内容。 大数据从何而来?美国互联网数据中心指出,互联网上的数据每年将增长50%,每两年便将翻一番,目前世界上90%以上的数据是最近几年才产生的。此外,全世界的工业设备、汽车、电表上有着无数的数码传感器随时测量和传递大数据在生活中的应用全文共5页,当前为第2页。大数据在生活中的应用全文共5页,当前为第2页。着有关位置、运动、震动、温度、湿度乃至空气中化学物质的变化,也产生了海量的数据信息。物联网、云计算、移动互联网、车联网、手机、平板电脑、PC以及各种各样的传感器,无一不是数据来源或者承载的方式。 大数据在生活中的应用全文共5页,当前为第2页。 大数据在生活中的应用全文共5页,当前为第2页。 大数据的概念及其解释。大数据,指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和程优化能力的海量、高增长率和多样化的信息资产。首先大数据要大,大体现在数据的"海量"上,这个"海量"不仅仅指的是数据的多,还有数据的多种多样,复杂程度等。并不是像我们平常所说的大量数据这么简单。大数据的特点可归纳为4个"V"——Volume(大量)、Velocity(高速)、Variety(多样)、Veracity(精确)。第一,数据体量。从TB级别,跃升到PB级别第二数据类型繁多数据来源于各种各样的渠道。第三价值密度低,商业价值高。以视频为例,连续不间断监控过程中,可能有用的数据仅仅有一两秒。第四,处理速度快。一般要在秒级时间范围内给出分析结果,时间太长就失去价值了。这个速度要求是大数据处理技术和传统的数据挖掘技术最大的区别。 数据是信息化时代的"石油"。大数据、云计算、物联网等新一代信息科技的普及和广泛运用,已经远 超出科技革命的范畴,成为深刻影响人们生产生活方式、社会经济发展方式、国际竞争方式等的重要变量,带动了经济、政治、军事、文化等诸多领域的巨大
浅谈大数据技术 作者:崔倩 来源:《科学与财富》2020年第30期 摘 要:大数据已经成为一种基础性新资源,已初显潜在的价值和巨大的变革之力。本文介绍了大数据的定义、特征,分析了大数据的应用和发展趋势。 关键词:大数据;大数据时代;应用 引言: 随着新一代信息技术的发展和应用,尤其是互联网、物联网、移动互联网、社交网络等技术的发展,人类产生的数据成倍增长,数据种类繁多,数据在宽带网络中高速动,数据的待开发价值越来越大,我们正在进入一个大数据时代,大数据应用也成为当前最为热门的信息技术应用领域。 一、什么是大数据 (一)大数据的定义 大数据(Big Data)指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和程优化能力,以及海量、高增长率和多样化的信息资产。 (二)大数据的特征 大数据的"大"是一个动态的概念。以前10GB的数据是个天文数字,而今在地球、基因、空间科学等领域,TB级的数据已经很普遍。关于大数据的特征,虽然有多种解读,但业界一般认为,大数据具有4V特征:Volume(数据量大)、Variety(数据类型多样)、Velocity(处理速度快)和最重要的Value(价值密度低)。 1.数据量大(Volume) 浅谈大数据技术全文共4页,当前为第1页。 大数据的体量大,数据集合的规模不断扩大,已经从GB到TB再到PB级,甚至已经开始以EB和ZB来计数。例如,一个中型城市的视频监控头每天就能产生几十TB的数据。有资料证实,到目前为止,人类生产的所有印刷材料的数据量仅为200PB。国际知名咨询机构IDC(International Data Corporation)的研究报告预测,未来十年全球大数据将增加50倍,管理数据仓库的服务器的数据将增加10倍。 浅谈大数据技术全文共4页,当前为第1页。 2.数据类型多样(Variety) 大数据类型繁多,包括结构化、半结构化和非结构化数据。以往产生或处理的数据类型较为单一,大部分是结构化数据。而现代互联网应用呈现出非结构化数据大幅增长的特点,非结构化数据越来越成为数据的主要部分。据咨询机构IDC的调查调查报告显示,企业中80%的数据都是非结构化数据,这些数据每年都按指数增长60%。 3.处理速度快(Velocity) 大数据往往以数据的形式动态、快速地产生,具有很强的时效性,用户只有把握好对数据的掌控才能有效利用这些数据。另外,数据自身的状态与价值也往往随时空变化而发生演变,数据的涌现特征明显。业界对大数据的数据处理速度有一个称谓——"1秒定律",即要在秒级时间范围内给出分析结果,超出这个时间,数据就失去价值了。这个速度要求是大数据处理技术与传统的数据挖掘技术最大的区别,这也充分说明了大数据需要具备快速处理的能力。 4.价值密度低(Value) 数据总体的价值巨大,但是价值密度很低。价值密度的高低与数据总量的大小成反比,数据规模越大,真正有价值的数据相对越少。以常规的监控视频为例,连续24h的视频监控中,有用的数据可能仅有数秒。如何通过强大的机器算法更迅速地完成数据的价值"提纯"成为目前大数据背景下亟待解决的难题。 也有机构在4V之外定义第5个V:真实性(Veracity)指的是当数据的来源越来越多元时,这些数据本身的可靠程度如何、能否反映真实情况、质量是否合格,都需要关注。若数据本身就有问题,那分析得到的结果也不会正确。 二、大数据的应用 1.洛杉矶警察局和加利福尼亚大学合作利用大数据预测犯罪的发生。 2.Google感趋势(Google Flu Trends)利用搜索关键词预测禽感的散布。 3.统计学家内特?西爾弗(Nate Silver)利用大数据预测2012美国选举结果。 4.麻省理工学院利用手机定位数据和交通数据建立城市规划。 浅谈大数据技术全文共4页,当前为第2页。 5.梅西百货的实时定价机制,根据需求和库存的情况,该公司基于SAS的系统对多达7300万种货品进行实时调价。 浅谈大数据技术全文共4页,当前为第2页。 6.医疗行业早就遇到了海量数据和非结构化数据的挑战,而近年来很多国家都在积极推进医疗信息化发展,这使得很多医疗机构有资金来做大数据分析。 三、大数据的发展趋势 (一)数据的资源化 资源化是指大数据成为企业和社会关注的重要战略资源,并已成为大家争相抢夺的新焦点。因而,企业必须要提前制定大数据营销战略计划,抢占市场先机。 (二)与云计算的深度结合 大数据离不开云处理,云处理为大数据提供了弹性可拓展的基础设备,是产生大数据的平台之一。自2013年开始,大数据技术已开始和云计算技术紧密结合,预计未来两者关系将更为密切。除此之外,物联网、移动互联网等新兴计算形态,也将一齐助力大数据革命,让大

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值