【差分约束系统】总结

定义

差分约束系统(system of dierence constraints),是求解多个不等式的合法解的算法,因以两变量之差与一常量关系的形式出现,故称作差分约束。

数学形式表示如下:


该算法旨在对于以上 n 个未知数,m 个不等式的不等式组求解。

算法

不妨将式子变换形式,即 x i x_i xi ≤ \leq x j x_j xj + + + y k y_k yk,可以发现,该式子和最短路算法中的松弛操作有异曲同工之妙,考虑将问题转化为最短路的求解。

作为今人的我们,常常说 “不难发现”,“显然” 来评价算法的核心思想,但其实,每一个算法都是学者们经过千万次演算的沉淀才诞生的结晶,我们是携着前人的基础继续探索的,所以体会不到发明算法的困难程度。也正如该算法一样,从不等式到图论的转化过程其实非常不易,难以想到。

对于最短路算法,我们曾学过 dijkstra 和 spfa 两种,虽然 dijkstra 的时间复杂度更加优异,但无法对带负权的图进行处理。

学习最短路时,我们曾得出几个结论:

  1. 在最短路上,一定有 d i s v dis_v disv ≤ \leq d i s u dis_u disu + + + w w w
  2. 最短路中一定不包含环

以下给出简易证明:

  1. d i s v dis_v disv > > > d i s u dis_u disu + w w w,那么可将 s → \rightarrow v 的路径更新为 s → \rightarrow u → \rightarrow v,与最短路定义矛盾。
  2. 若存在负环,则可遍历该环无穷次,不存在最短路。若存在正环,则 s → \rightarrow v → \rightarrow a → \rightarrow b → \rightarrow v 一定比 s → \rightarrow v 更劣,与最短路定义矛盾。

有了以上两个结论,便可考虑将不等式转化为一条边 x j x_j xj → \rightarrow x i x_i xi,权值为 w w w,根据结论 1,对该图求解最短路,则一定满足 x i x_i xi ≤ \leq x j x_j xj + + + w w w

我们将 x i x_i xi 视作了 d i s i dis_i disi 进行求解,那么对于一组可行解, d i s i dis_i disi = = = x i x_i xi

考虑不存在可行解的情况,根据结论 2 可知,若求解出的路径中存在负环,则不存在最短路,即意味着无可行解。

倘若题目中涉及求最大解或最小解,对于最短路来说,对于任意 i 来说 d i s i dis_i disi 都无法再次增大,否则不满足路径权值和最小,所以最短路求解的是最大值,反之最长路求解的是最小值。

实现

上述内容中,提出要建立一条 x j x_j xj → \rightarrow x i x_i xi 权值为 w w w 的有向边,因为存在 w w w ≤ \leq 0 0 0 的情况,所以差分约束系统只能通过 spfa 进行实现。

对于图不联通的情况,不妨建立一个汇点连接每一个点,以该点为起点进行最短路求解,但是要注意此时 spfa 的判环条件会随之改变,每一条边可能会被用作松弛 n 次,而非 n - 1 次。
代码流程如下:

  1. 输入存边
  2. 建立汇点连边
  3. 最短路求解
  4. 判无解 / / / 输出

这里放置一道模板题【模板】差分约束算法

代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 4e5 + 5;
int n , m , vis[MAXN] , cnt , s , t , head[MAXN];
int dis[MAXN];
struct edge{
  int to , nxt , w;
}e[MAXN];
void add(int u , int v , int w) { // 链式前向星存边
  e[++ cnt].to = v;
  e[cnt].nxt = head[u];
  e[cnt].w = w;
  head[u] = cnt;
}
queue<int> q;
void Spfa() { // 最短路求解
  memset(dis , 0x3f , sizeof(dis));
  dis[0] = 0;
  q.push(0);
  while(!q.empty()) {
  	int u = q.front();
  	q.pop();
  	for (int i = head[u] ; i ; i = e[i].nxt) {
  		int v = e[i].to;
  		if (dis[v] > dis[u] + e[i].w) {
  			dis[v] = dis[u] + e[i].w;
  			vis[v] ++;
  			if (vis[v] == n + 1)  // spfa 判断是否存在负环
  				printf("No");
  				exit(0);
  			}
  			q.push(v);
  		}
  	}
  }
}
int main() {
  scanf("%d %d", &n , &m);
  for (int i = 1 , u , v , w ; i <= m ; i ++) {
  	scanf("%d %d %d", &u , &v , &w);
  	add(v , u , w);
  }
  for (int i = 1 ; i <= n ; i ++) add(0 , i , 0); // 建立汇点
  Spfa();
  for (int i = 1 ; i <= n ; i ++) printf("%d ", dis[i]); // 输出可行解
  return 0;
} 

扩展

上述内容中,我们只考虑了 x i x_i xi − - x j x_j xj ≤ \leq w k w_k wk 的形式,但某些题目中还可能存在如下形式:

  1. x i x_i xi − - x j x_j xj < < < w k w_k wk
  2. x i x_i xi − - x j x_j xj ≥ \geq w k w_k wk
  3. x i x_i xi − - x j x_j xj > > > w k w_k wk
  4. x i x_i xi − - x j x_j xj = = = 0 0 0

处理:

  1. x i x_i xi x j x_j xj 为整数的情况下,可转化为 x i x_i xi − - x j x_j xj ≤ \leq w k w_k wk − - 1 1 1
  2. 将两边同时乘以 -1,可转化为 x j x_j xj − - x i x_i xi ≤ \leq − w k -w_k wk
  3. 同理在 x i x_i xi x j x_j xj 为整数的情况下,可转化为 x j x_j xj − - x i x_i xi ≤ \leq − 1 -1 1 − - w k w_k wk
  4. 将等式拆成两个不等式, x i x_i xi − - x j x_j xj ≥ \geq 0 0 0 x i x_i xi − - x j x_j xj ≤ \leq 0 0 0,再进行处理即可

典型例题 [SCOI2011] 糖果

该题是差分约束系统的大杂烩,涵盖五种不等式。需要注意的是该题有实际意义,每一个小朋友分到的糖果数量不能为零,所以建立汇点连边时边权不再为 0,而是 1。

