AU4303 线性规划与非线性规划
章节 | 链接 | 源文件 |
---|---|---|
Sec1 | Sec1-介绍 | Sec1-介绍 |
Sec2 | Sec2-线性规划 | Sec2-线性规划 |
Sec3 | Sec3-对偶理论 | Sec3-对偶理论 |
Sec4 | Sec4-运输问题和指派问题 | Sec4-运输问题和指派问题 |
Sec1-介绍
Sec2-线性规划
Sec3-对偶理论
Sec4-运输问题和指派问题
运输问题
代码实现:
- greedy 方法求出初始可行解。(PPT P19)
def greedy_method():
ap = np.copy(a)
bp = np.copy(b)
v = []
for i in range(n):
for j in range(m):
v.append((P[i][j], i, j))
v.sort()
for k in v:
p, i, j = k
if ap[i] > 0 and bp[j] > 0:
sel = min(ap[i], bp[j])
ap[i] -= sel
bp[j] -= sel
bfs[i][j] = 1
T[i][j] = sel
- 计算检验数(PPT P23,还是需要解方程)
def calc_check_score():
# 计算检验数
u = np.zeros(n)
v = np.zeros(m)
A = np.zeros((n + m, n + m))
b = np.zeros(n + m)
cnt = 0
for i in range(n):
for j in range(m):
if bfs[i][j] == 1:
A[cnt][i] = 1
A[cnt][n + j] = 1
b[cnt] = P[i][j]
cnt += 1
A[cnt][0] = 1
b[cnt] = 0
sol = np.linalg.solve(A, b)
u = sol[:n]
v = sol[n:]
check_score = np.zeros((n, m))
for i in range(n):
for j in range(m):
check_score[i][j] = u[i] + v[j] - P[i][j]
return check_score
- 更新基(PPT P25)
def bfs_update(check_score):
# 选择 check_score 最大的点入基
max_score = -1e9
in_i, in_j = -1, -1
for i in range(n):
for j in range(m):
if check_score[i][j] > max_score:
max_score = check_score[i][j]
in_i, in_j = i, j
if max_score <= 0:
return False
print("in", in_i, in_j)
bfs[in_i][in_j] = 1
A = np.zeros((n + m, n + m))
id = np.zeros((n, m))
cnt = 0
p = []
for i in range(n):
for j in range(m):
if bfs[i][j] == 1:
id[i][j] = cnt
if i == in_i and j == in_j:
k0 = cnt
p.append((i, j))
cnt = cnt + 1
for i in range(n):
for j in range(m):
if (bfs[i][j]):
A[i][(int)(id[i][j])] = 1
for j in range(m):
for i in range(n):
if (bfs[i][j]):
A[j + n][(int)(id[i][j])] = 1
V = scipy.linalg.null_space(A)
V = V / V[k0]
V = -V
minn = 1e9
out_i, out_j = -1, -1
for k in range(cnt):
i, j = p[k]
if not (i == in_i and j == in_j) and V[k] > 0 and T[i][j] / V[k] < minn:
minn = T[i][j] / V[k]
out_i, out_j = i,j
print("out", out_i, out_j)
for k in range(cnt):
i, j = p[k]
T[i][j] -= minn * V[k]
bfs[out_i][out_j] = 0
return True
- 其实问题也可以用最小费用最大流解决,扩展阅读:https://oi-wiki.org/graph/flow/min-cost/
指派问题
- 其实问题也可以用二分图最大权匹配解决,扩展阅读:https://oi-wiki.org/graph/graph-matching/bigraph-weight-match/