java单纯形法_单纯形法 - fjzzq2002 - 博客园
看了集训队答辩,感觉要学习的有杜教筛高级版、线性规划、FFT、仙人掌、高级版线段树
不出意外的话一个月内博客内都不会有别的东西了QAQ
首先是喜闻乐见的单纯形法解线性规划。
今年(2016年)和线性规划有关的集训队论文有两篇,大家可以自行翻一下集训队论文(当然如果你没有拿到你可以去UOJ群下载啊),下面的大部分内容都是参阅akf那篇
线性规划的标准型一般长得像这样:
一般我们拿到的都是像标准型这样的问题,例如网络流问题,我们就是要最大化流量并且让每个点流量守恒。
假设我们把汇点到源点连一条容量为+∞的边那么所有点就都流量守恒了。我们用c(u,v)表示(u,v)这条边的容量,f(u,v)表示这条边的流量。
那么我们不难得到这样的一个标准型线性规划
不难把它转化成标准型这样的模型。
而最小费用流则也是一个标准型,我们还是把汇点到源点加一条容量为+∞,费用为0的边。
那么也可以得到一个比较标准的线性规划:
(较论文中的配文有修改)
如果你要最小费用最大流的话只要加一个约束条件$\sum_{(u,v)}{f(u,v)}=maxflow$
额那不等号怎么办呢?
对于不等约束条件${\sum_{j=1}^n{a_{ij}x_j}}\leq{b_i}$
在松弛型等式左边的那些变量我们把它们叫做基变量,在上面的松弛型表示中就是x[n+1]…x[n+m],非基变量就是在等式右边的那些,在上面的表示中是x[1]…x[n]。
显然当bi非负时令所有基变量为bi,非基变量为0,即可得到一个满足条件的初始解。(至于bi可能为负的情况下面在单独说)
单纯形法有一个重要的操作,叫转轴(pivot)操作。就是说我们可以把一个基变量x[b]和非基变量x[n]互换,用x[b]和其他非基变量代换这个x[n],这样x[b]就成了非基变量,而x[n]成了基变量。
一开始我们知道。
那么简单代换一下会发现,然后我们也可以把其他约束条件中的x[n]这样代换掉,于是就完成了这个转轴操作。
然后有了这个转轴过程的帮助,我们就可以实现线性规划算法了。
首先为了最大化目标函数,我们考虑不停地找一个系数为正的非基变量,然后增大这个x。
具体的这个最优化过程如下:
(注意邹逍遥原论文在这里的做法是选择满足的,ysy告诉我这样是不科学的,akf的论文里写的也是ce>0,于是做了一些修改)
这是为什么呢?akf在论文中给出了一个例子,从中我们可以大概理解一下。
这个线性规划是这样的:
我们考虑第一步我们选择换正系数的x1,因为增大x1必然会增大目标函数。
我们分别考虑三个限制,显然第一个限制下x1<=30,第二个限制下x1<=12,第三个限制x1<=9,然后x1<=9的下界最紧,所以我们用x1代换x6,得到下面的新线性规划:
哇目标函数增大到了27,可喜可贺。
接下来假设我们来增大x3,类似地可以得到:
然后可以增大x2,可以得到:
由于所有非基变量系数均为负的,所以我们不可能再得到更小的解了。
咦,有没有注意到上面漏了什么东西说要下面讲啊…
对了,在bi为负的时候,如果你把所有基变量带0,而非基变量就不一定是一组合法的初始解。
这时候我们就需要一个初始化操作,初始化操作的基本思想是引入一个辅助线性规划:
如果我们求得了这个辅助线性规划的最优解,那么如果最优解中x0>0显然原线性规划无解。
如果最优解中x0=0,那么x[1]…x[n+m]就是原线性规划的一个可行解。
而我们容易构造出辅助线性规划的一个可行解。
我们只要把x0作为换入变量,找到bi的最小值bl,把x[i+l]用x0来替代。
例如:
我们引入辅助线性规划:
bi最小值是-4,那么我们把x4用x0来替代:
然后我们就可以得到一组x的初始解用来进行最优化操作。
讲道理:为什么bi这样之后一定为正?
首先bi的最小值bl一定为负(废话,否则就不用进行最优化操作了)
然后我们考虑第l个约束会变为:
而-bi显然为正的。
而其他约束会变为:
由于bl是最小值,所以bi>=bl,所以-bl+bi>=0。
而我们发现UOJ上似乎有一种更加神奇的初始化方法?
我们的目标显然是让所有系数bi都为非负的。
我们选择一个bi为负的基变量x[i+n],然后我们在该约束右边找一个系数为正的非基变量,然后进行转轴操作,如果没有系数为正显然就无解了。
额其实这和这个初始化操作本质上是一样的。
所以这样就可以完成整个线性规划的过程。
我们来分析一下时间复杂度?
pivot操作的复杂度显然是O(NM)的,但是最优化操作中pivot操作的调用次数可能会成为指数级。
但是我们可以发现要达到这个指数级的调用次数,边权也必须是指数级的。所以在OI中往往跑得比谁都快。所以“能在1s内跑出范围为几百的数据”。
然而一般线性规划是可以在多项式范围内求解的,只不过…
椭球算法 O(n^6*m^2)
内点算法 O(n^3.5*m^2)
改进的内点算法 O(n^3.5*m)
在oi中一般并不能有什么卵用
所以单纯形法就这么讲完啦。
实现的时候可以发现,写单纯形并不要真的把松弛型建出来,只要假装第i个约束条件就对应第i个基变量,把系数取负就可以了。
我的代码(有一些细节写的比较丑
#include #include#include#include#include#include#include#include#include#include
using namespacestd;
typedefdoubleld;#define SZ 233
intn,m,t,id[SZ];
ld a[SZ][SZ],vv[SZ];const ld eps=1e-7;intdcmp(ld x)
{if(xeps) return 1;return 0;
}void pivot(int r,int c) //基变量r和非基变量c
{
swap(id[r+n],id[c]);
ld x=-a[r][c]; a[r][c]=-1;for(int i=0;i<=n;i++) a[r][i]/=x;for(int i=0;i<=m;i++)
{if(dcmp(a[i][c])&&i!=r);else continue;
x=a[i][c]; a[i][c]=0;for(int j=0;j<=n;j++) a[i][j]+=x*a[r][j];
}
}voidsolve()
{for(int i=1;i<=n;i++) id[i]=i;while(1) //init
{int x=0,y=0;for(int i=1;i<=m;i++)
{if(dcmp(a[i][0])<0&&(!x||(rand()&1))) x=i;
}if(!x) break;for(int i=1;i<=n;i++)
{if(dcmp(a[x][i])>0&&(!y||(rand()&1))) {y=i; break;}
}if(!y) {puts("Infeasible"); return;}
pivot(x,y);
}while(1) //simplex
{int x=0,y=0;for(int i=1;i<=n;i++)
{if(dcmp(a[0][i])>0&&(!x||(rand()&1))) x=i;
}if(!x) break;double w,t; bool f=1;for(int i=1;i<=m;i++)
{if(dcmp(a[i][x])<0&&((t=-a[i][0]/a[i][x]),f||t
}if(!y) {puts("Unbounded"); return;}
pivot(y,x);
}
printf("%.9lf\n",a[0][0]);if(!t) return;for(int i=1;i<=n;i++) vv[i]=0;for(int i=n+1;i<=n+m;i++) vv[id[i]]=a[i-n][0];for(int i=1;i<=n;i++) printf("%.9lf",vv[i]);
}intmain()
{
scanf("%d%d%d",&n,&m,&t);for(int i=1;i<=n;i++) scanf("%lf",&a[0][i]);for(int i=1;i<=m;i++)
{for(int j=1;j<=n;j++) scanf("%lf",&a[i][j]), a[i][j]*=-1;
scanf("%lf",&a[i][0]);
}
solve();
}
java单纯形法_单纯形法 - fjzzq2002 - 博客园相关推荐
- java充值_充值 - javalzy - 博客园
http://blog.csdn.net/xiaoxiangzhu660810/article/details/17434907 http://blog.csdn.net/fangzy0112/art ...
- java传感器_传感器 - javawebsoa - 博客园
传感器(英文名称:transducer/sensor)是一种检测装置,能感受到被测量的信息,并能将检测感受到的信息,按一定规律变换成为电信号或其他所需形式的信息输出,以满足信息的传输.处理.存储.显示 ...
- java 独木桥_独木桥 - pandaB - 博客园
题目背景 战争已经进入到紧要时间.你是运输小队长,正在率领运输部队向前线运送物资.运输任务像做题一样的无聊.你希望找些刺激,于是命令你的士兵们到前方的一座独木桥上欣赏风景,而你留在桥下欣赏士兵们.士兵 ...
- java爬虫之爬取博客园推荐文章列表
这几天学习了一下Java爬虫的知识,分享并记录一下: 写一个可以爬取博客园十天推荐排行的文章列表 通过浏览器查看下一页点击请求,可以发现 在点击下一页的时候是执行的 post请求,请求地址为 http ...
- java bean 单例模式_单例模式 - Beans_bag - 博客园
1.单例模式的简介 定义 保证每个类仅有一个实例,并给外部提供一个访问它的全局访问点. 思路 如果一个类能够被创建多个实例,那么,这个类的构造方法肯定是公开的,外部通过此类的构造方法可以创建多个类的实 ...
- java输出孪生素数对数_孪生素数 - Vincent-yuan - 博客园
题目描述 所谓孪生素数指的是间隔为2的相邻的素数,他们之间的距离已经近得不能再近了,就像孪生兄弟一样,最小的孪生素数是(3,5),在100以内还有(5,7),(11,13),(17,19),(17,1 ...
- java里面的pai_Java - ZhangPai - 博客园
Java语言是一种单继承结构语言,Java中所有的类都有一个共同的祖先Object类. 如果一个类没有用extends明确指出继承于某个类,那么它默认继承Object类. Object类是Java中所 ...
- mysql可以做决策树吗_决策树 - stream886 - 博客园
参考资料 决策树 决策树是一种运用概率与图论中的树对决策中的不同方案进行比较,从而获得最优方案的风险型决策方法. 决策树学习三步骤: 特征选择 决策树的生成 决策树的剪枝 常用的决策树算法有ID3,C ...
- java jce_JCE - 懒懒的呐喊 - 博客园
https://blog.csdn.net/weinichendian/article/details/78549157 安装BouncyCastle JCE应该按照如下步骤: 1)下载提供者 Bou ...
最新文章
- jenkins-svn配置
- 深入分析 Redis Lua 脚本运行原理
- Spring的依赖注入和管理Bean
- golang中的Mock依赖
- KineticJS教程(6)
- 桌面支持--打印机任务取消不了
- “.公司”域名注册总量TOP15:新网问鼎 万网居亚
- android实现欢迎启动界面
- 降价200!华为部分手机已取消充电器和数据线,网友表示可以接受
- 剑指offer(C++)-JZ36:二叉搜索树与双向链表(数据结构-树)
- ubuntu下环境变量详解 bashrc, profile, environment
- OpenCV3计算机视觉:Python实现 读书笔记-第二章
- “交通·未来”第22期:城市轨道交通管理与控制优化:相关问题及方法
- 安卓系统命令 ftp服务器,安卓手机 ftp服务器
- qemu-kvm使用无线网卡桥接_网桥和无线网桥的概念及架设方案
- 什么是IPX/SPX
- javascript语言,定义变量
- HandlerMethodReturnValueHandler处理返回值问题,aop
- 算法之-判断某个整数是否为素数的自定义函数:
- Mac系统环境变量配置和说明【实用版】
热门文章
- 路由重分布列表控制例子
- Type mismatch: cannot convert from int to Object错误
- DNN(DotNetNuke)注册用户终于突破10万人了,其3.0也终于跳票了...
- CSDN登陆校验码模式识别程序
- java hashmap 的api_JAVA基础--JAVA API集合框架(ArrayList、HashSet、HashMap使用)
- php curl json post请求_php post请求发送json对象数据参数
- jpa findone怎么用_Jpa VS MyBatis,你用哪个?
- oracle schema_oracle数据库全局统计更新
- [转载] Java-forEach增强for循环是值传递规则详解
- python名称空间与运用域_Python名称空间和作用域讲座,命名,Namespaces,Scopes