该题是四川省选原题,所以数据对 spfa 有着严格的要求,需要加入 SLF 优化才能勉强卡过,详情请见此处SPFA的优化

代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 4e5 + 5;
int n , m , vis[MAXN] , cnt , s , t , head[MAXN];
ll dis[MAXN] , ans;
char B[1 << 15], *S = B, *T = B, obuf[1 << 15], *p3 = obuf;
#define getchar() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
template <typename item>
void read(item &x) {
  char c(getchar());
  x = 0;
  int f(1);
  while (c > '9' || c < '0') {
      if (c == '-')f = -1;
      c = getchar();
  }
  while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  x *= f;
}
struct edge{
  int to , nxt , w;
}e[MAXN];
void add(int u , int v , int w) {
  e[++ cnt].to = v;
  e[cnt].nxt = head[u];
  e[cnt].w = w;
  head[u] = cnt;
}
deque<int> q;//将普通队列进阶为双端队列
void Spfa() {
  dis[0] = 0;
  q.push_back(0);
  while(!q.empty()) {
  	int u = q.front();
  	q.pop_front();
  	for (int i = head[u] ; i ; i = e[i].nxt) {
  		int v = e[i].to;
  		if (dis[v] < dis[u] + e[i].w) { // 最长路来求最小值
  			dis[v] = dis[u] + e[i].w;
  			vis[v] ++;
  			if (vis[v] == n) {
  				printf("-1");
  				exit(0);
  			}
         // SLF优化
  			if (q.size() && dis[q.front()] <= dis[v]) q.push_front(v);
              else q.push_back(v);
  		}
  	}
  }
}
int main() {
  read(n);
  read(m);
  for (int i = 1 , op , u , v ; i <= m ; i ++) {
  	read(op) , read(u) , read(v);
    // 因为该题存在实际意义,改变存边方式,思想相同
  	if (op == 1) {
  		add(u , v , 0);
  		add(v , u , 0);
  	} else if (op == 2) {
  		if (u == v) {
  			return printf("-1") , 0;
  		}
  		add(u , v , 1);
  	} else if (op == 3) {
  		add(v , u , 0);
  	} else if (op == 4) {
  		if (u == v) {
  			return printf("-1") , 0;
  		}
  		add(v , u , 1);
  	} else {
  		add(u , v , 0);
  	}
  }
  for (int i = 1 ; i <= n ; i ++) add(0 , i , 1); // 注意边权为 1
  Spfa();
  for (int i = 1 ; i <= n ; i ++) ans += dis[i];
  printf("%lld", ans);
  return 0;
} 

习题

组一组

简化题意如下:
构造一个含有 n 个元素的序列 a,给定 m1 个区间 [ l i , r i ] [l_i , r_i] [li,ri] 使得该区间按位或和为 w w w,给定 m2 个区间 [ l i , r i ] [l_i , r_i] [li,ri] 使得该区间为按位与和为 w w w

初次分析这道题,由于该题涉及到了位运算,较容易想到将序列 a 转换为 2 进制的形式进行思考,那么对于题目条件限制,可得如下结论:
不妨令 w i w_i wi w w w 二进制表示形式的第 i 位,并对 w i w_i wi 进行分讨。

  • w i = 1 w_i=1 wi=1,对于按位与操作来说,则要求 [ l i , r i ] [l_i , r_i] [li,ri] 之中任意数二进制的第 i 位都为 1,对于按位或操作来说,则要求 [ l i , r i ] [l_i , r_i] [li,ri] 之中至少一个数的二进制第 i 位为 1。
  • w i = 0 w_i=0 wi=0,对于按位与操作来说,则要求 [ l i , r i ] [l_i , r_i] [li,ri] 之中至少一个数的二进制第 i 位为 0,对于按位或操作来说,则要求 [ l i , r i ] [l_i , r_i] [li,ri] 之中任意数的二进制第 i 位都为 0。

由于该题是区间处理,可考虑加入前缀和解决问题。

对于二进制的第 i 位,令 p r e j pre_j prej 为前 j 个数二进制第 i 位的和,则可通过限制条件得出以下不等式:

  • w i = 1 w_i=1 wi=1,对于按位与操作来说,则 p r e r − p r e l − 1 = r − l + 1 pre_r - pre_{l-1} = r-l+1 prerprel1=rl+1,对于按位或操作来说,则 p r e r − p r e l − 1 ≥ 1 pre_r - pre_{l-1} \geq 1 prerprel11
  • w i = 0 w_i=0 wi=0,对于按位与操作来说,则 p r e r − p r e l − 1 ≤ r − l pre_r - pre_{l-1} \leq r-l prerprel1rl,对于按位或操作来说,则 p r e r − p r e l − 1 = 0 pre_r - pre_{l-1} = 0 prerprel1=0

有了以上不等式,我们即可建立差分约束系统,求出 pre 序列,从而差分求出满足题意的 a 序列。

注意事项:

  1. 该题因为 0 号节点被占用,所以不能像往常一样将 0 号节点作为汇点,而是以 n + 1 节点作为汇点。
  2. 该题数据由我们敬爱的学长 llsw 精心制作,所以使用 spfa 的时候需加入 SLF 优化。
  3. 该题需要进行多次 spfa,记得初始化。
  4. 对于前缀和数组本身也有 p r e i ≥ p r e i − 1 pre_i \geq pre_{i-1} preiprei1 p r e i − 1 ≤ p r e i {pre_{i-1} \leq pre_i} prei1prei 的条件,记得连边。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 5;
