表上作业法的源代码

合集下载

表上作业法

表上作业法
最优解
调整:找到新的调运方案
方法:闭回路法
➢闭回路法
基本思想:确定换入、换出变量。在闭回路上 采用“奇加偶减”调整运量xij,闭回路以外xij
不变。
方法要点:
换入变量:最小负检验数对应的非基变量; 换出变量:以换入变量为起点找到相应的闭回路,回路 上其它顶点为基变量,偶数顶点上最小的xij所对应的基变 量就是换出变量,这个最小的xij的值就是调整量; 调整方法:闭回路上,奇数顶点上xij加上调整量,偶数顶 点上xij减去调整量;闭回路以外的点对应的xij不变。
产地 销 地 B 1
A1
-4
2
3

A2
13
A3
78
销量
3
B2 95
3 -1

43
8
B3 3 10 1 4
24 4
B4
产量
7 41 9
2 25 5
35
7
6
产地
销地
A1 A2 A3 销量
B1
23
1
8
3
B2 95 3
43
8
B3 10 4 24 4
B4
71
25
5
6
产量 9 5 7
4.2 表上作业法
▪算法思想
与单纯形法一样,最优解在基本可行解中产生。 但基于模型的特征,初始基本可行解是通过分析单位运价表, 首先满足局部最优,然后通过调整(迭代)使整体达到最优。
-------单纯形法的简化方法
▪算法流程及要点
初始调运方案
检验数ij0 ? N
Y 最优解
调整:找到新的调运方案
B3 3 10 24
24 4

运输问题的求解方法(过程)——表上作业法的解题思路和原理、具体步骤。

运输问题的求解方法(过程)——表上作业法的解题思路和原理、具体步骤。

运输问题的求解方法(过程)——表上作业法的解题思路和原理、具体步骤。

运输问题是一种常见的工业应用问题,涉及到如何安排运输工具和货物,以最小化总成本或最大化利润。

表上作业法(Tableau Programming)是解决运输问题的一种有效方法,其解题思路和原理、具体步骤如下:1. 确定问题的状态在表上作业法中,我们需要先确定问题的状态。

状态是指某个特定时间段内,某个运输问题需要满足的条件。

例如,在一个例子中,我们可以将运输问题的状态定义为“需要从A城市运输货物到B城市,运输工具数量为3,运输距离为100公里”。

2. 定义状态转移方程接下来,我们需要定义状态转移方程,以描述在不同状态下可能采取的行动。

例如,在这个问题中,我们可以定义一个状态转移方程,表示当运输工具数量为2时,货物可以运输到B城市,而运输距离为80公里。

3. 确定最优解一旦我们定义了状态转移方程,我们就可以计算出在不同状态下的最优解。

例如,在这个问题中,当运输工具数量为2时,货物可以运输到B城市,运输距离为80公里,总成本为200元。

因此,该状态下的最优解是运输距离为80公里,运输工具数量为2,总成本为200元。

4. 确定边界条件最后,我们需要确定边界条件,以确保问题的状态不会无限制地变化。

例如,在这个问题中,当运输工具数量为3时,运输距离为120公里,超过了B城市的运输距离范围。

因此,我们需要设置一个限制条件,以确保运输工具数量不超过3,且运输距离不超过120公里。

表上作业法是一种简单有效的解决运输问题的方法,其原理和具体步骤如下。

通过定义状态转移方程、确定最优解、确定边界条件,我们可以计算出问题的最优解,从而实现最小化总成本和最大化利润的目标。

物流 表上作业法与图上作业法

物流 表上作业法与图上作业法

1
A13 5
(3)
(1)
1
4
B1
2
(1)
4
B2
3
该是收点数+发点数-1。图上作 1 业法要求在流向图上的箭头数( 有调运量的边数)也应为收点数 +发点数-1。这一要求也可以等 (1) 2 价地表述为:在去线破圈后得到 的不成圈的交通图上,要求每边 都应该有流向。 (2) 3 A2
B3
3
• 因此,某一边无流向时,必须在这一边上添上调运量为0的虚流 向,和其它流向同样对待。按照这一要求,应在A3边上添上虚 流向。于是,再补上去掉的边,得下图:
工地800需求量t2503003504005001800工地800需求量t250300350400500180030025050300运费21001300240022005250420075083006500工地300200400100200250503002131工地300200400100300250502001工地30040020010030025050200运费31001300240022005250430075072006000课后作业销地产地657075销量50455560210无分支不闭合运输回路60303025有分支不闭合运输回路101518022070607590806513011010016017015010080b4b3b2b1a4a2a3a128018031711811816516525234953525520302020有某物资7t由发出点a1a2a3发出发量分别为331t运往收点b1b2b3b4收量分别为2311t收发量平衡交通图如下图问应如何调动才使tkm最小
• 四个销售地,每天的 需求量为:B1:3吨, B2:6吨,B3:5吨, B4:6吨。运价表如 图所示

表上作业法

表上作业法

运输问题的求解方法——表上作业法产销平衡表与单位运价表表上作业法一、产销平衡表与单位运价表运输问题还可用产销平衡表与单位运价表进行描述。

