单纯形法

原博客:
http://blog.csdn.net/zhoubin1992/article/details/46916429

计算步骤:
http://www.doc88.com/p-7495430586060.html
http://www.docin.com/p-1260942683.html

根据自己的理解加上了注释

/*----------------------------------- 
单纯形法求解线性规划问题(C++实现代码)
----------------------------------- 
Author:牧之丶  Date:2014年
Email:bzhou84@163.com 
**********************************/ 
#include<iostream> 
#include<math.h> 
using namespace std;
#define INF 10000        // 全局变量大值

// 核心矩阵表 
// 第0行为目标函数
// 后n行为约束不等式,0列为不等式右边的常数项,1~m列为系数,m+1~m+n列为基
// 第n+1行为非基变量对应的检验数
float juzhen[11][31];  
int m = 0;             // m:结构向量的个数
int n = 0;             // n:约束不等式个数
int t = 0;             // t:目标函数类型:-1代表求求最小值,1代表求最大值     

// 输入接口函数                     
void input() 
{   
    int i,j; 
    cout << "----------单纯形法的参 数 输 入-----------" << endl; 
    cout << "请按提示输入下列参数:" << endl << endl; 
    cout << "  结构向量数m:  " << "   m=  "; 
    cin >> m; 
    cout << endl << "  约束不等式数n:" << "   n=  "; 
    cin >> n; 

    //初始化矩阵,所有元素均为0
    for (i=0; i<=n+1; i++) 
    {
        for (j=0; j<=m+n+n; j++)  
            juzhen[i][j] = 0;      
    }

    //读入约束条件 
    cout << endl << "  约束方程矩阵的系数及不等式方向(1代表<=,-1代表>=):" << endl << endl <<"          "; 
    for (i=1; i<=m; i++) 
        cout << "   x" << i; 
    cout << "  不等式方向 " << " 常数项" << endl; 
    for(i=1; i<=n; i++)  
    {  
        cout << "    不等式" << i << "  "; 
        for (j=1; j<=m+2; j++)  
            cin >> juzhen[i][j]; 
    } 
    for(i=1; i<=n; i++) 
    {  
        juzhen[i][0] = juzhen[i][m+2]; 
        juzhen[i][m+2] = 0; 
    } 

    //读入目标条件 
    cout << endl << endl << " 目标函数的系数及类型(求最小值:1;求最大值:-1):" << endl << endl <<"                "; 
    for(i=1; i<=m; i++) 
    {
        cout << "x" << i << "   "; 
    }
    cout << "类型" << endl << "  "; 
    cout << "  目标函数:   "; 
    for(i=1; i<=m; i++) 
    {
        cin >> juzhen[0][i];   // 目标函数系数
    }
    cin >> t;                  // 目标函数类型

    // 目标函数调整 
    if(t == -1)  
    {
        for(i=1; i<=m; i++)  
            juzhen[0][i] = (-1) * juzhen[0][i]; 
    }

    // 初始基调整
    for(i=1; i<=n; i++) 
    {  
        juzhen[i][m+i] = juzhen[i][m+1];   // 根据不等式方向调整
        if(i != 1) 
            juzhen[i][m+1] = 0;      
    } 
} 

