展开全部

产销不平衡用NBPSProcedure,平衡用BPSProcedure

public class ProductSaleBTProb {

public static void main(String[] args) {

float[][] costMatrix=new float[][]{{1.5f,2f,0.3f,3f},{7f,0.8f,1.4f,2f},{1.2f,0.3f,2f,2.5f}};

/*

* 测试行、62616964757a686964616fe58685e5aeb931333330336362列位势方法

float[][] ASMatrix=new float[6][7];

ASMatrix[0]=new float[]{20f,0f,80f,0f,0f,0f,0f};

ASMatrix[1]=new float[]{0f,70f,0f,10f,0f,0f,0f};

ASMatrix[2]=new float[]{30f,0f,0f,20f,0f,0f,0f};

doLCPosiPower(costMatrix, ASMatrix, 3, 4);

for(int i=0;i<6;i++){

System.out.println(Arrays.toString(ASMatrix[i]));

}

*/

/*

* 测试pw为产地产量,sw为销售地效率,费用矩阵costMatrix

*/

int[] pw=new int[]{100,80,50};

int[] sw=new int[]{50,70,80,30};

int[] rv=BPSProcedure(costMatrix, 3, 4, pw, sw);

for(int i=0;i

System.out.print("编号"+rv[i]+"的产地,向编号"+rv[i+1]+"的销地运输:"+rv[i+2]+"\n");

}

/*

*产销不平衡测试

costMatrix=new float[][]{{4f,2f,5f},{3f,5f,3f},{1f,3f,2f}};

int[] pw=new int[]{8,7,4};

int[] sw=new int[]{4,8,5};

int[] rv=NBPSProcedure(costMatrix, 3, 3, pw, sw);

for(int i=0;i

System.out.print("编号"+rv[i]+"的产地,向编号"+rv[i+1]+"的销地运输:"+rv[i+2]+"\n");

}

*/

}

//产销平衡运输费用最低问题,保证pw和sw相等

//costMatrix为费用矩阵,pnum为产地个数,即costMatrix的行数,snum为销地个数,即costMatrix的列数

//pw表示不同产地产量,sw表示不同销地销量,由于是float浮点运算,保留2位小数

//返回值没三位表示一个信息,比如{...,0,1,40,1,2,60..}表示编号0的产地向编号1的销售地运输40,编号1的产地向编号2的销售地运输60,

public static int[] BPSProcedure(float[][] costMatrix,int pnum,int snum,int[] pw,int[] sw){

int i,j;

//构造一个分配矩阵,增加3行3列,增加的第1行列表示分配的和,第2行列表示行列差,第3行列表示行、列位势

float[][] ASMatrix=new float[pnum+3][snum+3];

int tmpsum=0;//记录初始解是否分配完毕,

while(tmpsum

//运用行、列差值法分别求行、列差,对即没有给运量又没有打叉的进行统计

float min1=0,min2=0;

for(i=0;i

//该行打叉则跳过

if(ASMatrix[i][snum+1]==-1)continue;

min1=0;min2=0;

for(j=0;j

//如果ij有运量或者已经该行或该列打叉则不统计

if(ASMatrix[i][j]>0||ASMatrix[pnum+1][j]==-1)

continue;

else if(min1==0)min1=costMatrix[i][j];

else if(min2==0){

if(min1>costMatrix[i][j]){

min2=min1;

min1=costMatrix[i][j];

}else

min2=costMatrix[i][j];

}else{

if(!(min2>costMatrix[i][j])) continue;

else if(!(min1>costMatrix[i][j]))

min2=costMatrix[i][j];

else{

min2=min1;

min1=costMatrix[i][j];

}

}

}

if(min2!=0)//如果min2有值,则计算差额

ASMatrix[i][snum+1]=Math.round((min2-min1)*100)/100f;

else

ASMatrix[i][snum+1]=min1;

}

for(j=0;j

//该列打叉则跳过

if(ASMatrix[pnum+1][j]==-1)continue;

min1=0;min2=0;

for(i=0;i

//如果有运量或者该行打叉则跳过

if(ASMatrix[i][j]>0||ASMatrix[i][snum+1]==-1)

continue;

else if(min1==0) min1=costMatrix[i][j];

else if(min2==0){

if(min1>costMatrix[i][j]){

min2=min1;

min1=costMatrix[i][j];

}else

min2=costMatrix[i][j];

}else{

if(!(min2>costMatrix[i][j])) continue;

else if(!(min1>costMatrix[i][j]))

min2=costMatrix[i][j];

else{

min2=min1;

min1=costMatrix[i][j];

}

}

}

if(min2!=0)

ASMatrix[pnum+1][j]=Math.round((min2-min1)*100)/100f;

else

ASMatrix[pnum+1][j]=min1;

}

//找出没有被标记为-1的行、列差额最大的并按照满足一方最大分配,当分配数和等于最大值时对应行列差标记为-1,循环进行,直到分完

float lcpospowmax=-1;

int lindex=-1,cindex=-1;

for(i=0;i

if(ASMatrix[i][snum+1]==-1)continue;

if(ASMatrix[i][snum+1]!=-1&&lcpospowmax

lcpospowmax=ASMatrix[i][snum+1];

lindex=i;

}

}

for(j=0;j

if(ASMatrix[pnum+1][j]==-1)continue;

if(ASMatrix[pnum+1][j]!=-1&&lcpospowmax

lcpospowmax=ASMatrix[pnum+1][j]; cindex=j;

}

}

float mincost=0;

//在列上找到最大值

if(cindex!=-1){

lindex=-1;

for(i=0;i

//如果该位置有运量或者被叉掉则不在统计之内

if(ASMatrix[i][cindex]>0||ASMatrix[i][snum+1]==-1)

continue;

else if(mincost==0){

mincost=costMatrix[i][cindex];

lindex=i;

}else{

if(mincost>costMatrix[i][cindex]){

mincost=costMatrix[i][cindex];

lindex=i;

}

}

}

//最终找到lindex、cindex对应格子分配,尽量满足一方

//ASMatrix[pnum][cindex]表示第cindex已经分配数、ASMatrix[lindex][snum]表示已经供应的数量

//需求量和分配量之间的关系,分配后标记每行、列和的格子也相应加上

if((sw[cindex]-ASMatrix[pnum][cindex])

ASMatrix[lindex][cindex]=Math.round((sw[cindex]-ASMatrix[pnum][cindex])*100)/100f;

ASMatrix[pnum+1][cindex]=-1;//该列已经分配完毕

}else if((sw[cindex]-ASMatrix[pnum][cindex])>(pw[lindex]-ASMatrix[lindex][snum])){

ASMatrix[lindex][cindex]=Math.round((pw[lindex]-ASMatrix[lindex][snum])*100)/100f;

ASMatrix[lindex][snum+1]=-1;

tmpsum++;//该行生产量分配完毕

}else{

ASMatrix[lindex][cindex]=pw[lindex]-ASMatrix[lindex][snum];

ASMatrix[lindex][snum+1]=-1;

ASMatrix[pnum+1][cindex]=-1;

tmpsum++;

}

ASMatrix[lindex][snum]=Math.round((ASMatrix[lindex][snum]+ASMatrix[lindex][cindex])*100)/100f;

ASMatrix[pnum][cindex]=Math.round((ASMatrix[pnum][cindex]+ASMatrix[lindex][cindex])*100)/100f;

}else if(lindex!=-1){

mincost=0;

cindex=-1;

for(j=0;j

if(ASMatrix[lindex][j]>0||ASMatrix[pnum+1][j]==-1)

continue;

else if(mincost==0){

mincost=costMatrix[lindex][j];

cindex=j;

}else{

if(mincost>costMatrix[lindex][j]){

mincost=costMatrix[lindex][j];

cindex=j;

}

}

}

//最终找到lindex、cindex对应格子分配

if((sw[cindex]-ASMatrix[pnum][cindex])

ASMatrix[lindex][cindex]=Math.round((sw[cindex]-ASMatrix[pnum][cindex])*100)/100f;

ASMatrix[pnum+1][cindex]=-1;//该列已经分配完毕

}else if((sw[cindex]-ASMatrix[pnum][cindex])>(pw[lindex]-ASMatrix[lindex][snum])){

ASMatrix[lindex][cindex]=Math.round((pw[lindex]-ASMatrix[lindex][snum])*100)/100f;

ASMatrix[lindex][snum+1]=-1;

tmpsum++;//该行生产量分配完毕

}else{

ASMatrix[lindex][cindex]=pw[lindex]-ASMatrix[lindex][snum];

ASMatrix[lindex][snum+1]=-1;

ASMatrix[pnum+1][cindex]=-1;

tmpsum++;

}

ASMatrix[lindex][snum]=Math.round((ASMatrix[lindex][snum]+ASMatrix[lindex][cindex])*100)/100f;

ASMatrix[pnum][cindex]=Math.round((ASMatrix[pnum][cindex]+ASMatrix[lindex][cindex])*100)/100f;

}

}

//至此,用行列差法找到了初始分配方案ASMatrix[i][j]==0表示叉去的格子,i

boolean findSolu=false;

int tmp1=0;

for(i=0;i

for(j=0;j

if(ASMatrix[i][j]>0)

tmp1+=1;

}

if(tmp1

findSolu=true;

while(!findSolu){

//位势法求Rij,如果能找到<0的说明要调整,否则找到最优解

doLCPosiPower(costMatrix,ASMatrix,pnum,snum);

//Rij=cij-(ui+vj);对于分派矩阵中空格计算Rij

float rijmin=0;//存放最小的空格校验值

int rijminl=-1,rijminc=-1;

for(i=0;i

for(j=0;j

if(!(ASMatrix[i][j]>0)&&((costMatrix[i][j]-ASMatrix[i][snum+2]-ASMatrix[pnum+2][j])

rijmin=Math.round((costMatrix[i][j]-ASMatrix[i][snum+2]-ASMatrix[pnum+2][j])*100)/100f;

rijminl=i;rijminc=j;

}

}

}

//如果校验值小于0,则用闭回路进行调整

if(rijmin<0){

//找闭回路,

int rijminOVl=-1,rijminOVc=-1;//rijmin对应点的闭回路的顶点的i、j

boolean find=false;

//向右边上下找

for(j=rijminc+1;j

if(ASMatrix[rijminl][j]>0){

for(i=rijminl+1;i

if(ASMatrix[i][rijminc]>0&&(ASMatrix[i][j]>0)){

rijminOVl=i;rijminOVc=j;

find=true;

break;

}

}

for(i=rijminl-1;i>=0;i--){

if(ASMatrix[i][rijminc]>0&&(ASMatrix[i][j]>0)){

rijminOVl=i;rijminOVc=j;

find=true;

break;

}

}

}

}

//向左边上下找

for(j=rijminc-1;j>=0&&!find;j--){

if(ASMatrix[rijminl][j]>0){

for(i=rijminl+1;i

if(ASMatrix[i][rijminc]>0&&(ASMatrix[i][j]>0)){

rijminOVl=i;rijminOVc=j;

find=true;

break;

}

}

for(i=rijminl-1;i>=0;i--){

if(ASMatrix[i][rijminc]>0&&(ASMatrix[i][j]>0)){

rijminOVl=i;rijminOVc=j;

find=true;

break;

}

}

}

}

//记录rijmin闭回路相邻点中最小的,并调整分派矩阵

float minW=ASMatrix[rijminl][rijminOVc]

ASMatrix[rijminl][rijminOVc]:ASMatrix[rijminOVl][rijminc];

ASMatrix[rijminl][rijminOVc]=Math.round((ASMatrix[rijminl][rijminOVc]-minW)*100)/100f;

ASMatrix[rijminOVl][rijminc]=Math.round((ASMatrix[rijminOVl][rijminc]-minW)*100)/100f;

ASMatrix[rijminOVl][rijminOVc]=Math.round((ASMatrix[rijminOVl][rijminOVc]+minW)*100)/100f;

ASMatrix[rijminl][rijminc]=minW;

}else

findSolu=true;

}

List rv=new ArrayList();

for(i=0;i

for(j=0;j

if(ASMatrix[i][j]>0){

rv.add(i);

rv.add(j);

rv.add((int)ASMatrix[i][j]);

}

}

int[] tmprv=new int[rv.size()];

for(i=0;i

tmprv[i]=rv.get(i);

}

return tmprv;

}

//根据分配矩阵和费用矩阵求出分配矩阵中的行、列位势,pnum+2、sunm+2表示行、列位势在ASMatrix中的位置

//由于方程组都是cij=ui+vj的形式,根据矩阵可以逐行逐列求解。

public static void doLCPosiPower(float[][] costMatrix,float[][] ASMatrix,int pnum,int snum){

int ansnum=0,lp=snum+2,cp=pnum+2;//lp列位置,cp行位置

boolean[] bs=new boolean[pnum+snum];//0..pnum-1为行位势

ASMatrix[0][lp]=0;//令u0=0

bs[0]=true;

ansnum+=1;

int i,j;

while(ansnum

for(i=0;i

for(j=0;j

if(ASMatrix[i][j]>0&&bs[pnum+j]){

ASMatrix[i][lp]=Math.round((costMatrix[i][j]-ASMatrix[cp][j])*100)/100f;

ansnum+=1;

bs[i]=true;

}

}

if(!bs[i])continue;

for(j=0;j

if(ASMatrix[i][j]>0&&!bs[pnum+j]){

ASMatrix[cp][j]=Math.round((costMatrix[i][j]-ASMatrix[i][lp])*100)/100f;

ansnum+=1;

bs[pnum+j]=true;

}

}

}

}

}

/*

* 产销不平衡,把它增加产地或者销地转化为平衡问题

* costMatrix费用矩阵,pnum产地个数,snum销地个数

*/

public static int[] NBPSProcedure(float[][] costMatrix,int pnum,int snum,int[] pw,int[] sw){

int pwsum=0,swnum=0;

int i,j;

for(i=0;i

pwsum+=pw[i];

for(i=0;i

swnum+=sw[i];

//产大于销 增加一个销地,单位费用为0

int[] rv;

if(pwsum>swnum){

float[][] nCostMatrix=new float[pnum][snum+1];

for(i=0;i

for(j=0;j

nCostMatrix[i][j]=costMatrix[i][j];

for(i=0;i

nCostMatrix[i][snum]=0f;

int[] nsw=new int[snum+1];

for(i=0;i

nsw[i]=sw[i];

nsw[snum]=pwsum-swnum;

rv=BPSProcedure(nCostMatrix, pnum, snum+1, pw, nsw);

}

//销大于产 增加一个产地

else if(pwsum

float[][] nCostMatrix=new float[pnum+1][snum];

for(i=0;i

for(j=0;j

nCostMatrix[i][j]=costMatrix[i][j];

for(j=0;j

nCostMatrix[pnum][j]=0f;

int[] npw=new int[pnum+1];

for(i=0;i

npw[i]=pw[i];

npw[pnum]=swnum-pwsum;

rv=BPSProcedure(nCostMatrix, pnum+1, snum, npw, sw);

}else

rv=BPSProcedure(costMatrix, pnum, snum, pw, sw);

return rv;

}

}

本回答由提问者推荐

已赞过

已踩过<

你对这个回答的评价是?

评论

收起

如何实现产销平衡_java语言实现产销平衡和产销不平衡问题的代码相关推荐

  1. java定义说话方法_类定义的基本形式_Java语言程

    类定义的基本形式_Java语言程 4.2.1 类定义的基本形式 前面一节我们已经了解了类和对象的概念,然而在实际编程过程中,该如何定义一个类以及类中的对象呢? 在Java语言中,用户自己可以定义一个类 ...

  2. java中对象清空值_对象的引用和清除_Java语言程

    对象的引用和清除_Java语言程 4.3.3 对象的引用和清除 在创建了类的对象后,就可以使用对象.即对象使用的原则是"先创建后使用". 使用对象的方法是:通过运算符". ...

  3. java枚举类构造方法默认是,枚举类型的构造方法_Java语言程

    枚举类型的构造方法_Java语言程 6.6.4 枚举类型的构造方法 枚举类型既然是类,那么就可以有构造方法.只不过只能是私有的(private),不能有公有的(public)构造方法,这是为了避免直接 ...

  4. 简单的java图形_简单图形的输出_Java语言程

    简单图形的输出_Java语言程 3.5.4 简单图形的输出 [例3-26] 编程显示以下图形(共N行,N由键盘输入). 程序运行结果:略. 分析与思考:(1)设N=5 第1行 4个空格=5-1 1个& ...

  5. java 类中有几种访问权限_类中成员的访问权限_Java语言程

    类中成员的访问权限_Java语言程 4.7.2 类中成员的访问权限 Java将类中成员(成员变量和成员方法)的访问权限(可见性)划分为4种情况,按照访问权限的范围大小从小到大列出如下. ·私有(pri ...

  6. java穷举法解方程_枚举法(穷举法)_Java语言程

    枚举法(穷举法)_Java语言程 3.5.1 枚举法(穷举法) 枚举法就是把所有可能的情况一一测试,筛选出符合条件的各种结果进行输出. [例3-20] 百元买百鸡:用一百元钱买一百只鸡.已知公鸡5元/ ...

  7. Java中包装类型的作用_基本类型的包装类_Java语言程

    基本类型的包装类_Java语言程 6.3 基本类型的包装类 在Java中,每一种基本数据类型都有一个相应的包装类,这些类都在java.lang包中.8种基本数据类型所对应的包装类是:byte(Byte ...

  8. Java jni 底层_JAVA语言语言调用底层语言的技术JNI解析

    本文主要向大家介绍了JAVA语言语言调用底层语言的技术JNI解析,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. java语言调用底层语言的技术JNI解析. Java代码执行步骤 JN ...

  9. c语言控制台光标的坐标范围,C语言之实现控制台光标随意移动的实例代码

    原理引入windows.h,首先是要获得输入的东西,然后通过判断: 1.方向键:执行上下左右的移动功能 2 .回车键:执行换行的功能. 3.普通键:输入功能. 终点就是要获取到屏幕上的坐标,当按下了方 ...

最新文章

  1. mysql数据库名虚拟机_linux虚拟机上装mysql数据库
  2. 蓝牙Bluetooth技术小知识
  3. 解决/WEB-INF目录下的jsp页面引入webRoot下的Js、css和图片的问题
  4. oracle身份证号substr,Oracle substr()与substrb()
  5. 反解析Navicat ncx加密后的密码(并导入到dbeaver)
  6. 如何在docker中运行MySQL实例(转载)
  7. 线上python课程一般多少钱-专业Python实战课程|学习Python需要多少钱?
  8. 开源 免费 java CMS - FreeCMS1.5-数据对象-info
  9. 数据挖掘比赛笔记总结
  10. matlab 对自定义函数求导,用matlab对多项式函数求导
  11. 个推大数据:3月线上消费率先恢复,在线购物APP迎来春天
  12. uniapp 登录页跳转到首页
  13. 安卓逆向_6 --- Dalvik 字节码、Smali 详解
  14. Python题目辅导-题目及其题目
  15. 怎么计算机械连接的工程量,传力杆套筒工程量怎么算
  16. ebx 与 ebp的作用 ---- 总线接口部件
  17. 【转】利用Windows API调用摄像头
  18. 人脸识别App面临的安全风险
  19. 8.Spring学习笔记_使用外部属性文件(by尚硅谷_佟刚)
  20. 北上广深之外,互联网经济也在杭州成都西安武汉异军突起

热门文章

  1. HTML5 Canvas圆盘抽奖应用DEMO演示
  2. VUEElement综合案例
  3. twemproxy explore
  4. 怎样使网页页面变黑白
  5. github上有什么好的node.js的项目?
  6. IDEA运行Run和services
  7. 井里有一只蜗牛,他白天往上爬5米,晚上掉3.5 米,井深56.7米,计算蜗牛需要多少天才能从井底到爬出来
  8. HTML语言制作知识竞猜页面,100道基于Web标准的网页设计与制作试题及答案
  9. android ims注册流程,ims注册流程volte通话流程总结
  10. 关于图灵测试和中文屋Chinese room的理解