假设某种物资有m个生产地点Ai(i=1,2,…,m),其产量(供应量)分别为ai(i=1,2,…,m),有n个销地Bj(j=1,2,…,n),其销量(需求量)分别为bj(j=1,2,…,n)。

从Ai到Bj运输单位物资的运价(单价)为Cij。

将这些数据汇总可以得到产销平衡表和单位运价表5.3.1。

表5.3.1 产销平衡表与单位运价表二、表上作业法运输这一类特殊问题可用更加简便的求解方法———表上作业法求解,实质仍是单纯形法,步骤如下:(1)确定初始调运方案,即找出初始基可行解,在产销平衡表上给出m+n-1个数字格。

(2)求非基变量的检验数,即在表上计算空格的检验数,判别是否达到最优解:是否存在负的检验数?如果存在负的检验数,则初始调运方案不是最优方案;如果所有检验数都非负,则初始调运方案已经是最优方案了。

如果已经得到最优调运方案,则停止计算,否则转入下一步。

(3)确定换入变量和换出变量,找出新的调运方案(新的基可行解),即在表上用闭回路法进行调整。

(4)重复(1)~(2),直到求出最优解为止。

(一)确定初始可行基的方法⏹最小元素法从单位运价表中最小的运价开始确定供销关系,然后考虑运价次小的,一直到给出初始基可行解为止。

⏹伏格尔法采用最小元素法可能造成其他处的更多浪费,伏格尔法考虑最小运费与次小运费之间的差额,差额越大,就按次小运费调运。

(二)最优解的判别计算非基变量(空格)的检验数,当所有的检验数时,为最优解。

求空格检验数的方法有:⏹闭回路法以某一空格为起点找一条闭回路,用水平或垂直线向前划,每碰到一数字格转900后,继续前进,直到回到起始空格为止。

闭回路如图5.3.1的(a)、(b)、(c)等所示。

从每一个空格出发一定存在并且可以找到唯一的闭回路。

因为,m+n-1个数字格(基变量)对应的系数向量是一个基,任一空格(非基变量)对应的系数向量是这个基的线性组合。

[物流管理]表上作业法

[物流管理]表上作业法

表上作业法什么是表上作业法表上作业法是指用列表的方法求解线性规划问题中运输模型的计算方法。

是线性规划一种求解方法。

当某些线性规划问题采用图上作业法难以进行直观求解时,就可以将各元素列成相关表,作为初始方案,然后采用检验数来验证这个方案,否则就要采用闭合回路法、位势法等方法进行调整,直至得到满意的结果。

这种列表求解方法就是表上作业法。

表上作业法的步骤1、找出初始基本可行解(初始调运方案,一般m+n-1个数字格),用西北角法、最小元素法;(1)西北角法:从西北角(左上角)格开始,在格内的右下角标上允许取得的最大数。

然后按行(列)标下一格的数。

若某行(列)的产量(销量)已满足,则把该行(列)的其他格划去。

如此进行下去,直至得到一个基本可行解。

(2)最小元素法:从运价最小的格开始,在格内的右下角标上允许取得的最大数。

然后按运价从小到大顺序填数。

若某行(列)的产量(销量)已满足,则把该行(列)的其他格划去。

如此进行下去,直至得到一个基本可行解。

注:应用西北角法和最小元素法,每次填完数,都只划去一行或一列,只有最后一个元例外(同时划去一行和一列)。

当填上一个数后行、列同时饱和时,也应任意划去一行(列),在保留的列(行)中没被划去的格内标一个0。

2、求出各非基变量的检验数,判别是否达到最优解。

如果是停止计算,否则转入下一步,用位势法计算;运输问题的约束条件共有m+n个,其中:m是产地产量的限制;n是销地销量的限制。

其对偶问题也应有m+n个变量,据此:σij = c ij− (u i + v j) ,其中前m个计为,前n个计为由单纯形法可知,基变量的σij = 0c ij− (u i + v j) = 0因此u i,v j可以求出。

3、改进当前的基本可行解(确定换入、换出变量),用闭合回路法调整;(因为目标函数要求最小化)表格中有调运量的地方为基变量,空格处为非基变量。

基变量的检验数σij = 0,非基变量的检验数。

《表上作业法》

《表上作业法》

《表上作业法》《表上作业法》是一种求解指派问题的优化算法。

这种算法通过在表格中进行标记和计算,找出最优解或可行解,使得分配问题得到最优质的解决方案。

以下是关于《表上作业法》的详细介绍。

1.背景和目的《表上作业法》是一种针对指派问题的优化算法,旨在寻找最优解或可行解,使得分配问题得到最优质的解决方案。

它是一种常见的数学优化方法,适用于各种类型的分配问题,如任务分配、资源分配和决策制定等。

通过使用《表上作业法》,可以在给定的一组选项中,为每个任务或资源选择最佳的分配方案,以达到最优的效果或目标。

2.方法和步骤《表上作业法》的核心思想是将指派问题转化为表格形式,通过在表格中进行标记和计算,找出最优解或可行解。

《表上作业法》可以在一个给定的任务集合中选择一个任务来完成,使得选择的每个任务的综合评估值最大。

它包括以下步骤:(1)定义问题:首先,要明确指派问题的具体目标、任务集合、每个任务的评估值和约束条件等。