int n , m , s , t , dis[MAXN] , op[MAXN] , u[MAXN] , v[MAXN] , w[MAXN] , ans[MAXN];
int cnt , head[MAXN];
bool vis[MAXN];
struct edge{
	int to , nxt , w;
}e[MAXN];
void add(int u , int v , int w) {
	e[++ cnt].to = v;
	e[cnt].nxt = head[u];
	e[cnt].w = w;
	head[u] = cnt;
}
deque<int> q;
void Spfa() {
	memset(dis , 0x3f , sizeof(dis));
	dis[n + 1] = 0;
	q.push_back(n + 1);
	while(!q.empty()) {
		int u = q.front();
		q.pop_front();
		for (int i = head[u] ; i ; i = e[i].nxt) {
			int v = e[i].to;
			if (dis[v] > dis[u] + e[i].w) {
				dis[v] = dis[u] + e[i].w;
				vis[v] ++;
				if (vis[v] == n + 2) {
					printf("No");
					exit(0);
				}
				if (q.size() && dis[q.front()] >= dis[v]) q.push_front(v); // SLF 优化 
                else q.push_back(v);
			}
		}
	}
}
int main() {
	scanf("%d %d", &n , &m);
	for (int i = 1 ; i <= m ; i ++) {
		scanf("%d %d %d %d", &op[i] , &u[i] , &v[i] , &w[i]);
		u[i] --;
	}
	for (int i = 0 ; i <= 20 ; i ++) { // 对二进制每一位分别处理 
		cnt = 0;
		memset(head , 0 , sizeof(head));
		for (int i = 0 ; i <= n ; i ++) add(n + 1 , i , i);
		for (int j = 1 ; j <= m ; j ++) {
			if (op[j] == 1) { // 依照限制条件连边 
				if ((w[j] >> i) & 1) add(v[j] , u[j] , -1);
				else add(u[j] , v[j] , 0) , add(v[j] , u[j] , 0);
			} else {
				if ((w[j] >> i) & 1) add(u[j] , v[j] , v[j] - u[j]) , add(v[j] , u[j] , u[j] - v[j]);
				else add(u[j] , v[j] , v[j] - u[j] - 1);
			}
		}
		for (int j = 1 ; j <= n ; j ++) add(j , j - 1 , 0) , add(j - 1 , j , 1); // 前缀和数组本身条件 
		Spfa();
		for (int j = 1 ; j <= n ; j ++) {
			ans[j] += ((dis[j] - dis[j - 1]) << i);
		}
	}
	for (int i = 1 ; i <= n ; i++) printf("%d ", ans[i]);
	return 0;
}

Intervals

题意:在 [ 0 , 50000 ] [0,50000] [0,50000] 选出尽量少的整数,使每个区间 [ l i , r i ] [l_i,r_i] [li,ri] 内都有至少 x i x_i xi 个数被选出。

由于该题涉及了区间操作,较易想到前缀和。不妨令 p r e i pre_i prei 0 − i 0 - i 0i 选出的数的个数,这可得以下不等式:

  • 由于 [ l i , r i ] [l_i,r_i] [li,ri] 内都有至少 x i x_i xi 个数被选出,则 p r e r i − p r e l i − 1 ≥ x i pre_{r_i} - pre_{l_i - 1} \geq x_i preripreli1xi
  • 由于每个数只能被选一次,则 p r e i − p r e i − 1 ≤ 1 pre_i - pre_{i-1} \leq 1 preiprei11
  • 根据前缀和本身的定义,则 p r e i ≥ p r e i − 1 pre_i \geq pre_{i-1} preiprei1

根据以上不等式,建立差分约束系统进行求解即可。

注意:

  1. 该题求最小值,所以是最长路。
  2. 该题无需将 [ 0 , 50000 ] [0,50000] [0,50000] 的数都建边,只需要对 [ m i n n , m a x n ] [\mathrm{minn} , \mathrm{maxn}] [minn,maxn] 进行处理即可,其中 m i n n \mathrm{minn} minn l i l_i li 最小值, m a x n \mathrm{maxn} maxn r i r_i ri 最大值。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1e6 + 5;
int n , m , vis[MAXN] , cnt , head[MAXN] , ed;
int st = 0x3f3f3f3f , dis[MAXN];
struct edge{
	int to , nxt , w;
}e[MAXN];
void add(int u , int v , int w) {
	e[++ cnt].to = v;
	e[cnt].nxt = head[u];
	e[cnt].w = w;
	head[u] = cnt;
}
void Spfa() { // 最长路 
	memset(dis , 0xcf , sizeof(dis));
	dis[st] = 0;
	queue<int> q;
	q.push(st);
	vis[st] = 1;
	while(!q.empty()) {
		int u = q.front();
		q.pop();
		vis[u] = 0;
		for (int i = head[u] ; i ; i = e[i].nxt) {
			int v = e[i].to;
			if (dis[v] < dis[u] + e[i].w) {
				dis[v] = dis[u] + e[i].w;
				if (vis[v]) continue;
				vis[v] = 1;
				q.push(v);
			}
		}
	}
}
int main() {
	scanf("%d", &n);
	for (int i = 1 , u , v , w ; i <= n ; i ++) {
		scanf("%d %d %d", &u , &v , &w);
		ed = max(ed , v + 1);
		st = min(st , u);
		add(u , v + 1 , w); // 建边 
	}
	for (int i = st + 1 ; i <= ed ; i ++) add(i , i - 1 , -1) , add(i - 1 , i , 0);
	Spfa();
	printf("%d", dis[ed]); // dis[ed] 即为 0 ~ ed 选取的数的个数 
	return 0;
} 

矩阵游戏

简化题意:给出一个 n - 1 行 m - 1 列的矩阵 b,令 b i , j = a i , j + a i , j + 1 + a i + 1 , j + a i + 1 , j + 1 b_{i,j} = a_{i,j}+a_{i,j+1}+a_{i+1,j}+a_{i+1,j+1} bi,j=ai,j+ai,j+1+ai+1,j+ai+1,j+1,求出满足条件的矩阵 a,满足矩阵中任意元素 0 ≤ a i , j ≤ 1000000 0 \leq a_{i,j} \leq 1000000 0ai,j1000000

不难发现,该题求出一个合法的 a 矩阵非常容易,不妨令 a 矩阵第一行第一列均为 0,即可求出合法解。但是该种做法,不一定满足 0 ≤ a i , j ≤ 1000000 0 \leq a_{i,j} \leq 1000000 0ai,j1000000 的限制条件。对于该种情况,考虑调整法。

