运输问题基本解 最小元素法
关于运输问题的理解这里就不在赘述了,百度上一搜就有很多介绍。
直接进入正题,怎么把算法写出来。这里只考虑运输平衡的运输问题,对应运输不平衡的问题先转换为运输平衡的问题然后解决。
最小元素法需要画一张表,表行标题是对应发货地,列标题是对应收货地点,另外多加一行对应每个收货地的收货量,多加一列对应每个发货地的发货量。
每个格子里有两个数,一个是已知的这个发货地给对应收货地点发货的费用单价dij,另外一个是要求的发货量xij。
收货地1 |
收货地2 |
收货地3 |
收货地4 |
总发货量 |
|
发货1 |
单位运价为 9 |
18 |
1 |
9 |
9 |
发货2 |
11 |
6 |
8 |
18 |
10 |
发货3 |
14 |
12 |
2 |
16 |
6 |
总收货量 |
4 |
9 |
7 |
5 |
供需平衡都是25 |
最小元素法的思想是找到运价最低的一个地方,优先给那里发货。就这么简单
输入:sNum,Rnum, 行数和列数
s[] , r[]总发货量和总收货量
d[][]单位费用数组
输出:
x[] []最后的结果
算法用到辅助变量ok[][] 这个地方已经确定发货量,初始都是0
算法:1)、如果R[j] = 0, 那么ok[k][j] = 1;k = 1, 2, sNum;
如果S[i] = 0, 那么ok[i][k] = 1;k = 1,2,rNum;
2)、如果所有ok[][]都是1 那么Ok计算结束
3)、遍历d[][];找到没有Ok地方里面最小费用的那个行位置和列位置 i, j;
4)、得X[I][J] = min(S[i], R[j]);
S[i] -= X[i][j];
R[j] -= X[i][j];
5)、转1)重新执行。
下面给出代码
typedef std::vector<double> VecDoubleType;
typedef std::vector<bool> VecBoolType;
const double g_dTol = 1.0E-3;/***********************************vecS *vecE *vecD *vecX 最后结果,***********************************/static void Cal(VecDoubleType vecS, VecDoubleType vecR, const VecDoubleType &vecD, VecDoubleType &vecX){const VecDoubleType::size_type iSSize = vecS.size(), iRSize = vecR.size(), iDSize = vecD.size();assert(iSSize * iRSize == iDSize);vecX.clear();VecBoolType vecOk;// 初始化VecDoubleType::size_type i = 0, j = 0;for (i = 0; i != iDSize; i++){vecOk.push_back(false);vecX.push_back(0.0);}while(true){CheakOk(vecS, vecR, vecOk);if (AllOk(vecOk)){break;}// 找到最小的距离VecDoubleType::size_type iMin = iSSize, jMin = iRSize;double dMinDis = 1.0E7;for (i = 0; i != iSSize; i++){for (j = 0; j != iRSize; j++){if (!vecOk[i * iRSize +j]){if (vecD[i * iRSize + j] - dMinDis < g_dTol){iMin = i;jMin = j;dMinDis = vecD[i * iRSize + j];}}}}assert(iMin != iSSize && jMin != iRSize);double dMinItem = min(vecS[iMin], vecR[jMin]);vecX[iMin * iRSize + jMin] = dMinItem;vecS[iMin] -= dMinItem;vecR[jMin] -= dMinItem;vecOk[iMin * iRSize + jMin] = true;}std::vector<VecDoubleType>::size_type iDIndex = 0;}static bool AllOk(const VecBoolType &vecOk){bool bAllOk = true;VecBoolType::size_type iBoolSize = vecOk.size(), i = 0;for (i = 0; i != iBoolSize; i++){if (!vecOk[i]){bAllOk = false;break;}}return bAllOk;}static void CheakOk(const VecDoubleType &vecS, const VecDoubleType &vecR, VecBoolType &vecOk){const VecDoubleType::size_type iSSize = vecS.size(), iRSize = vecR.size();VecDoubleType::size_type i = 0, j = 0;// 如果这个发送点的发送量已经为0了,那么这一行都Okfor (i = 0; i != iSSize; i++){if (vecS[i] < g_dTol){for (j = 0; j != iRSize; j++){vecOk[i * iRSize + j] = true;}}}// 如果这个接收点的待接收量减为0了,那么这一列都Ok,for (j = 0; j != iRSize; j++){if (vecR[j] < g_dTol){for (i = 0; i != iSSize; i++){vecOk[i * iRSize + j] = true;}}}}
测试程序
VecDoubleType vecS, vecR, vecD, vecX;vecS.push_back(9.0);vecS.push_back(10.0);vecS.push_back(6.0);vecR.push_back(4.0);vecR.push_back(9.0);vecR.push_back(7.0);vecR.push_back(5.0);vecD.push_back(9.0);vecD.push_back(18.0);vecD.push_back(1.0);vecD.push_back(9.0);vecD.push_back(11.0);vecD.push_back(6.0);vecD.push_back(8.0);vecD.push_back(18.0);vecD.push_back(14.0);vecD.push_back(12.0);vecD.push_back(2.0);vecD.push_back(16.0);
Cal(vecS, vecR, vecD, vecX);
// 输入:// 9 18 1 9 9// 11 6 8 18 10// 14 12 2 16 6//// 4 9 7 5//// 输出为 0,0,7,2,1,9,0,0,3,0,0,3 不是最优,下面的结果 150是最优,// 3 0 1 5// 1 9 0 0// 0 0 6 0// //
上面解出的结果不是最优解,只是一个可行解,如果要得到最优解需要继续进行计算,计算方法有位势法和活路法,算法很复杂没有写出来。
但是用另外一种差额法也可以得到基本可行解,而且效果比最小元素法要好。对于上面的列子能直接得到最优解。
运输问题基本解 最小元素法相关推荐
- 最小元素法求运输问题初始可行解
实验内容:利用Matlab编程,利用最小元素法求运输问题的初始解. 产销地 B1 B2 B3 B4 产量 A1 2 9 10 7 9 A2 1 3 4 2 5 A3 8 4 2 5 7 销量 3 8 ...
- 【运筹学】运输规划、表上作业法总结 ( 运输规划模型 | 运输规划变量个数 | 表上作业法 | 最小元素法 | 差额 Vogel 法 ★ | 闭回路法 ) ★★★
文章目录 一.运输规划模型 1.产销平衡模型 2.产销不平衡模型 二.运输规划数学模型变量个数 三.表上作业法 四.表上作业法 : 求初始基可行解 1.最小元素法 2.差额法 ( Vogel ) 推荐 ...
- 【运筹学】表上作业法 ( 最小元素法分析 | Vogel 方法 )
文章目录 一." 最小元素法 " 分析 二.Vogel 方法 ( 差额法 ) 一." 最小元素法 " 分析 在上一篇博客 [运筹学]表上作业法 ( 求初始基可行 ...
- 【运筹学】表上作业法 ( 求初始基可行解 | 最小元素法 )
文章目录 一.表上作业法 第一步 : 确定初始基可行解 二.最小元素法 一.表上作业法 第一步 : 确定初始基可行解 运输问题如下 : 下面的表格代表 333 个产地 , 444 个销地 的运输规划问 ...
- 【运筹学】表上作业法 ( 示例 | 使用 “ 最小元素法 “ 找初始基可行解 )
文章目录 一.运输规划问题 二.找初始基可行解 一.运输规划问题 运输规划问题 : B1\rm B_1B1 B1\rm B_1B1 B1\rm B_1B1 B1\rm B_1B1 产量 A1\ ...
- c语言实现运输问题表上作业法,运输问题的表上作业法
<运输问题的表上作业法>由会员分享,可在线阅读,更多相关<运输问题的表上作业法(15页珍藏版)>请在装配图网上搜索. 1.2020/9/25,Chapter 06 中文资料运输 ...
- 分治法求数组中的最大最小元素
#include<iostream> using namespace std; //分而治之法求数组中的最大最小元素 void maxmin(int i,int j,int A[],int ...
- 程序员面试题精选100题(42)-旋转数组的最小元素[算法]
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的 ...
- 剑指offer:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
剑指offer算法题 二分查找,旋转数组最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组[3, ...
- LeetCode每日一题--有序队列(整理最小表示法)
题目要求: 给定一个字符串 s 和一个整数 k .你可以从 s 的前 k 个字母中选择一个,并把它加到字符串的末尾. 返回 在应用上述步骤的任意数量的移动后,字典上最小的字符串 . 示例 1: 输入: ...
最新文章
- mysql 浏览器可视窗口_浏览器窗口的可视区域大小指的是哪里?
- python正则表达regex_Python 正则表达式(RegEx)
- Redis 是属于多线程还是单线程?
- 安装Mediamanager 后Messenger后无法登录
- john工具破解密码(Linux、ZIP等)
- keras笔记-模型保存以及tensorboard的使用
- apache缺省banner_NSFOCUS建议您采取以下措施以降低威胁: * 修改源代码或者配置文件改变SSH服务的缺省banner。...
- 如何使用 Apple Watch 拨打电话?
- STL源码剖析(侯捷)笔记——STL概述
- SQL Server活动监视器
- STM32L476+STM32cubeMx+Freemodbus移植记录
- Gradle慢需要6min 现在20s解决了。
- 微信支付--网页版-V3-(1)
- 串口通信协议(基于面试),与及树莓派与电脑之间串口通信
- 8万字208道Java经典面试题总结(附答案)
- 学着搭建流媒体服务器
- 按照物种丰度对OTU表格进行拆分-丰富和稀有物种识别
- 英语基础知识:定语使用规则下篇
- OSV 智能桌面虚拟化_教育桌面云解决方案
- 31省份推出40万亿投资蓝图 新基建、公共卫生成亮点