(2)建立表格:根据指派问题的任务集合和评估值,建立一个合适的表格。

表格的行代表各个任务,列代表可用的资源或选择方案。

在表格中,每个单元格表示某个任务在某个资源或选择方案下的评估值。

(3)填表:根据问题的约束条件和每个任务的评估值,填写表格中的各个单元格。

填表过程中要确保表格的可行性,即满足所有约束条件。

(4)寻找最优解:在填好表格后,通过一定的搜索策略,找出使得综合评估值最大的任务分配方案。

(5)输出结果:输出找到的最优解或可行解,分析每个任务被分配的情况以及对应的评估值。

3.应用和优势《表上作业法》适用于各种类型的指派问题,如任务分配、资源分配和决策制定等。

它具有以下优势:(1)直观易懂:《表上作业法》通过表格形式展示问题,使得问题更加直观易懂。

(2)容易实现:《表上作业法》算法流程清晰明了,容易实现,不需要太多的编程技巧。

(3)可扩展性强:《表上作业法》可以扩展到处理大型复杂的问题,可以有效地处理大规模问题。

管理运筹学 第七章 运输问题之表上作业法


最优解的判断与调整
最优解的判断
比较目标函数值,如果当前基础可行解 的目标函数值最优,则该解为最优解。
VS
最优解的调整
如果当前基础可行解不是最优解,需要对 其进行调整。通过比较不同运输路线的运 输费用,对运输量进行优化分配,以降低 总运输费用。
最优解的验证与
要点一
最优解的验证
对求得的最优解进行检验,确保其满足所有约束条件且目 标函数值最优。
01
将智能优化算法(如遗传算法、模拟退火算法等)与表上作业
法相结合,以提高求解效率和精度。
发展混合算法
02
结合多种算法的优势,发展混合算法以处理更复杂的运输问题。
拓展应用范围
03
在保持简单易行的基础上,拓展表上作业法的应用范围,使其
能够处理更多类型的运筹问题。
THANKS FOR WATCHING
果达到最优解,则确定最优解;如果未达到最优解,则确定次优解。
表上作业法的应用范围
总结词
表上作业法适用于解决供销平衡的运输问题,即供应量和需求量相等的情况。
详细描述
表上作业法适用于解决供销平衡的运输问题,即供应量和需求量相等的情况。在这种情况下,可以通过在运输表 格上填入数字来求解最小运输成本。此外,表上作业法还可以用于解决其他类型的线性规划问题,如资源分配问 题、生产计划问题等。
03 表上作业法的求解过程
初始基础可行解的求解
确定初始基础可行解
根据已知的发货地和收货地的供需关系,以及运输能力限制,通 过试算和调整,求得初始的基础可行解。
初始解的检验
检查初始解是否满足非负约束条件,即所有出发地到收货地的运输 量不能为负数。
初始解的调整
如果初始解不满足非负约束条件,需要对运输量进行调整,直到满 足所有约束条件。

第二节运输问题求解表上作业法-精品文档

10
应用西北角法、最小元素法和 Vogel法,每次填完数,都只划去一 行或一列,只有最后一个元例外(同 时划去一行和一列)。当填上一个数 后行、列同时饱和时,也应任意划去 一行(列),在保留的列(行)中没 被划去的格内标一个0。
11
[例 3-2] 某食品公司下属的 A1、A2、 A3 ,3 个厂生产方便食品,要运输到 B1、 B2、B3、B4 ,4 个销售点,数据如下: 表1 B1 B2 A1 3 11 A2 1 9 A3 7 4 销量 bj 3 6 求最优运输方案。 B3 3 2 10 5 B4 产量 ai 10 7 8 4 5 9 6 20(产销平衡)
(1)西 北 角 法 B3 B4 10
产量 ai 7
8 2 5 3 6 6
4
9
销量 bj
3
6
5
20
14
( 2) 最 小 元 素 法 B1 B2 A1 3 11
B3 3 4 10
B4
产 量 ai 7 3
A2
1 3
9
2 1
8
4
A3
7
4 6
10
5 3 5 6
9
销 量 bj
3
6
2015
( 2) 最 小 元 素 法 B1 B2 A1 3 11
(4)若运输平衡表中所有的行与列均被 划去,则得到了一个初始基本可行解。否 则在剩下的运输平衡表中选下一个变量, 转(4)。
4
上述计算过程可用流程图描述如下
取未划去的单元格xij ,令 xij = min { ai , bj }
ai’ = ai - xij bj’ = bj - xij

ai’ = 0?
第二节 运输问题求解 —表上作业法

第二节运输问题求解表上作业法

2
即从 Ai 向 Bj 运最大量(使行或列在 允许的范围内尽量饱和,即使一个约 束方程得以满足),填入 xij 的相应位 置; (2) 从 ai 或 bj 中分别减去 xij 的值,即调整 Ai 的拥有量及 Bj 的需 求量;
3
(3) 若 ai = 0 ,则划去对应的行(把 拥有的量全部运走),若 bj = 0 则划去 对应的列(把需要的量全部运来),且每 次只划去一行或一列(即每次要去掉且只 去掉一个约束);
—表上作业法
我们已经介绍过,可以通过增加虚 设产地或销地(加、减松弛变量)把问 题转换成产销平衡问题。
1.产量大于销量的情况
考虑 si > dj 的运输问题,得到的数学模 型为
i=1 j=1
39
m
n
2.运输问题求解
—表上作业法
Min f =
n m i=1 j=1

