分数规划问题

2024-08-28 18:04
文章标签 规划 问题 分数

本文主要是介绍分数规划问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

分数规划

  • 概念及解法
  • 一些题目

概念及解法

  引用自OI Wiki

分数规划用来求一个分式的极值。
形象一点就是,给出 a i a_i ai b i b_i bi,求一组 w i ∈ { 0 , 1 } w_i\in\{0,1\} wi{0,1},最小化或最大化 ∑ i = 1 n a i × w i ∑ i = 1 n b i × w i \displaystyle\frac{\sum\limits_{i=1}^na_i\times w_i}{\sum\limits_{i=1}^nb_i\times w_i} i=1nbi×wii=1nai×wi
另外一种描述:每种物品有两个权值 a 和 b,选出若干个物品使得 ∑ a ∑ b \displaystyle\frac{\sum a}{\sum b} ba 最小/最大。
一般分数规划问题还会有一些奇怪的限制,比如『分母至少为 W』。

分数规划问题的通用解法是二分

假设要求最大值。二分一个答案 mid,然后推式子(为了方便少写了上下界):
               ∑ a i × w i ∑ b i × w i > m i d ⟹ ∑ a i × w i − m i d × ∑ b i ⋅ w i > 0 ⟹ ∑ w i × ( a i − m i d × b i ) > 0 \displaystyle \begin{aligned} &\frac{\sum a_i\times w_i}{\sum b_i\times w_i}>mid\\ \Longrightarrow&\sum a_i\times w_i-mid\times \sum b_i\cdot w_i>0\\ \Longrightarrow&\sum w_i\times(a_i-mid\times b_i)>0 \end{aligned} bi×wiai×wi>midai×wimid×biwi>0wi×(aimid×bi)>0
那么只要求出不等号左边的式子的最大值就行了。如果最大值比 0 要大,说明 mid 是可行的,否则不可行。
求最小值的方法和求最大值的方法类似。

一些题目

  UVa12164/LA4412 The Great Game
  这是一道综合了概率(马尔可夫链)、二分、dp的好题,也是我碰到的首个分数规划题目。

  UVa11090 Going in Cycle!!
  给定一个n个点m条边的加权有向图,求平均权值最小的回路。输入第一行为数据组数T。每组数据第一行为图的点数n和边数m(n≤50)。以下m行每行3个整数u, v, w,表示有一条从u到v的有向边,权值为w。输入没有自环。对于每组数据,输出最小平均值。如果无解,输出“No cycle found.”。

#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;#define INF 20000000
#define N 52
struct {int v; double w;} g[N][N]; int w[N][N], c[N], f[N], cnt[N], q[N*N], m, n, kase = 0; double d[N];bool cycle() {int head = 0, tail = n;for (int i=1; i<=n; ++i) cnt[i] = d[i] = 0, f[i] = 1, q[i-1] = i;while (head < tail) {int u = q[head++]; f[u] = 0;for (int i=0; i<c[u]; ++i) {int v = g[u][i].v; double d1 = d[u] + g[u][i].w;if (d[v] > d1) {d[v] = d1;if (++cnt[v] >= n) return true;if (!f[v]) q[tail++] = v, f[v] = 1;}}}return false;
}bool cycle(double x) {for (int u=1; u<=n; ++u) for (int i=0; i<c[u]; ++i) g[u][i].w -= x;bool r = cycle();for (int u=1; u<=n; ++u) for (int i=0; i<c[u]; ++i) g[u][i].w += x;return r;
}void solve() {memset(w, 31, sizeof(w)); memset(c, 0, sizeof(c));cin >> n >> m;int x = 0;while (m--) {int u, v, z; cin >> u >> v >> z; x = max(x, z);if (w[u][v] > INF) g[u][c[u]++].v = v;if (z < w[u][v]) w[u][v] = z;}for (int u=1; u<=n; ++u) for (int i=0; i<c[u]; ++i) g[u][i].w = w[u][g[u][i].v];if (cycle(x + 1e-3))  {double l = 0., r = x;while (l + 1e-3 < r) {double m = (l+r) / 2.;cycle(m) ? r = m : l = m;}cout << "Case #" << ++kase << ": " << l << endl;} else cout << "Case #" << ++kase << ": No cycle found." << endl;
}int main() {cout << fixed << setprecision(2);int t; cin >> t;while (t--) solve();return 0;
}

  洛谷 P3705 [SDOI2017] 新生舞会

#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;#define INF 1e30
#define N 102
double slack[N], lx[N], ly[N], m; int a[N][N], b[N][N], pre[N], p[N], vis[N], n, clk;void bfs(int u) {for (int i=1; i<=n; ++i) pre[i] = 0, slack[i] = INF;int y = 0, yy = 0; p[0] = u;do {double d = INF; int x = p[y]; vis[y] = clk;for (int i=1; i<=n; ++i) if (vis[i] != clk) {double w = lx[x] + ly[i] - a[x][i] + m*b[x][i];if (slack[i] > w) slack[i] = w, pre[i] = y;if (slack[i] < d) d = slack[i], yy = i;}for (int i=0; i<=n; ++i) vis[i] == clk ? (lx[p[i]]-=d, ly[i] += d) : slack[i] -= d;y = yy;} while (p[y]);while (y) p[y] = p[pre[y]], y = pre[y];
}double km() {lx[0] = ly[0] = 0.; vis[0] = 0;for (int i=1; i<=n; ++i) {p[i] = 0; lx[i] = -INF; ly[i] = 0.; vis[i] = 0;for (int j=1; j<=n; ++j) lx[i] = max(lx[i], a[i][j] - m*b[i][j]);}for (int i=1; i<=n; ++i) bfs(clk = i);double cc = 0.;for (int i=1; i<=n; ++i) cc += a[p[i]][i] - m*b[p[i]][i];return cc;
}double solve() {for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) cin >> a[i][j];for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) cin >> b[i][j];double l = 0., r = 1e4, eps = 1e-8;while (l+eps <= r) {m = .5*(l+r);km() < 0. ? r = m-eps : l = m+eps; }return r;
}int main() {ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);cout << fixed << setprecision(6);while (cin >> n) cout << solve() << endl;return 0;
}

这篇关于分数规划问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1115489

相关文章

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

如何解决Spring MVC中响应乱码问题

《如何解决SpringMVC中响应乱码问题》:本文主要介绍如何解决SpringMVC中响应乱码问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC最新响应中乱码解决方式以前的解决办法这是比较通用的一种方法总结Spring MVC最新响应中乱码解

pip无法安装osgeo失败的问题解决

《pip无法安装osgeo失败的问题解决》本文主要介绍了pip无法安装osgeo失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 进入官方提供的扩展包下载网站寻找版本适配的whl文件注意:要选择cp(python版本)和你py

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图

Redis解决缓存击穿问题的两种方法

《Redis解决缓存击穿问题的两种方法》缓存击穿问题也叫热点Key问题,就是⼀个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击,本文给大家介绍了Re... 目录引言解决办法互斥锁(强一致,性能差)逻辑过期(高可用,性能优)设计逻辑过期时间引言缓存击穿:给

Java程序运行时出现乱码问题的排查与解决方法

《Java程序运行时出现乱码问题的排查与解决方法》本文主要介绍了Java程序运行时出现乱码问题的排查与解决方法,包括检查Java源文件编码、检查编译时的编码设置、检查运行时的编码设置、检查命令提示符的... 目录一、检查 Java 源文件编码二、检查编译时的编码设置三、检查运行时的编码设置四、检查命令提示符