调整法,是由一组解经过调整得到另一组合法解的方法。该题中,不妨将矩阵 a 每行元素交替加减 r i r_i ri,对每列元素也交替加减 c i c_i ci。这样便可保证 a 矩阵中每一个 2 × 2 2 \times 2 2×2 的矩阵元素和不变,即 b 矩阵不变。

如上图所示,为何要 “交替” 呢?因为对于差分约束系统,只能处理形如 x i − x j ≤ x x_i - x_j \leq x xixjx 的不等式,而不能处理形如 x i + x j ≤ x x_i + x_j \leq x xi+xjx 的不等式。

有了调整方法,便可得出以下不等式:

  • 对于 2 ∣ i + j 2 \mid \mathrm{i}+\mathrm{j} 2i+j 0 ≤ a i , j + r i − c j ≤ 1000000 0 \leq a_{i,j}+r_i-c_j \leq 1000000 0ai,j+ricj1000000
  • 对于 2 ∤ i + j 2 \nmid \mathrm{i}+\mathrm{j} 2i+j 0 ≤ a i , j − r i + c j ≤ 1000000 0 \leq a_{i,j}-r_i+c_j \leq 1000000 0ai,jri+cj1000000

依照不等式建立差分约束系统,输出答案即可。由于该题是省选数据,需要加入 SLF 优化。