n
cij xij
s.t. xij si i = 1,2,…,m
10
应用西北角法、最小元素法和 Vogel法,每次填完数,都只划去一 行或一列,只有最后一个元例外(同 时划去一行和一列)。当填上一个数 后行、列同时饱和时,也应任意划去 一行(列),在保留的列(行)中没 被划去的格内标一个0。
11
表1
12
13
14
15
16
二、基本可行解的最优性检验
最优性检验就是检查所得到的方 案是不是最优方案。 检查的方法----计算检验数 由于目标要求极小,因此,当所 有的检验数都大于或等于零时该调运 方案就是最优方案;否则就不是最优, 需要进行调整。
第二节 运输问题求解 —表上作业法
运输问题的方法 —— 表上作业法: 1、确定一个初始基本可行解; 2 、根据最优性判别准则来检查这 个基本可行解是不是最优的。如果 是则计算结束;如果不是,则至3 3、换基,直至求出最优解为止。

表上作业法的源代码

/* 表上作业法的源代码 */#include ""#include ""#include ""/* #define debug */#define a(j) (*(C+(M-1)*N+j)) /*销量数组*/#define b(i) (*(C+i*N+N-1)) /*产量数组*/#define c(i,j) (*(C+i*N+j)) /*运价数组*/#define x(i,j) (*(X+i*(N-1)+j)) /*运量数组 *//*(<:基本解,>=:运量为0) */#define s(i,j) (*(S+i*(N-1)+j)) /*检验数数组Sij */ #define u(i) (*(U+i)) /*位势数组Ui*/#define v(i) (*(V+i)) /*位势数组Vi*/#define cpi(k) ((CP+k)->i) /*闭回路点i标*/#define cpj(k) ((CP+k)->j) /*闭回路点i标*/#define cpf(k) ((CP+k)->f) /*闭回路点i标*//* f=0:j++; f=2:j--;f=1;i--; f=3:i++; *//*void TP(int M,int N,double *C,double *X); */10 6 300 20 30 40 50 6012 7 14 16 9 10 9 13 8 14183 185 119 162 137 102 179 118 114189 107 169 161 179 169 140 135 112184 149 128 106 165 178 199 183 194127 184 173 124 125 151 127 178 160162 105 150 185 179 153 174 121 142108 163 157 138 189 171 114 131 165150 159 131 155 135 165 124 167 107109 107 149 175 162 108 182 135 181106 136 183 134 179 188 136 131 189166 158 159 180 162 104 116 159 111void main(){int M,N,i,j;double *C; /*存储运价,产量及销量 */double *X; /*存储运量分配方案 */float z;FILE *fp;char fn[80];double sum;void TP(int M,int N,double *C,double *X);printf("please input the data file name: ");scanf("%s",fn);if((fp=fopen(fn,"r"))==NULL){printf("Cannot open the data file!");}fscanf(fp,"%d%d",&M,&N);M++; N++;X=(double *)malloc(sizeof(double)*(M-1)*(N-1));C=(double *)malloc(sizeof(double)*M*N);/* 把运价,供应量和需求量的数据读入到数组c(i,j); *//*---高太光:这里可以直接定义固定的数组c(i,j),也可以从文件读取for(i=0;i<M;i++){for(j=0;j<N;j++){fscanf(fp,"%f",&z);c(i,j)=z;}printf("\n");}fclose(fp);/* output c(i,j); */printf("\n=============Data File================\n");for(i=0;i<M;i++){for(j=0;j<N;j++){printf("%10.3f",c(i,j));}printf("\n");}getch();TP(M,N,C,X);/* 输出产销分配方案; */printf("\n=============Best Solution===================\n"); sum=0;for(i=0;i<M-1;i++){for(j=0;j<N-1;j++){if(x(i,j)>=printf("%10s","******");else{printf("%10.3f",x(i,j));sum+=(x(i,j)*c(i,j));}}printf("\n");}printf("\n\n\tThe min Cost is: %-10.4f\n",sum);getch();}struct PATH{int i,j,f;}; /*记录闭回路点结构*/void TP(int M,int N, double *C,double *X){double *U,*V,*S;int MN1,m,n;struct PATH *CP;int k,i,j,l,k1,l1,ip;double Cmin,sum;int I0,J0,Imin,Jmin;int fi,fj,fc,f;MN1=(M-1)+(N-1)-1;m=M-1;n=N-1;S=(double *)malloc(sizeof(double)*(M-1)*(N-1));U=(double *)malloc(sizeof(double)*M);V=(double *)malloc(sizeof(double)*N);CP=(struct PATH *)malloc(sizeof(struct PATH)*(MN1+1)); #ifdef debugprintf("\nM=%d,N=%d,m=%d,n=%d\n",M,N,m,n);printf("\nb(i)is following:\n");for(i=0;i<m;i++)printf("%8.4f\t",b(i));printf("\na(j)is folowing:\n");for(j=0;j<n;j++)printf("%8.4f\t",a(j));printf("\n");getch();#endif/*解初始化Xij=; */for(i=0;i<m;i++)for(j=0;j<n;j++)x(i,j)=;/*最小元素法求初始可行解 */for(k=0;k<MN1;k++){Cmin=;for(i=0;i<m;i++){fi=0;for(l=0;l<k;l++){/* 去除已经用过的行; */if(i==cpi(l)){fi=1;break;}}if(fi==1)continue;for(j=0;j<n;j++){fj=0;for(l=0;l<k;l++){/* 去除已经用过的列; */if(j==cpj(l)){fj=1;break;}}if(fj==1) continue;if(Cmin>c(i,j)){Cmin=c(i,j);I0=i;J0=j;#ifdef debugprintf("\n now c(i,j)=%8.4f\n",c(i,j));#endif}} /*end for j */}/* end for i *//*得到了未划去的最小运价所在格的坐标(I0,J0)和最小运价Cmin */if(k>0){if(Cmin==&&cpi(k-1)==0){for(l1=0;l1<m;l1++)if(x(l1,cpj(k-1))=={x(l1,cpj(k-1))=0;}}else if(Cmin==&&cpi(k-1)!=0){for(l1=0;l1<n;l1++)if(x(cpi(k-1),l1)=={x(cpi(k-1),l1)=0;}}}if(b(I0)<a(J0)){cpi(k)=I0;cpj(k)=-1;x(I0,J0)=b(I0);#ifdef debugprintf("I0=%d,J0=%d,x(I0,J0)=%8.4f,k=%d,cpi(k)=%d,cpj(k)=%d\n",I0,J0,x(I0,J0),k,cpi(k),cpj(k)); #endifa(J0)-=b(I0);b(I0)=0;}else{cpi(k)=-1;cpj(k)=J0;x(I0,J0)=a(J0);#ifdef debugprintf("I0=%d,J0=%d,x(I0,J0)=%8.4f,k=%d,cpi(k)=%d,cpj(k)=%d\n",I0,J0,x(I0,J0),k,cpi(k),cpj(k)); #endifb(I0)-=a(J0);a(J0)=0;}} /*END FOR K 用最小元素法求得了初使可行解*//*输出初始可行解*/printf("\n=============init Solution===================\n");sum=0;for(i=0;i<M-1;i++){for(j=0;j<N-1;j++){if(x(i,j)>=printf("%10s","******");else{printf("%10.3f",x(i,j));sum+=(x(i,j)*c(i,j));}}printf("\n");}printf("\n\n\tThe Cost is: %-10.4f\n",sum);getch();/***************循环换入换出,直到检验数为非负数*****************************//*循环决定换入变量 */while(1){/*位势置初值Ui,Vi= */for(i=0;i<m;i++)u(i)=;for(j=0;j<n;j++)v(j)=;/*求位势*/l=0;u(0)=0;for(i=0;i<m;i++){for(j=0;j<n;j++){if(u(i)>=&&v(j)>=&&x(i,j)<{cpi(l)=i;cpj(l)=j;l++; /*记录未求过位势的位置*/}else if(x(i,j)<&&u(i)<{v(j)=c(i,j)-u(i);}else if(x(i,j)<&&v(j)<{u(i)=c(i,j)-v(j);}}/*end for j */}/*end for i *//*按记录位置求其余位势*/if(l>0){while(1){ip=0;for(k=0;k<l;k++){i=cpi(k);j=cpj(k);if((u(i)>=&&(v(j)>=&&(x(i,j)<){cpi(ip)=i;cpj(ip)=j;ip++; /*记录未求过位势的位置*/ }else if(x(i,j)<&&u(i)<{v(j)=c(i,j)-u(i);}else if(x(i,j)<&&v(j)<{u(i)=c(i,j)-v(j);}}/*end for k */if(ip==0)break;l=ip;}/*end for while */} /*end if l */#ifdef debugprintf("\nU(i):");for(i=0;i<m;i++){printf("%10.2f",u(i));}printf("\nV(j):");for(j=0;j<n;j++){printf("%10.2f",v(j));}printf("\n");#endif/*求检验数*/for(i=0;i<m;i++){for(j=0;j<n;j++){ s(i,j)=;if(x(i,j)>= s(i,j)=c(i,j)-u(i)-v(j);}}/*求最小检验数*/Cmin=;for(i=0;i<m;i++){for(j=0;j<n;j++){if(Cmin>s(i,j)){Cmin=s(i,j);I0=i;J0=j;}}}#ifdef debugprintf("\ncheck number:\n");for(i=0;i<m;i++){for(j=0;j<n;j++){printf("s(%d,%d)=%-10.2f\n",i,j,s(i,j));}printf("\n");}printf("Smin=%-10.2f",Cmin);getch();#endifif(Cmin>=0) return; /*已经得到最优解,返回主程序*/ /*此时找到了入基变量X(I0,J0) *//*求闭回路*/for(k=0;k<MN1;k++){cpf(k)=-1;}/*end for k */cpi(0)=I0;cpj(0)=J0;k=0;while(1){f=cpf(k);/*设置闭回路搜索方向*/while(1){i=cpi(k);j=cpj(k);fc=0;f++;cpf(k)=f;if(f>=4)break;/*避免反向搜索*/if(k>0){if(f==0&&cpf(k-1)==2) continue;else if(f==1&&cpf(k-1)==3)continue;else if(f==2&&cpf(k-1)==0)continue;else if(f==3&&cpf(k-1)==1)continue;}if(f==0){/*沿J+方向搜索*/while(1){j++;if(j>=n){fc=2;break;}if((i==I0)&&(j==J0)){fc=1;break;}if(s(i,j)>={fc=3;break;}}}/*end j+ */else if(f==1){ /*沿i-方向搜索*/while(1){ i--;if(i<0){fc=2;break;}if((i==I0)&&(j==J0)){fc=1;break;} if(s(i,j)>={fc=3;break;}}}/*end if=1 */else if(f==2){/*沿J-方向搜索*/while(1){j--;if(j<0){fc=2;break;}if((i==I0)&&(j==J0)){fc=1;break;} if(s(i,j)>={fc=3;break;}}} /*end f==2 */else if(f==3){/*沿I+方向搜索*/while(1){i++;if(i>=m){fc=2;break;}if((i==I0)&&(j==J0)){fc=1;break;} if(s(i,j)>={fc=3;break;}}}/*end f==3 */if((fc==1)||(fc==3))break;}/*end while flag 2 */if(fc==0){/*沿些方向搜索失败,退回回到前一点*/ k--;}else if(fc==1)break; /*搜索完成*/else if(fc==3){/*沿此方向搜索成功,前进一点*/k++;cpi(k)=i;cpj(k)=j;#ifdef debugprintf("\n");printf("k=%d,cpi(k)=%d,cpj(k)=%d,cpf(k)=%d,x(i,j)=%8.4f\n",k,cpi(k),cpj(k),cpf(k),x(cpi(k),cpj(k))); getch();#endifcpf(k)=-1;}}/*end while *//*去除闭回路中的非转折点*/l=0;while(l<k-1){ i=l+1;while(i<=k){if(cpf(l)==cpf(i)) i++;else break;}if(i>(l+1)){j=l+1;k1=k-(i-j);/*如果某些点前进方向相同,则去除中间各点*/while(i<=k){cpi(j)=cpi(i);cpj(j)=cpj(i);cpf(j)=cpf(i);i++;j++;}l+=2;k=k1;}else l++;}/*end while l<k-1 *//*查找闭回路上基本解的最小值*/Cmin=x(cpi(1),cpj(1));Imin=cpi(1);Jmin=cpj(1);for(i=3;i<=k;i+=2){if(Cmin>x(cpi(i),cpj(i))){Cmin=x(cpi(i),cpj(i));Imin=cpi(i);Jmin=cpj(i);}}/*换入基变量*/x(I0,J0)=Cmin;for(i=1;i<=k;i+=2){x(cpi(i),cpj(i))-=Cmin;if((i+1)<=k) x(cpi(i+1),cpj(i+1))+=Cmin;}x(Imin,Jmin)=;}free(CP);free(V);free(U);free(S);QUIT: return;}================END====================。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

