《最优化理论》:运输问题(一)求最小运费【西北角法、最小元素法、伏格尔法】

【运筹学】-运输问题(一)(运输问题模型)

西北角法:在单位运价表中,每次从西北角位置选择元素,不考虑单位运价
最小元素法:在单位运价表中,每次选择运价最小的元素
伏格尔法:每次重新计算未被划去的行列的最小元素和次小元素的差额,选择最大差额对应列的最小元素对应的行列

例题

在这里插入图片描述

求解方法

在这里插入图片描述

步骤一:求初始基本可行解

西北角法求解

(1)确定西北角
在这里插入图片描述
(2)标识基变量:确定最大运输量(可接受量) bj 和可提供量 ai
在这里插入图片描述
在这里插入图片描述
(3)确定西北角
在这里插入图片描述

(4)标识基变量:确定最大运输量(可接受量) bj 和可提供量 ai
在这里插入图片描述
在这里插入图片描述
(5)确定西北角
在这里插入图片描述
(6)标识基变量:确定最大运输量(可接受量) bj 和可提供量 ai
在这里插入图片描述
(7)确定西北角
在这里插入图片描述
(8)确定运输表
在这里插入图片描述
(9)确定西北角
在这里插入图片描述
(10)确定运输表
在这里插入图片描述
(11)确定西北角
在这里插入图片描述
(12)确定运输表
在这里插入图片描述
到此,找到了6个基变量,而我们需要的基变量也正是m+n-1=3+4-1=6个,说明我们找到了初始可行解<

### Python 实现运输问题中的格尔逼近 (VAM) 和位势 #### 格尔逼近 (VAM) 格尔逼近种用于解决运输问题的有效方,能够提供接近最优解的结果。下面是个基于给定引用的Python实现: ```python import numpy as np def vogel_approximation_method(cost_matrix, supply, demand): rows = len(supply) cols = len(demand) # 创建副本以防止修改原始数据[^5] cost = copy.deepcopy(cost_matrix) allocation = np.zeros((rows, cols)) while sum(supply) > 0 and sum(demand) > 0: penalty = [] for i in range(rows): sorted_row = sorted(row for row in cost[i] if row != 'X') if len(sorted_row) >= 2: penalty.append(abs(sorted_row[1] - sorted_row[0])) else: penalty.append(float('inf')) for j in range(cols): col = [cost[row][j] for row in range(rows) if cost[row][j] != 'X'] sorted_col = sorted(col) if len(sorted_col) >= 2: penalty[j] = abs(sorted_col[1] - sorted_col[0]) elif not penalty: penalty.append(float('inf')) max_penalty_index = int(np.argmax(penalty)) # 找到最大罚数所在位置[^3] min_cost_in_max_penalty = float('inf') selected_i, selected_j = None, None if max_penalty_index < rows: # 如果是在行中找到的最大罚数 for j in range(cols): if cost[max_penalty_index][j] < min_cost_in_max_penalty and cost[max_penalty_index][j] != 'X': min_cost_in_max_penalty = cost[max_penalty_index][j] selected_i, selected_j = max_penalty_index, j else: # 如果是在列中找到的最大罚数 adjusted_index = max_penalty_index - rows for i in range(rows): if cost[i][adjusted_index] < min_cost_in_max_penalty and cost[i][adjusted_index] != 'X': min_cost_in_max_penalty = cost[i][adjusted_index] selected_i, selected_j = i, adjusted_index allocated_amount = min(supply[selected_i], demand[selected_j]) allocation[selected_i][selected_j] = allocated_amount cost[selected_i][selected_j] = 'X' supply[selected_i] -= allocated_amount demand[selected_j] -= allocated_amount if supply[selected_i] == 0: for k in range(cols): cost[selected_i][k] = 'X' if demand[selected_j] == 0: for l in range(rows): cost[l][selected_j] = 'X' total_cost = sum(allocation * cost_matrix).sum() return allocation, total_cost ``` 此函数接收三个参数:`cost_matrix`, `supply`, 和 `demand`. 它返回分配矩阵以及总费用。 #### 位势(Stepping Stone Method) 位势用来检验当前解决方案是否是最优解,并通过调整来改进方案直到达到最优状态。以下是该过程的个简化版本: ```python def stepping_stone_method(initial_solution, cost_matrix, supply, demand): m, n = initial_solution.shape u = [None] * m v = [None] * n # 初始化u和v向量 u[0] = 0 cells_visited = set() def find_path(i, j): stack = [(i, j)] visited = {(i, j)} while stack: ci, cj = stack[-1] neighbors = [ (ni, nj) for ni, nj in ((ci-1,cj), (ci+1,cj), (ci,cj-1), (ci,cj+1)) if 0<=ni<m and 0<=nj<n and (initial_solution[ni,nj]>0 or (ni==i and nj==j)) and (ni, nj) not in visited ] if any(ni==i and nj==j for ni, nj in neighbors): path = list(reversed(stack[:]+[(i,j)])) return True, path unvisited_neighbors = [cell for cell in neighbors if cell not in visited] if unvisited_neighbors: next_cell = unvisited_neighbors.pop(0) stack.append(next_cell) visited.add(next_cell) else: stack.pop() return False, [] found_cycle, cycle = find_path(-1,-1) while found_cycle: theta = min([initial_solution[x,y] for x,y in cycle[:-1]]) plus_minus = (+theta, -theta)*len(cycle)//2 for idx, (x,y) in enumerate(cycle): initial_solution[x,y] += plus_minus[idx%2] found_cycle, cycle = find_path(-1,-1) improved_allocation = initial_solution.copy() optimal_total_cost = sum(improved_allocation * cost_matrix).sum() return improved_allocation, optimal_total_cost ``` 这段代码实现了位势的核心逻辑,即寻找闭合回路并据此调整流量分布,从而降低总体成本。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值