代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1e3 + 5 , MAXM = 2e5 + 5;
int n , m , vis[MAXN] , cnt , T , head[MAXN] , tot[MAXN];
int a[MAXN][MAXN] , b[MAXN][MAXN];
ll dis[MAXN];
struct edge{
	int to , nxt , w;
}e[MAXM];
void add(int u , int v , int w) {
	e[++ cnt].to = v;
	e[cnt].nxt = head[u];
	e[cnt].w = w;
	head[u] = cnt;
}
int Spfa() {
	memset(dis , 0x3f , sizeof(dis));
	memset(vis , 0 , sizeof(vis));
	memset(tot , 0 , sizeof(tot));
	dis[0] = 0;
	deque<int> q;
	q.push_back(0);
	while(!q.empty()) {
		int u = q.front();
		q.pop_front();
		vis[u] ++;
		if (vis[u] > n + m) return 0;
		tot[u] = 0;
		for (int i = head[u] ; i ; i = e[i].nxt) {
			int v = e[i].to;
			if (dis[v] > dis[u] + e[i].w) {
				dis[v] = dis[u] + e[i].w;
				if (tot[v]) continue;
				tot[v] = 1;
				if (q.size() && dis[q.front()] >= dis[v]) q.push_front(v); //SLF优化
                else q.push_back(v);
			}
		}
	}
	return 1;
}
int main() {
	freopen("matrix.in" , "r" , stdin);
	freopen("matrix.out" , "w" , stdout);
	scanf("%d", &T);
	while(T --) {
		scanf("%d %d", &n , &m);
		memset(a , 0 , sizeof(a));
		for (int i = 1 ; i < n ; i ++) {
			for (int j = 1 ; j < m ; j ++) {
				scanf("%d", &b[i][j]);
			}
		} 
		for (int i = 2 ; i <= n ; i ++) { //求出一组解
			for (int j = 2 ; j <= m ; j ++) {
				a[i][j] = b[i - 1][j - 1] - a[i - 1][j] - a[i][j - 1] - a[i - 1][j - 1];
			}
		}
		cnt = 0;
		memset(head , 0 , sizeof(head));
		for (int i = 1 ; i <= n ; i ++) {
			for (int j = 1 ; j <= m ; j ++) {
				if (i + j & 1){ // 建立差分约束系统
					add(i , j + n , a[i][j]);
					add(j + n , i , 1000000 - a[i][j]);
				} else {
					add(i , j + n , 1000000 - a[i][j]);
					add(j + n , i , a[i][j]);
				}
			}
		}
		for (int i = 1 ; i <= n + m ; i ++) add(0 , i , 0); // 建立汇点
		if (!Spfa()) puts("NO");
		else {
			puts("YES");
			for(int i = 1 ; i <= n ; i ++) {
				for(int j = 1 ; j <= m ; j ++) {
					if(i + j & 1) a[i][j] = a[i][j] + dis[i] - dis[n + j];
					else a[i][j] = a[i][j] - dis[i] + dis[n + j];
					printf("%d ", a[i][j]);
				}
				puts("");
			}
		}
	}
	return 0;
} 
  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据库系统概论习题答案 1 第1 章 绪论 1 .试述数据、数据库、数据库系统、数据库管理系统的概念。 答: ( l )数据( Data ) :描述事物的符号记录称为数据。数据的种类有数字、文字、图形、图 像、声音、正文等。数据与其语义是不可分的。解析在现代计算机系统中数据的概念是广义 的。早期的计算机系统主要用于科学计算,处理的数据是整数、实数、浮点数等传统数学中 的数据。现代计算机能存储和处理的对象十分广泛,表示这些对象的数据也越来越复杂。数 据与其语义是不可分的。 500 这个数字可以表示一件物品的价格是 500 元,也可以表示一 个学术会议参加的人数有 500 人,还可以表示一袋奶粉重 500 克。 ( 2 )数据库( DataBase ,简称 DB ) :数据库是长期储存在计算机内的、有组织的、可 共享的数据集合。数据库中的数据按一定的数据模型组织、描述和储存,具有较小的冗余度、 较高的数据独立性和易扩展性,并可为各种用户共享。 ( 3 )数据库系统( DataBas 。 Sytem ,简称 DBS ) :数据库系统是指在计算机系统中 引入数据库后的系统构成,一般由数据库、数据库管理系统(及其开发工具)、应用系统、 数据库管理员构成。解析数据库系统和数据库是两个概念。数据库系统是一个人一机系统, 数据库是数据库系统的一个组成部分。但是在日常工作中人们常常把数据库系统简称为数据 库。希望读者能够从人们讲话或文章的上下文中区分“数据库系统”和“数据库”,不要引 起混淆。 ( 4 )数据库管理系统( DataBase Management sytem ,简称 DBMs ) :数据库管理系统是 位于用户与操作系统之间的一层数据管理软件,用于科学地组织和存储数据、高效地获取和 维护数据。 DBMS 的主要功能包括数据定义功能、数据操纵功能、数据库的运行管理功能、 数据库的建立和维护功能。解析 DBMS 是一个大型的复杂的软件系统,是计算机中的基础 软件。目前,专门研制 DBMS 的厂商及其研制的 DBMS 产品很多。著名的有美国 IBM 公 司的 DBZ 关系数据库管理系统和 IMS 层次数据库管理系统、美国 Oracle 公司的 orade 关系数据库管理系统、 s 油 ase 公司的 s 油 ase 关系数据库管理系统、美国微软公司的 SQL Serve ,关系数据库管理系统等。 2 .使用数据库系统有什么好处? 答: 使用数据库系统的好处是由数据库管理系统的特点或优点决定的。使用数据库系统的好处很 多,例如,可以大大提高应用开发的效率,方便用户的使用,减轻数据库系统管理人员维护 的负担,等等。使用数据库系统可以大大提高应用开发的效率。因为在数据库系统中应用程 序不必考虑数据的定义、存储和数据存取的具体路径,这些工作都由 DBMS 来完成。用一 个通俗的比喻,使用了 DBMS 就如有了一个好参谋、好助手,许多具体的技术工作都由这 个助手来完成。开发人员就可以专注于应用逻辑的设计,而不必为数据管理的许许多多复杂 的细节操心。还有,当应用逻辑改变,数据的逻辑结构也需要改变时,由于数据库系统提供 了数据与程序之间的独立性,数据逻辑结构的改变是 DBA 的责任,开发人员不必修改应 用程序,或者只需要修改很少的应用程序,从而既简化了应用程序的编制,又大大减少了应 用程序的维护和修改。使用数据库系统可以减轻数据库系统管理人员维护系统的负担。因为 DBMS 在数据库建立、运用和维护时对数据库进行统一的管理和控制,包括数据的完整性、 安全性、多用户并发控制、故障恢复等,都由 DBMS 执行。总之,使用数据库系统的优点 是很多的,既便于数据的集中管理,控制数据冗余,提高数据的利用率和一致性,又有利于 应用程序的开发和维护。读者可以在自己今后的工作中结合具体应用,认真加以体会和总结。 3 .试述文件系统与数据库系统的区别和联系。 答: 文件系统与数据库系统的区别是:文件系统面向某一应用程序,共享性差,冗余度大,数据 独立性差,记录内有结构,整体无结构,由应用程序自己控制。数据库系统面向现实世界, 共享性高,冗余度小,具有较高的物理独立性和一定的逻辑独立性,整体结构化,用数据模 型描述,由数据库管理系统提供数据的安全性、完整性、并发控制和恢复能力。 文件系统与数据库系统的联系是:文件系统与数据库系统都是计算机系统中管理数据的软 件。解析文件系统是操作系统的重要组成部分;而 DBMS 是独立于操作系统的软件。但是 DBMS 是在操作系统的基础上实现的;数据库中数据的组织和存储是通过操作系统中的文 件系统来实现的。 4 .举出适合用文件系统而不是数据库系统的例子;再举出适合用数据库系统的应用例子。 答 : ( l )适用于文件系统而不是数据库系统的应用例子数据的备份、软件或应用程序使用过程 中的临时数据存储一般使用文件比较合适。早期功能比较简单、比较固定的应用系统也适合 用文件系统。 ( 2 )适用于数据库系统而非文件系统的应用例子目前,几乎所有企业或部门的信息系统 都以数据库系统为基础,都使用数据库。例如,一个工厂的管理信息系统(其中会包括许多 子系统,如库存管理系统、物资采购系统、作业调度系统、设备管理系统、人事管理系统等), 学校的学生管理系统,人事管理系统,图书馆的图书管理系统,等等,都适合用数据库系统。 希望读者能举出自己了解的应用例子。 5 .试述数据库系统的特点。 答: 数据库系统的主要特点有: ( l )数据结构化数据库系统实现整体数据的结构化,这是数据库的主要特征之一,也是数 据库系统与文件系统的本质区别。解析注意这里的“整体’夕两个字。在数据库系统中,数 据不再针对某一个应用,而是面向全组织,具有整体的结构化。不仅数据是结构化的,而且 数据的存取单位即一次可以存取数据的大小也很灵活,可以小到某一个数据项(如一个学生 的姓名),大到一组记录(成千上万个学生记录)。而在文件系统中,数据的存取单位只有一 个:记录,如一个学生的完整记录。 ( 2 )数据的共享性高,冗余度低,易扩充数据库的数据不再面向某个应用而是面向整个 系统,因此可以被多个用户、多个应用以多种不同的语言共享使用。由于数据面向整个系统, 是有结构的数据,不仅可以被多个应用共享使用,而且容易增加新的应用,这就使得数据库 系统弹性大,易于扩充。解析数据共享可以大大减少数据冗余,节约存储空间,同时还能够 避免数据之间的不相容性与不一致性。所谓“数据面向某个应用”是指数据结构是针对某个 应用设计的,只被这个应用程序或应用系统使用,可以说数据是某个应用的“私有资源”。 所谓“弹性大”是指系统容易扩充也容易收缩,即应用增加或减少时不必修改整个数据库的 结构,只需做很少的改动。可以取整体数据的各种子集用于不同的应用系统,当应用需求改 变或增加时,只要重新选取不同的子集或加上一部分数据,便可以满足新的需求。 ( 3 )数据独立性高数据独立性包括数据的物理独立性和数据的逻辑独立性。数据库管理 系统的模式结构和二级映像功能保证了数据库中的数据具有很高的物理独立性和逻辑独立 性。 ( 4 )数据由 DBMS 统一管理和控制数据库的共享是并发的共享,即多个用户可以同时存 3 取数据库中的数据甚至可以同时存取数据库中同一个数据。为此, DBMS 必须提供统一的 数据控制功能,包括数据的安全性保护、数据的完整性检查、并发控制和数据库恢复。解析 DBMS 数据控制功能包括四个方面:数据的安全性保护:保护数据以防止不合法的使用造 成的数据的泄密和破坏;数据的完整性检查:将数据控制在有效的范围内,或保证数据之间 满足一定的关系;并发控制:对多用户的并发操作加以控制和协调,保证并发操作的正确性; 数据库恢复:当计算机系统发生硬件故障、软件故障,或者由于操作员的失误以及故意的破 坏影响数据库中数据的正确性,甚至造成数据库部分或全部数据的丢失时,能将数据库从错 误状态恢复到某一已知的正确状态(亦称为完整状态或一致状态)。下面可以得到“什么是 数据库”的一个定义:数据库是长期存储在计算机内有组织的大量的共享的数据集合,它可 以供各种用户共享,具有最小冗余度和较高的数据独立性。 DBMS 在数据库建立、运用和 维护时对数据库进行统一控制,以保证数据的完整性、安全性,并在多用户同时使用数据库 时进行并发控制,在发生故障后对系统进行恢复。数据库系统的出现使信息系统从以加工数 据的程序为中心转向围绕共享的数据库为中心的新阶段。 6 .数据库管理系统的主要功能有哪些? 答: ( l )数据库定义功能; ( 2 )数据存取功能; ( 3 )数据库运行管理; ( 4 )数据库的建立和维护功能。 7 .试述数据模型的概念、数据模型的作用和数据模型的三个要素。 答: 数据模型是数据库中用来对现实世界进行抽象的工具,是数据库中用于提供信息表示和操作 手段的形式构架。一般地讲,数据模型是严格定义的概念的集合。这些概念精确描述了系统 的静态特性、动态特性和完整性约束条件。因此数据模型通常由数据结构、数据操作和完整 性约束三部分组成。 ( l )数据结构:是所研究的对象类型的集合,是对系统静态特性的描述。 ( 2 )数据操作:是指对数据库中各种对象(型)的实例(值)允许进行的操作的集合, 包括操作及有关的操作规则,是对系统动态特性的描述。 ( 3 )数据的约束条件:是一组完整性规则的集合。完整性规则是给定的数据模型中数据 及其联系所具有的制约和依存规则,用以限定符合数据模型的数据库状态以及状态的变化, 以保证数据的正确、有效、相容。解析数据模型是数据库系统中最重要的概念之一。必须通 过 《 概论 》 的学习真正掌握数据模型的概念和作用。数据模型是数据库系统的基础。任 何一个 DBMS 都以某一个数据模型为基础,或者说支持某一个数据模型。数据库系统中, 模型有不同的层次。根据模型应用的不同目的,可以将模型分成两类或者说两个层次:一类 是概念模型,是按用户的观点来对数据和信息建模,用于信息世界的建模,强调语义表达能 力,概念简单清晰;另一类是数据模型,是按计算机系统的观点对数据建模,用于机器世界, 人们可以用它定义、操纵数据库中的数据,一般需要有严格的形式化定义和一组严格定义了 语法和语义的语言,并有一些规定和限制,便于在机器上实现。 8 .试述概念模型的作用。 答: 概念模型实际上是现实世界到机器世界的一个中间层次。概念模型用于信息世界的建模,是 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. 数据库系统概论习题答案 4 现实世界到信息世界的第一层抽象,是数据库设计人员进行数据库设计的有力工具,也是数 据库设计人员和用户之间进行交流的语言。 9 .定义并解释概念模型中以下术语:实体,实体型,实体集,属性,码,实体联系图( E 一 R 图) 答: 实体:客观存在并可以相互区分的事物叫实体。实体型:具有相同属性的实体具有相同的特 征和性质,用实体名及其属性名集合来抽象和刻画同类实体,称为实体型。实体集:同型实 体的集合称为实体集。属性:实体所具有的某一特性,一个实体可由若干个属性来刻画。码: 惟一标识实体的属性集称为码。实体联系图( E 一 R 图):提供了表示实体型、属性和联 系的方法: · 实体型:用矩形表示,矩形框内写明实体名; · 属性:用椭圆形表示,并 用无向边将其与相应的实体连接起来; · 联系:用菱形表示,菱形框内写明联系名,并用 无向边分别与有关实体连接起来,同时在无向边旁标上联系的类型( 1 : 1 , 1 : n 或 m : n )。 10 .试给出 3 个实际部门的 E 一 R 图,要求实体型之间具有一对一、一对多、多对多 各种不同的联系。 答: 11 .试给出一个实际部门的 E 一 R 图,要求有三个实体型,而且 3 个实体型之间有多 对多联系。 3 个实体型之间的多对多联系和三个实体型两两之间的三个多对多联系等价 吗?为什么? 答: 3 个实体型之间的多对多联系和 3 个实体型两两之间的 3 个多对多联系是不等价,因为它 们拥有不同的语义。 3 个实体型两两之间的三个多对多联系如下图所示。 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only.