//算法函数 
void comput() 
{ 
    int i, j, flag, temp1, temp2, h, k=0, temp3[10]; 
    float a, b[11], temp;
    float C_b[11];      // 基/非基变量在目标函数中的系数向量
    float X[11];        // 最优解
    float f = 0;        // 最优结果
    float aa, d, c; 

    //初始化 
    for(i=1; i<=n; i++)  
    {
        temp3[i]=0; 
    }
    for(i=0; i<11; i++) 
    {    
        C_b[i] = 0; 
        X[i] = 0; 
    } 

    // 对基变量处理
    for(i=1; i<=n; i++) 
    { 
        if(juzhen[i][m+i] == -1)      
        { 
            juzhen[i][m+n+i] = 1;     
            juzhen[0][m+n+i] = INF;   // 在目标函数中的系数
            temp3[i] = m+n+i;         
        } 
        else  
        {
            temp3[i] = m+i; 
        }
    } 
    for(i=1; i<=n; i++) 
    {
        C_b[i] = juzhen[0][temp3[i]];  // 在目标函数中的系数
    }

    //循环求解目标函数的最小值
    do
    {    
        // 求非基变量的检验数
        for(i=1; i<=m+n+n; i++) 
        {   
            a = 0; 
            for(j=1; j<=n; j++) 
            {
                a += juzhen[j][i] * C_b[j];     // 系数列 * 基变量在目标函数中的系数向量
            }
            juzhen[n+1][i] = juzhen[0][i] - a;  // 非基变量的检验数
        } 

        int flag = 1;
        for(i=1; i<=m+n+n; i++) 
        { 
            if(juzhen[n+1][i] < 0)   
            {   
                flag = -1; 
                break; 
            } 
        } 

        // 对于求最小值
        // 如果非基变量检验数均 > 0
        if(flag == 1)  
        {     
            // 是否存在最优解
            temp1 = 1;
            for(i=1; i<=n; i++) 
            {  
                if(temp3[i] > m+n)  // 这里不明白 !!!
                {  
                    temp1 = -1; 
                    break; 
                } 
            } 

            //输出结果 
            cout << endl << endl; 
            cout << "----------结 果 输 出-----------"<<endl<<endl; 

            // 对于求最小值
            // 如果所有非基变量检验数均 > 0
            // 且不存在无最优解的情况
            // 那么该基可行解为最优解
            if(temp1 == 1) 
            {  
                cout << " 此线性规划的最优解存在!" << endl << endl << "  最优解为:" << endl << endl << "     "; 
                for(i=1; i<=n; i++) 
                {
                    X[temp3[i]] = juzhen[i][0]; 
                }
                for(i=1; i<=m; i++) 
                {
                    f += t * juzhen[0][i] * X[i]; 
                }
                for(i=1; i<=m; i++)  
                { 
                    cout << "x" << i << " = " << X[i]; 
                    if(i != m) 
                        cout<<", "; 
                } 
                cout << " ;" << endl << endl << "     最优目标函数值f= " << f << endl << endl; 
                return ; 
            } 

            // 如果存在无最优解情况
            else  
            {    
                cout << " 此线性规划无解" << endl << endl; 
                return ; 
            } 
        } 

        // 对于求最小值
        // 如果存在检验数 <= 0
        // 那么该基可行解不是最优解
        // 继续寻找另一个基可行解
        if(flag == -1) 
        {    
            // 挑选检验数最小的为进基变量
            temp = INF; 
            for(i=1; i <= m+n+n; i++) 
            {
                if(juzhen[n+1][i] < temp)     
                { 
                    temp = juzhen[n+1][i]; 
                    h = i;                     
                } 
            }
            for(i=1; i<=n; i++) 
            {  
                if(juzhen[i][h] <= 0) 
                    temp2 = 1; 
                else 
                {  
                    temp2 = -1; 
                    break; 
                }                        
            } 
        } 
        if(temp2 == 1)   
        {  
            cout << "此线性规划无约束"; 
            return; 
        } 
        if(temp2 == -1)  
        {    
            // 挑选出基变量
            c = INF; 
            for(i=1; i<=n; i++) 
            { 
                if(juzhen[i][h] != 0)  
                    b[i] = juzhen[i][0] / juzhen [i][h]; 
                if(juzhen[i][h] == 0)  
                    b[i] = INF; 
                if(b[i] < 0)     
                    b[i] = INF; 
                if(b[i] < c)  
                { 
                    c = b[i]; 
                    k = i; 
                } 
            } 
            temp3[k] = h; 
            C_b[k] = juzhen[0][h]; 
            d = juzhen[k][h];   // 主元

            // 希望基变量对应的系数列向量矩阵为单位矩阵

            // 在主元所在的约束不等式中,希望其系数为1
            for(i=0; i<=m+n+n; i++) 
                juzhen[k][i] = juzhen[k][i] / d; 

            // 改变别的约束不等式系数
            for(i=1; i<=n; i++) 
            { 
                if(i == k)  
                    continue; 
                aa = juzhen[i][h]; 
                for(j=0; j<=m+n+n; j++) 
                    juzhen[i][j] = juzhen[i][j] - aa * juzhen[k][j];  
            } 
        }     
    }while(1); 
    return; 
}

int main()
{   
    cout<<"-------------------单纯形算法程序----------------------"<<endl<<endl; 
    input(); 
    comput();
    system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值