• uoj#179. 线性规划


    题目链接

    uoj#179. 线性规划

    题解

    引入基向量(x_{i + n}),将约束(sum_{i = 1}^{m}a_{ij}x_j leq b_i) 写为 $x_{i + n} = b_i - sum_{i = 1}^m a_{ij} x_j $
    目标函数 $sum_{i = 1}^n C_i x_i $ 当存在 $ r,c$ 满足 (C_c>0,B_r > 0,a_{rc} > 0) ,把(x_c)作为第(r)个限制的基向量,得到$x_c = B_r - sum_{c geq j}a_{rj}x_j - x_{r + n} $
    带入目标函数,非基向量取(0),一定可使目标函数增大,同时把其他约束中的(x_c)替换。
    当所有的(B_r > 0)时一定能得到零解,存在(B_r < 0),在限制中找到一个小于(0)(a_rc)(x_c)带换为基向量,可以使(B_r >0) $x_i > 0 $
    建议去看集训队论文
    不过,为什么过不了

    代码

    #include<bits/stdc++.h> 
    using namespace std;
    #define eps 1e-8
    #define INF 1e9 
    inline int read() { 
    	int x = 0,f = 1; 
    	char c = getchar(); 
    	while(c < '0' ||c > '9'){ if(c == '-')f = - 1; c = getchar();} 
    	while(c <= '9' &&c >= '0')x = x * 10 + c - '0',c = getchar(); 
    	return x * f; 
    } 
    int n,m,type,id[57]; 
    double a[27][27],ans[57]; 
    void pivot(int r,int c) { // swap basic varivle and nonbasic variable  
    	swap(id[r + n],id[c]); 
    	double t = a[r][c];a[r][c] = 1; 
    	for(int i = 0;i <= n;++ i) a[r][i] /= t; 
    	for(int i = 0;i <= m;++ i) 
    		if(fabs(a[i][c]) > eps && i != r) { 
    			t = a[i][c];a[i][c] = 0 ; 
    			for(int j = 0;j <= n;++ j) a[i][j] -= t * a[r][j]; 
    		} 
    } 
    bool init() { 	
    	for(int r,c;;) { 
    		r = c = 0; 
    		for(int i = 1;i <= m;++ i) 
    			if(a[i][0] < -eps && (!r || rand() & 1)) r = i; 
    		if(!r) return 1; 
    		for(int i = 1;i <= n;++ i) 
    			if(a[r][i] < -eps && (!c || rand() & 1)) c = i; 
    		if(!c) return puts("Infeasible") , 0; 
    		pivot(r,c); 
    	} 
    } 
    bool simplex() { 
    	for(int r,c;;) { 
    		r = c = 0; 
    		for(int i = 1;i <= n;++ i)// C[c] > 0; 
    		if(a[0][i] > eps) {c = i;break;} 
    		if(!c)return 1; 
    		double mn = INF; //找约束最紧的正系数a[r][c]
    		for(int i = 1;i <= m;++ i) 
    			if(a[i][c] > eps && a[i][0] / a[i][c] < mn) r = i,mn = a[i][0] / a[i][c]; 
    		if(! r) return puts("Unbounded"),0; 
    		pivot(r,c); 
    	} 
    } 
    int main() { 
    	srand(20020711); 
    	n = read(),m = read(),type = read(); 
    	for(int i = 1;i <= n;++ i) a[0][i] = read(); //C[i] 
    	for(int i = 1;i <= m;++ i) { 
    		for(int j = 1;j <= n;++ j) a[i][j] = read(); 
    		a[i][0] = read(); //B[i] 
    	} 
    	for(int i = 1;i <= n;++ i) id[i] = i; 
    	if(init() && simplex()) { 
    		printf("%.8lf
    ",-a[0][0]); 
    		if(type) { 
                for(int i = 1;i <= m;++ i) ans[id[i + n]] = a[i][0]; //成为基变量的xi取值即为bi,非基变量上的xi取0. 
                for(int i = 1;i <= n;++ i) printf("%.8lf ",ans[i]); 
    		} 
    	} 
    	return 0; 
    } 
    
  • 相关阅读:
    1065. [Nescafe19] 绿豆蛙的归宿(概率)
    SDOI 2016 Round1 Day2
    SDOI 2016 Round1 Day1
    Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined)
    串 2016Vijos省选集训 day3[AC自动机]
    java连接elastic search 9300
    maven安装,maven命令行使用
    eclipse/IDEA使用maven
    hadoop笔记 基础 归档
    tpot蜜罐平台搭建
  • 原文地址:https://www.cnblogs.com/sssy/p/9386185.html
Copyright © 2020-2023  润新知