表上作业法的源代码-标准化文件发布号:(9456-EUATWK-MWUB-WUNN-INNUL-DDQTY-KII/* 表上作业法的源代码 */#include "stdio.h"#include "alloc.h"#include "math.h"/* #define debug */#define a(j) (*(C+(M-1)*N+j)) /*销量数组*/#define b(i) (*(C+i*N+N-1)) /*产量数组*/#define c(i,j) (*(C+i*N+j)) /*运价数组*/#define x(i,j) (*(X+i*(N-1)+j)) /*运量数组 *//*(<1.0E15:基本解,>=1.0E15:运量为0) */#define s(i,j) (*(S+i*(N-1)+j)) /*检验数数组Sij */ #define u(i) (*(U+i)) /*位势数组Ui*/#define v(i) (*(V+i)) /*位势数组Vi*/#define cpi(k) ((CP+k)->i) /*闭回路点i标*/#define cpj(k) ((CP+k)->j) /*闭回路点i标*/#define cpf(k) ((CP+k)->f) /*闭回路点i标*//* f=0:j++; f=2:j--;f=1;i--; f=3:i++; *//*void TP(int M,int N,double *C,double *X); */ 10 6 300 20 30 40 50 6012 7 14 16 9 10 9 13 8 14183 185 119 162 137 102 179 118 114189 107 169 161 179 169 140 135 112184 149 128 106 165 178 199 183 194127 184 173 124 125 151 127 178 160162 105 150 185 179 153 174 121 142108 163 157 138 189 171 114 131 165150 159 131 155 135 165 124 167 107109 107 149 175 162 108 182 135 181106 136 183 134 179 188 136 131 189166 158 159 180 162 104 116 159 111void main(){int M,N,i,j;double *C; /*存储运价,产量及销量 */double *X; /*存储运量分配方案 */float z;FILE *fp;char fn[80];double sum;void TP(int M,int N,double *C,double *X);printf("please input the data file name: "); scanf("%s",fn);{printf("Cannot open the data file!");getch();exit(0);}fscanf(fp,"%d%d",&M,&N);M++; N++;X=(double *)malloc(sizeof(double)*(M-1)*(N-1));C=(double *)malloc(sizeof(double)*M*N);/* 把运价,供应量和需求量的数据读入到数组c(i,j); *//*---高太光:这里可以直接定义固定的数组c(i,j),也可以从文件读取for(i=0;i<M;i++){for(j=0;j<N;j++){fscanf(fp,"%f",&z);c(i,j)=z;}printf("\n");}fclose(fp);/* output c(i,j); */printf("\n=============Data File================\n");for(i=0;i<M;i++){for(j=0;j<N;j++){printf("%10.3f",c(i,j));}printf("\n");}getch();TP(M,N,C,X);/* 输出产销分配方案; */printf("\n=============Best Solution===================\n"); sum=0;for(i=0;i<M-1;i++){for(j=0;j<N-1;j++){if(x(i,j)>=1.0e15)printf("%10s","******");else{printf("%10.3f",x(i,j));sum+=(x(i,j)*c(i,j));}printf("\n");}printf("\n\n\tThe min Cost is: %-10.4f\n",sum);getch();free(X);free(C);}struct PATH{int i,j,f;}; /*记录闭回路点结构*/void TP(int M,int N, double *C,double *X){double *U,*V,*S;int MN1,m,n;struct PATH *CP;int k,i,j,l,k1,l1,ip;double Cmin,sum;int I0,J0,Imin,Jmin;int fi,fj,fc,f;MN1=(M-1)+(N-1)-1;m=M-1;n=N-1;S=(double *)malloc(sizeof(double)*(M-1)*(N-1));U=(double *)malloc(sizeof(double)*M);V=(double *)malloc(sizeof(double)*N);CP=(struct PATH *)malloc(sizeof(struct PATH)*(MN1+1)); #ifdef debugprintf("\nM=%d,N=%d,m=%d,n=%d\n",M,N,m,n);printf("\nb(i)is following:\n");for(i=0;i<m;i++)printf("%8.4f\t",b(i));printf("\na(j)is folowing:\n");for(j=0;j<n;j++)printf("%8.4f\t",a(j));printf("\n");getch();#endif/*解初始化Xij=1.0e15; */for(i=0;i<m;i++)for(j=0;j<n;j++)x(i,j)=1.0e15;/*最小元素法求初始可行解 */for(k=0;k<MN1;k++)Cmin=1.0e15;for(i=0;i<m;i++){fi=0;for(l=0;l<k;l++){/* 去除已经用过的行; */if(i==cpi(l)){fi=1;break;}}if(fi==1)continue;for(j=0;j<n;j++){fj=0;for(l=0;l<k;l++){/* 去除已经用过的列; */if(j==cpj(l)){fj=1;break;}}if(fj==1) continue;if(Cmin>c(i,j)){Cmin=c(i,j);I0=i;J0=j;#ifdef debugprintf("\n now c(i,j)=%8.4f\n",c(i,j));#endif}} /*end for j */}/* end for i *//*得到了未划去的最小运价所在格的坐标(I0,J0)和最小运价Cmin */ if(k>0){if(Cmin==1.0e15&&cpi(k-1)==0){for(l1=0;l1<m;l1++)if(x(l1,cpj(k-1))==1.0e15){x(l1,cpj(k-1))=0;}}else if(Cmin==1.0e15&&cpi(k-1)!=0){for(l1=0;l1<n;l1++)if(x(cpi(k-1),l1)==1.0e15){x(cpi(k-1),l1)=0;}}}if(b(I0)<a(J0)){cpi(k)=I0;cpj(k)=-1;x(I0,J0)=b(I0);printf("I0=%d,J0=%d,x(I0,J0)=%8.4f,k=%d,cpi(k)=%d,cpj(k)=%d\n",I0,J0,x(I0,J0),k,cpi(k),cpj(k)); #endifa(J0)-=b(I0);b(I0)=0;}else{cpi(k)=-1;cpj(k)=J0;x(I0,J0)=a(J0);#ifdef debugprintf("I0=%d,J0=%d,x(I0,J0)=%8.4f,k=%d,cpi(k)=%d,cpj(k)=%d\n",I0,J0,x(I0,J0),k,cpi(k),cpj(k)); #endifb(I0)-=a(J0);a(J0)=0;}} /*END FOR K 用最小元素法求得了初使可行解*//*输出初始可行解*/printf("\n=============init Solution===================\n");sum=0;for(i=0;i<M-1;i++){for(j=0;j<N-1;j++){if(x(i,j)>=1.0e15)printf("%10s","******");else{printf("%10.3f",x(i,j));sum+=(x(i,j)*c(i,j));}}printf("\n");}printf("\n\n\tThe Cost is: %-10.4f\n",sum);getch();/***************循环换入换出,直到检验数为非负数*****************************/ /*循环决定换入变量 */while(1){/*位势置初值Ui,Vi=1.0e15 */for(i=0;i<m;i++)u(i)=1.0e15;for(j=0;j<n;j++)v(j)=1.0e15;/*求位势*/l=0;u(0)=0;for(i=0;i<m;i++){if(u(i)>=1.0e15&&v(j)>=1.0e15&&x(i,j)<1.0e15){cpi(l)=i;cpj(l)=j;l++; /*记录未求过位势的位置*/}else if(x(i,j)<1.0e15&&u(i)<1.0e15){v(j)=c(i,j)-u(i);}else if(x(i,j)<1.0e15&&v(j)<1.0e15){u(i)=c(i,j)-v(j);}}/*end for j */}/*end for i *//*按记录位置求其余位势*/if(l>0){while(1){ip=0;for(k=0;k<l;k++){i=cpi(k);j=cpj(k);if((u(i)>=1.0e15)&&(v(j)>=1.0e15)&&(x(i,j)<1.0e15)) {cpi(ip)=i;cpj(ip)=j;ip++; /*记录未求过位势的位置*/ }else if(x(i,j)<1.0e15&&u(i)<1.0e15){v(j)=c(i,j)-u(i);}else if(x(i,j)<1.0e15&&v(j)<1.0e15){u(i)=c(i,j)-v(j);}}/*end for k */if(ip==0)break;l=ip;}/*end for while */} /*end if l */#ifdef debugprintf("\nU(i):");for(i=0;i<m;i++){printf("%10.2f",u(i));}printf("\nV(j):");for(j=0;j<n;j++){printf("%10.2f",v(j));}printf("\n");#endif/*求检验数*/for(j=0;j<n;j++){ s(i,j)=1.0e15;if(x(i,j)>=1.0e15) s(i,j)=c(i,j)-u(i)-v(j);}}/*求最小检验数*/Cmin=1.0e15;for(i=0;i<m;i++){for(j=0;j<n;j++){if(Cmin>s(i,j)){Cmin=s(i,j);I0=i;J0=j;}}}#ifdef debugprintf("\ncheck number:\n");for(i=0;i<m;i++){for(j=0;j<n;j++){printf("s(%d,%d)=%-10.2f\n",i,j,s(i,j));}printf("\n");}printf("Smin=%-10.2f",Cmin);getch();#endifif(Cmin>=0) return; /*已经得到最优解,返回主程序*/ /*此时找到了入基变量X(I0,J0) *//*求闭回路*/for(k=0;k<MN1;k++){cpf(k)=-1;}/*end for k */cpi(0)=I0;cpj(0)=J0;k=0;while(1){f=cpf(k);/*设置闭回路搜索方向*/while(1){i=cpi(k);j=cpj(k);fc=0;f++;if(f>=4)break;/*避免反向搜索*/if(k>0){if(f==0&&cpf(k-1)==2) continue;else if(f==1&&cpf(k-1)==3)continue; else if(f==2&&cpf(k-1)==0)continue; else if(f==3&&cpf(k-1)==1)continue; }if(f==0){/*沿J+方向搜索*/while(1){j++;if(j>=n){fc=2;break;}if((i==I0)&&(j==J0)){fc=1;break;}if(s(i,j)>=1.0e15){fc=3;break;}}}/*end j+ */else if(f==1){ /*沿i-方向搜索*/while(1){ i--;if(i<0){fc=2;break;}if((i==I0)&&(j==J0)){fc=1;break;} if(s(i,j)>=1.0e15){fc=3;break;}}}/*end if=1 */else if(f==2){/*沿J-方向搜索*/while(1){j--;if(j<0){fc=2;break;}if((i==I0)&&(j==J0)){fc=1;break;} if(s(i,j)>=1.0e15){fc=3;break;}}} /*end f==2 */else if(f==3){/*沿I+方向搜索*/while(1){i++;if(i>=m){fc=2;break;}if((i==I0)&&(j==J0)){fc=1;break;}}}/*end f==3 */if((fc==1)||(fc==3))break;}/*end while flag 2 */if(fc==0){/*沿些方向搜索失败,退回回到前一点*/k--;}else if(fc==1)break; /*搜索完成*/else if(fc==3){/*沿此方向搜索成功,前进一点*/k++;cpi(k)=i;cpj(k)=j;#ifdef debugprintf("\n");printf("k=%d,cpi(k)=%d,cpj(k)=%d,cpf(k)=%d,x(i,j)=%8.4f\n",k,cpi(k),cpj(k),cpf(k),x(cpi(k),cpj(k))); getch();#endifcpf(k)=-1;}}/*end while *//*去除闭回路中的非转折点*/l=0;while(l<k-1){ i=l+1;while(i<=k){if(cpf(l)==cpf(i)) i++;else break;}if(i>(l+1)){j=l+1;k1=k-(i-j);/*如果某些点前进方向相同,则去除中间各点*/while(i<=k){cpi(j)=cpi(i);cpj(j)=cpj(i);cpf(j)=cpf(i);i++;j++;}l+=2;k=k1;}else l++;}/*end while l<k-1 *//*查找闭回路上基本解的最小值*/Cmin=x(cpi(1),cpj(1));Imin=cpi(1);Jmin=cpj(1);{if(Cmin>x(cpi(i),cpj(i))){Cmin=x(cpi(i),cpj(i));Imin=cpi(i);Jmin=cpj(i);}}/*换入基变量*/x(I0,J0)=Cmin;for(i=1;i<=k;i+=2){x(cpi(i),cpj(i))-=Cmin;if((i+1)<=k) x(cpi(i+1),cpj(i+1))+=Cmin;}x(Imin,Jmin)=1.0e15;}free(CP);free(V);free(U);free(S);QUIT: return;}================END====================11。

相关文档
最新文档