智能优化算法总结 优化算法有很多,经典算法包括:有线性规划,动态规划等;改进型局部搜索算法包括爬⼭法,最速下降法等,模拟退⽕、遗传算法以及禁 忌搜索称作指导性搜索法。⽽神经⽹络,混沌搜索则属于系统动态演化⽅法。 梯度为基础的传统优化算法具有较⾼的计算效率、较强的可靠性、⽐较成熟等优点,是⼀类最重要的、应⽤最⼴泛的优化算法。但是,传统 的最优化⽅法在应⽤于复杂、困难的优化问题时有较⼤的局限性。⼀个优化问题称为是复杂的,通常是指具有下列特征之⼀:(1)⽬标函 数没有明确解析表达;(2)⽬标函数虽有明确表达,但不可能恰好估值;(3)⽬标函数为多峰函数;(4)⽬标函数有多个,即多⽬标优 化。⼀个优化问题称为是困难的,通常是指:⽬标函数或约束条件不连续、不可微、⾼度⾮线性,或者问题本⾝是困难的组合问题。传统优 化⽅法往往要求⽬标函数是凸的、连续可微的,可⾏域是凸集等条件,⽽且处理⾮确定性信息的能⼒较差。这些弱点使传统优化⽅法在解决 许多实际问题时受到了限制。 智能优化算法⼀般都是建⽴在⽣物智能或物理现象基础上的随机搜索算法,⽬前在理论上还远不如传统优化算法完善,往往也不能确保解的 最优性,因⽽常常被视为只是⼀些"元启发式⽅法"(meta-heuristic)。但从实际应⽤的观点看,这类新算法⼀般不要求⽬标函数和约束 的连续性与凸性,甚⾄有时连有没有解析表达式都不要求,对计算中数据的不确定性也有很强的适应能⼒。 下⾯给出⼀个局部搜索,模拟退⽕,遗传算法,禁忌搜索的形象⽐喻:      为了找出地球上最⾼的⼭,⼀群有志⽓的兔⼦们开始想办法。       1.兔⼦朝着⽐现在⾼的地⽅跳去。他们找到了不远处的最⾼⼭峰。但是这座⼭不⼀定是珠穆朗玛峰。这就是局部搜索,它不能保证局 部最优值就是全局最优值。       2.兔⼦喝醉了。他随机地跳了很长时间。这期间,它可能⾛向⾼处,也可能踏⼊平地。但是,他渐渐清醒了并朝最⾼⽅向跳去。这就 是模拟退⽕。   3.兔⼦们吃了失忆药⽚,并被发射到太空,然后随机落到了地球上的某些地⽅。他们不知道⾃⼰的使命是什么。但是,如果你过⼏年 就杀死⼀部分海拔低的兔⼦,多产的兔⼦们⾃⼰就会找到珠穆朗玛峰。这就是遗传算法。       4.兔⼦们知道⼀个兔的⼒量是渺⼩的。他们互相转告着,哪⾥的⼭已经找过,并且找过的每⼀座⼭他们都留下⼀只兔⼦做记号。他们制 定了下⼀步去哪⾥寻找的策略。这就是禁忌搜索。 ⼀般⽽⾔,局部搜索就是基于贪婪思想利⽤邻域函数进⾏搜索,若找到⼀个⽐现有值更优的解就弃前者⽽取后者。但是,它⼀般只可以得 到"局部极⼩解",就是说,可能这只兔⼦登"登泰⼭⽽⼩天下",但是却没有找到珠穆朗玛峰。⽽模拟退⽕,遗传算法,禁忌搜索,神经 ⽹络等从不同的⾓度和策略实现了改进,取得较好的"全局最⼩解"。      模拟退⽕算法(Simulated Annealing,SA)      模拟退⽕算法的依据是固体物质退⽕过程和组合优化问题之间的相似性。物质在加热的时候,粒⼦间的布朗运动增强,到达⼀定强度 后,固体物质转化为液态,这个时候再进⾏退⽕,粒⼦热运动减弱,并逐渐趋于有序,最后达到稳定。      模拟退⽕的解不再像局部搜索那样最后的结果依赖初始点。它引⼊了⼀个接受概率p。如果新的点(设为pn)的⽬标函数f(pn)更 好,则p=1,表⽰选取新点;否则,接受概率p是当前点(设为pc)的⽬标函数f(pc),新点的⽬标函数f(pn)以及另⼀个控制参数"温 度"T的函数。也就是说,模拟退⽕没有像局部搜索那样每次都贪婪地寻找⽐现在好的点,⽬标函数差⼀点的点也有可能接受进来。随着算 法的执⾏,系统温度T逐渐降低,最后终⽌于某个低温,在该温度下,系统不再接受变化。      模拟退⽕的典型特征是除了接受⽬标函数的改进外,还接受⼀个衰减极限,当T较⼤时,接受较⼤的衰减,当T逐渐变⼩时,接受较⼩的 衰减,当T为0时,就不再接受衰减。这⼀特征意味着模拟退⽕与局部搜索相反,它能避开局部极⼩,并且还保持了局部搜索的通⽤性和简 单性。   在物理上,先加热,让分⼦间互相碰撞,变成⽆序状态,内能加⼤,然后降温,最后的分⼦次序反⽽会更有序,内能⽐没有加热前更 ⼩。就像那只兔⼦,它喝醉后,对⽐较近的⼭峰视⽽不见,迷迷糊糊地跳⼀⼤圈⼦,反⽽更有可能找到珠峰。 值得注意的是,当T为0时,模拟退⽕就成为局部搜索的⼀个特例。       模拟退⽕的伪码表达:   procedure simulated annealing   begin   t:=0;   initialize temperature T   select a current string vc at random;   evaluate vc;   repeat    repeat    se
Amber 大牛关于图论的总结 ,1.1M 大小.... 1. 图论 Graph Theory 1.1. 定义与术语 Definition and Glossary 1.1.1. 图与网络 Graph and Network 1.1.2. 图的术语 Glossary of Graph 1.1.3. 路径与回路 Path and Cycle 1.1.4. 连通性 Connectivity 1.1.5. 图论中特殊的集合 Sets in graph 1.1.6. 匹配 Matching 1.1.7. 树 Tree 1.1.8. 组合优化 Combinatorial optimization 1.2. 图的表示 Expressions of graph 1.2.1. 邻接矩阵 Adjacency matrix 1.2.2. 关联矩阵 Incidence matrix 1.2.3. 邻接表 Adjacency list 1.2.4. 弧表 Arc list 1.2.5. 星形表示 Star 1.3. 图的遍历 Traveling in graph 1.3.1. 深度优先搜索 Depth first search (DFS) 1.3.1.1. 概念 1.3.1.2. 求无向连通图中的桥 Finding bridges in undirected graph 1.3.2. 广度优先搜索 Breadth first search (BFS) 1.4. 拓扑排序 Topological sort 1.5. 路径与回路 Paths and circuits 1.5.1. 欧拉路径或回路 Eulerian path 1.5.1.1. 无向图 1.5.1.2. 有向图 1.5.1.3. 混合图 1.5.1.4. 无权图 Unweighted 1.5.1.5. 有权图 Weighed — 中国邮路问题The Chinese post problem 1.5.2. Hamiltonian Cycle 哈氏路径与回路 1.5.2.1. 无权图 Unweighted 1.5.2.2. 有权图 Weighed — 旅行商问题The travelling salesman problem 1.6. 网络优化 Network optimization 1.6.1. 最小生成树 Minimum spanning trees 1.6.1.1. 基本算法 Basic algorithms 1.6.1.1.1. Prim 1.6.1.1.2. Kruskal 1.6.1.1.3. Sollin(Boruvka) 1.6.1.2. 扩展模型 Extended models 1.6.1.2.1. 度限制生成树 Minimum degree-bounded spanning trees 1.6.1.2.2. k小生成树 The k minimum spanning tree problem(k-MST) 1.6.2. 最短路Shortest paths 1.6.2.1. 单源最短路 Single-source shortest paths 1.6.2.1.1. 基本算法 Basic algorithms 1.6.2.1.1.1. Dijkstra 1.6.2.1.1.2. Bellman-Ford 1.6.2.1.1.2.1. Shortest path faster algorithm(SPFA) 1.6.2.1.2. 应用Applications 1.6.2.1.2.1. 差分约束系统 System of difference constraints 1.6.2.1.2.2. 有向无环图上的最短路 Shortest paths in DAG 1.6.2.2. 所有顶点对间最短路 All-pairs shortest paths 1.6.2.2.1. 基本算法 Basic algorithms 1.6.2.2.1.1. Floyd-Warshall 1.6.2.2.1.2. Johnson 1.6.3. 网络流 Flow network 1.6.3.1. 最大流 Maximum flow 1.6.3.1.1. 基本算法 Basic algorithms 1.6.3.1.1.1. Ford-Fulkerson method 1.6.3.1.1.1.1. Edmonds-Karp algorithm 1.6.3.1.1.1.1.1. Minimum length path 1.6.3.1.1.1.1.2. Maximum capability path 1.6.3.1.1.2. 预流推进算法 Preflow push method 1.6.3.1.1.2.1. Push-relabel 1.6.3.1.1.2.2. Relabel-to-front 1.6.3.1.1.3. Dinic method 1.6.3.1.2. 扩展模型 Extended models 1.6.3.1.2.1. 有上下界的流问题 1.6.3.2. 最小费用流 Minimum cost flow 1.6.3.2.1. 找最小费用路 Finding minimum cost path 1.6.3.2.2. 找负权圈 Finding negative circle 1.6.3.2.3. 网络单纯形 Network simplex algorithm 1.6.4. 匹配 Matching 1.6.4.1. 二分图 Bipartite Graph 1.6.4.1.1. 无权图-匈牙利算法 Unweighted - Hopcroft and Karp algorithm 1.6.4.1.2. 带权图-KM算法 Weighted –Kuhn-Munkres(KM) algorithm 1.6.4.2. 一般图General Graph 1.6.4.2.1. 无权图-带花树算法 Unweighted - Blossom (Edmonds) 1.
amber大牛的图论总结 1. 图论 Graph Theory 1.1. 定义与术语 Definition and Glossary 1.1.1. 图与网络 Graph and Network 1.1.2. 图的术语 Glossary of Graph 1.1.3. 路径与回路 Path and Cycle 1.1.4. 连通性 Connectivity 1.1.5. 图论中特殊的集合 Sets in graph 1.1.6. 匹配 Matching 1.1.7. 树 Tree 1.1.8. 组合优化 Combinatorial optimization 1.2. 图的表示 Expressions of graph 1.2.1. 邻接矩阵 Adjacency matrix 1.2.2. 关联矩阵 Incidence matrix 1.2.3. 邻接表 Adjacency list 1.2.4. 弧表 Arc list 1.2.5. 星形表示 Star 1.3. 图的遍历 Traveling in graph 1.3.1. 深度优先搜索 Depth first search (DFS) 1.3.1.1. 概念 1.3.1.2. 求无向连通图中的桥 Finding bridges in undirected graph 1.3.2. 广度优先搜索 Breadth first search (BFS) 1.4. 拓扑排序 Topological sort 1.5. 路径与回路 Paths and circuits 1.5.1. 欧拉路径或回路 Eulerian path 1.5.1.1. 无向图 1.5.1.2. 有向图 1.5.1.3. 混合图 1.5.1.4. 无权图 Unweighted 1.5.1.5. 有权图 Weighed — 中国邮路问题The Chinese post problem 1.5.2. Hamiltonian Cycle 哈氏路径与回路 1.5.2.1. 无权图 Unweighted 1.5.2.2. 有权图 Weighed — 旅行商问题The travelling salesman problem 1.6. 网络优化 Network optimization 1.6.1. 最小生成树 Minimum spanning trees 1.6.1.1. 基本算法 Basic algorithms 1.6.1.1.1. Prim 1.6.1.1.2. Kruskal 1.6.1.1.3. Sollin(Boruvka) 1.6.1.2. 扩展模型 Extended models 1.6.1.2.1. 度限制生成树 Minimum degree-bounded spanning trees 1.6.1.2.2. k小生成树 The k minimum spanning tree problem(k-MST) 1.6.2. 最短路Shortest paths 1.6.2.1. 单源最短路 Single-source shortest paths 1.6.2.1.1. 基本算法 Basic algorithms 1.6.2.1.1.1. Dijkstra 1.6.2.1.1.2. Bellman-Ford 1.6.2.1.1.2.1. Shortest path faster algorithm(SPFA) 1.6.2.1.2. 应用Applications 1.6.2.1.2.1. 差分约束系统 System of difference constraints 1.6.2.1.2.2. 有向无环图上的最短路 Shortest paths in DAG 1.6.2.2. 所有顶点对间最短路 All-pairs shortest paths 1.6.2.2.1. 基本算法 Basic algorithms 1.6.2.2.1.1. Floyd-Warshall 1.6.2.2.1.2. Johnson 1.6.3. 网络流 Flow network 1.6.3.1. 最大流 Maximum flow 1.6.3.1.1. 基本算法 Basic algorithms 1.6.3.1.1.1. Ford-Fulkerson method 1.6.3.1.1.1.1. Edmonds-Karp algorithm 1.6.3.1.1.1.1.1. Minimum length path 1.6.3.1.1.1.1.2. Maximum capability path 1.6.3.1.1.2. 预流推进算法 Preflow push method 1.6.3.1.1.2.1. Push-relabel 1.6.3.1.1

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值