每日一记:分数规划
2014-08-22 13:06
239 查看
以下部分内容引用论文内容。
分数规划一般形式:
解向量x在解空间S内, a(x)与 b(x)都是连续的实值函数。
求解过程:
1、令g(λ) = min{a(x) -λ*b(x)} (x∈S),g(λ)是一个严格递减的函数
证明:设 λ1 < λ2, x1最小化了g(λ)。则
g(λ1) = min {a(x) - t1*b(x)}
= a(x1) - λ1*b(x1)
> a(x1) - λ2*b(x1) //b(x) > 0
>= min {a(x) - λ2*b(x)} = g(λ2)
Dinkelbach定理:若λ*为原规划的最优解,则g(λ)=0当且仅当λ=λ*。
即只需求出λ*使得g(λ*)=0即可。
2、设λ*为该规划的最优解。
使用二分法可求解。
Example:
第2行到第M+1行:每行三个整数,u v c (1<=u,v<=N 0<=c<=1000),表示城市u和城市v之间可以花费费用c修建一条道路。
-------------------------------------------------------------------------------------------------------------------
解法:本题可贪心也可分数规划,这里用分数规划求解。
1、设sum为所选总花费,cnt为所选道路数,题目所求为使得sum/cnt最小,满足分数规划的条件、。
2、构造函数g(λ) = min{sum -λ*cnt}。
二分λ:对于λ*,为了求出g(λ*),我们把每条边的边权变为w - λ, 按照此边权求最小生成树即可,注意要把所有负边权也加入最小生成树中,这样总和一定是最小的sum -λ*cnt。
分数规划一般形式:
解向量x在解空间S内, a(x)与 b(x)都是连续的实值函数。
求解过程:
1、令g(λ) = min{a(x) -λ*b(x)} (x∈S),g(λ)是一个严格递减的函数
证明:设 λ1 < λ2, x1最小化了g(λ)。则
g(λ1) = min {a(x) - t1*b(x)}
= a(x1) - λ1*b(x1)
> a(x1) - λ2*b(x1) //b(x) > 0
>= min {a(x) - λ2*b(x)} = g(λ2)
Dinkelbach定理:若λ*为原规划的最优解,则g(λ)=0当且仅当λ=λ*。
即只需求出λ*使得g(λ*)=0即可。
2、设λ*为该规划的最优解。
使用二分法可求解。
Example:
Description
Bryan成为了一名土木工程师,负责一个国家的道路建设!这个国家有N个城市,从1到N标号。M条可以修建的路,每条路连接两个城市,并且有修建需要的花费。现在Bryan需要从M条路中选择一些修建,使得国家中任意两个城市都能连通。当然可行方案有很多,Bryan想选择平均修一条路的花费最小的那种方案。如果没有能连通所有城市的方案,输出-1。Input
第1行: 2个正整数,N M (1<=N<=1000, 0<=M<=100000),N表示城市的数量,M表示可以修建的路的数量。第2行到第M+1行:每行三个整数,u v c (1<=u,v<=N 0<=c<=1000),表示城市u和城市v之间可以花费费用c修建一条道路。
Output
输出最小的平均花费,四舍五入保留两位小数。如果不存在可行方案,输出-1。-------------------------------------------------------------------------------------------------------------------
解法:本题可贪心也可分数规划,这里用分数规划求解。
1、设sum为所选总花费,cnt为所选道路数,题目所求为使得sum/cnt最小,满足分数规划的条件、。
2、构造函数g(λ) = min{sum -λ*cnt}。
二分λ:对于λ*,为了求出g(λ*),我们把每条边的边权变为w - λ, 按照此边权求最小生成树即可,注意要把所有负边权也加入最小生成树中,这样总和一定是最小的sum -λ*cnt。
#include <iostream> #include <algorithm> #include <vector> #include <cstdio> using namespace std; #define MP(x,y) make_pair(x, y) const double eps = 1e-3; int pre[1005], n, m; void init (){ for (int i = 0; i < 1005; i ++){ pre[i] = i; } } int find (int x){ return pre[x] == x ? x : pre[x] = find (pre[x]); } void Union (int x, int y){ pre[find (x)] = find (y); } double cal (const vector<pair<int, pair<int, int> > >& g, double t){ init (); double ans = 0; int num = 0; for (int i = 0; i < g.size (); i ++){ int u = g[i].second.first; int v = g[i].second.second; int w = g[i].first; if (find (u) != find (v)){ Union (u, v); ans += (double)w-t; num ++; }else if (w - t < 0){ ans += (w-t); } } if (num < n-1) return -1; return ans; } int main (){ freopen ("6.in", "r", stdin); cin >> n >> m; vector<pair<int, pair<int, int> > > edge; for (int i = 1; i <= m; i ++){ int u, v, c; cin >> u >> v >> c; edge.push_back (MP (c, MP (u, v))); } sort (edge.begin (), edge.end ()); if (cal (edge, 0) == -1){ puts ("-1"); return 0; } double high = 100000.0, low = 0.0, mid; while (low + eps < high){ mid = (low + high)/2.0; if (cal (edge, mid) - eps> 0) low = mid; else high = mid; } printf ("%.2f\n", low); }
相关文章推荐
- poj 3155 Hard Life(最大密度子图,01分数规划)
- POJ-3621 Sightseeing Cows 最优比率环、01分数规划
- 01分数规划问题相关算法与题目讲解(二分法与Dinkelbach算法)
- SCOI2014方伯伯运椰子 (分数规划+SPFA)
- [bzoj1486][HNOI2009]最小圈——分数规划+spfa+负环
- [01分数规划]【学习笔记】
- BZOJ 1486: [HNOI2009]最小圈 [01分数规划]
- bzoj 3232: 圈地游戏 01分数规划
- poj 2976 基础01分数规划
- 每日一记--2014.9.12
- 【BZOJ2402】陶陶的难题II 分数规划+树链剖分+线段树+凸包
- 每日一记--2014.9.15
- POJ 2976 分数规划
- POJ 2976 Dropping tests & 分数规划讲解
- 每日一记:2017.12.1
- POJ-3621 Sightseeing Cows 01分数(参数搜索)规划问题-最优比率环
- 每日一记:2017.12.4
- bzoj 4819: [Sdoi2017]新生舞会 01分数规划 二分图最优匹配
- POJ 3621 Sightseeing Cows(01分数规划)
- POJ 2976 Dropping tests(普通01分数规划)