算法设计与分析:线性规划问题和单纯形算法(作业-必做)(头歌实验)

news2024/9/28 17:34:55

第1关:单纯性算法解一般线性方程组

任务描述

本关任务:编写一个利用两阶段单纯性算法求一般线性规划的程序。

相关知识

单纯形算法的第1步:选出使目标函数增加的非基本变量作为入基变量。

查看单纯形表的第 1 行(也称之为z行)中标有非基本变量的各列中的值。 选出使目标函数增加的非基本变量作为入基变量。

单纯形算法的第2步:选取离基变量。

在单纯形表中考察由第 1 步选出的入基变量所相应的列。 在一个基本变量变为负值之前,入基变量可以增到多大。 如果入基变量所在的列与基本变量所在行交叉处的表元素为负数,那么该元素将不受任何限制,相应的基本变量只会越变越大。 如果入基变量所在列的所有元素都是负值,则目标函数无界,已经得到了问题的无界解。 如果选出的列中有一个或多个元素为正数,要弄清是哪个数限制了入基变量值的增加。 受限的增加量可以用入基变量所在列的元素(称为主元素)来除主元素所在行的“常数列”(最左边的列)中元素而得到。所得到数值越小说明受到限制越多。 应该选取受到限制最多的基本变量作为离基变量,才能保证将入基变量与离基变量互调位置后,仍满足约束条件。

单纯形算法的第3步:转轴变换。

转轴变换的目的是将入基变量与离基变量互调位置。 给入基变量一个增值,使之成为基本变量; 修改离基变量,让入基变量所在列中,离基变量所在行的元素值减为零,而使之成为非基本变量。

单纯形算法的第4步:转回并重复第1步,进一步改进目标函数值。

不断重复上述过程,直到z行的所有非基本变量系数都变成负值为止。

编程要求

根据提示,在右侧编辑器补充代码。

测试说明

平台会对你编写的代码进行测试:

测试输入:

 
  1. 1 //1:(max) -1(min)
  2. 4 4 // 不等式个数m=4, 变量个数n=4
  3. 2 1 1 // m1(≤)=2, m2(=)=1,m3(≥)=1
  4. 1 0 2 0 18 //x1 + 2x3 ≤ 18
  5. 0 2 0 -7 0// 2x2 - 7x4 ≤ 0
  6. 1 1 1 1 9 // x1+x2+x3+x4 = 9
  7. 0 1 -1 2 1//x2-x3x+2x4 ≥1
  8. 1 1 3 -1 //目标函数 z = x1+x2+3x3-x4

开始你的任务吧,祝你成功!

参考答案:

#pragma once
#include <cmath>
#include <iostream>
#include<fstream>
#include <string>
#include <iomanip>
#include <cfloat>
using namespace std;
class LinearProgram
{
            
public:
        LinearProgram();
        ~LinearProgram();
        void solve();
    private:
        int enter(int objrow);
        int leave(int col);
        int simplex(int objrow);
        int phase1();
        int phase2();
        int compute();
        void swapbasic(int row,int col);
        void pivot(int row,int col);
    //    void stats();//这个方法是干什么的?
        void setbasic(int * basicp);
        void output();
        void Make2DArray(double ** & a, int m,int n);
        void Delet2DArray(double ** & a, int m,int n);
        int m,                //约束总数
            n,                //变量数
            m1,                //不等式约束数<=
            m2,                //等式约束
            m3,                //不等式约束数>=
            n1,n2,            //n1 = n + m3,n2 = n1 + m1
            error,            //记录错误类型
            *basic,            //基本变量下标
            *nonbasic;        //非基本变量下标
        double **a,minmax;
};
LinearProgram::LinearProgram()
{
            
    double value;
    cout<<"Enter data in the following format:"<<endl;
    cout<<"1:+1(max)or-1(min);m;n"<<endl;
    cout<<"2:m1;m2;m3"<<endl;
    cout<<"The constraint coefficient and the right term"<<endl;
    cout<<"Objective function coefficient"<<endl;
    error = 0;
    cin>>minmax;
    cin>>m;
    cin>>n;
    //输入各类约束数
    cin>>m1;
    cin>>m2;
    cin>>m3;
    if(m!=m1+m2+m3)
    {
            
        error = 1;
    }
    n1 = n + m3;
    n2 = n + m1 + m3;
    Make2DArray(a,m+2,n1+1);//构造二维数组
    basic = new int[m+2];
    nonbasic = new int[n1+1];
    //初始化基本变量和非基本变量
    /*********begin*************/
        for(int i=0; i<=m+1; i++)
    {
            
        for(int j=0; j<=n1; j++)
        {
            
            a[i][j] = 0.0;
        }
    }
    for(int j=0; j<=n1; j++)
    {
            
        nonbasic[j] = j;
    }
    /*********end***************/
    //引入松弛变量和人工变量
    /*********begin*************/
        for(int i=1,j=n1+1; i<=m; i++,j++)
    {
            
        basic[i] = j;
    }
    for(int i=m-m3+1,j=n+1; i<=m; i++,j++)
    {
            
        a[i][j] = -1.0;
        a[m+1][j] = -1.0;
    }
    /*********end***************/
    //输入约束系数和右端项
    for(int i=1; i<=m; i++)
    {
            
        for(int j=1; j<=n; j++)
        {
            
            cin>>value;
            a[i][j] = value;
        }
        cin>>value;
        if(value<0) 
        {
            
            error = 1;
        }
        a[i][0] = value;
    }
    //输入目标函数系数
    for(int j=1; j<=n; j++)
    {
            
        cin>>value;
        a[0][j] =  value * minmax;
    }
    //引入人工变量,构造第1阶段的辅助目标函数
    /*********begin*************/
        for(int j=1; j<=n;  j++)
    {
            
        value=0.0;
        for(int i=m1+1; i<=m; i++)
        {
            
            value += a[i][j];
        }
        a[m+1][j] = value;
    } 
    /*********end***************/
}
LinearProgram::~LinearProgram()
{
            
    delete basic;
    delete nonbasic;
    Delet2DArray(a,m+2,n1+1);
}
void LinearProgram::Make2DArray(double ** & a, int m,int n)
{
            
    a = new double*[m];
    for (int i=0; i<m; i++)
    {
            
        a[i] = new double[n];
    }
}
void LinearProgram::Delet2DArray(double ** & a, int m,int n)
{
            
    for (int i = 0; i <= m;i++)
    {
            
        delete[]a[i];
    }
    delete[]a;
}
//根据目标函数系数所在的行objrow,执行约束标准型线性规划问题的单纯形算法
int LinearProgram::simplex(int objrow)
{
            
    /*********begin*************/
        for(int row = 0;;)
    {
            
        int col = enter(objrow);
        if(col>0)
        {
            
            row = leave(col);
        }
        else
        {
            
            return 0;
        }
        if(row>0)
        {
            
            pivot(row,col);
        }
        else
        {
            
            return 2;
        }
    }
    /*********end***************/
}
//根据目标函数系数所在行objrow,选取入基变量
int LinearProgram::enter(int objrow)
{
            
    double temp = DBL_EPSILON;    
    int j,col;
    /*********begin*************/
    for(j=1,col=0; j<=n1; j++)
    {
            
        if(nonbasic[j]<=n2 && a[objrow][j]>temp)
        {
            
            col = j;
            temp = a[objrow][j];
            break;            //Bland避免循环法则
        }
    }
    /*********end***************/
    return col;
}
//根据入基变量所在列col,选取离基变量
int LinearProgram::leave(int col)
{
            
    double temp = DBL_MAX;
    int row, i;
    /*********begin*************/
        for(i=1,row=0; i<=m; i++)
    {
            
        double val = a[i][col];
        if(val>DBL_EPSILON)
        {
            
            val = a[i][0]/val;
            if(val<temp)
            {
            
                row = i;
                temp = val;
            }
        }
    }
    /*********end***************/
    return row;
}
//以入基变量所在列col和离基变量所在行row交叉处元素a[row][col]为轴心,做转轴变换
void LinearProgram::pivot(int row,int col)
{
            
    /*********begin*************/
    for(int j=0; j<=n1; j++)
    {
            
        if(j!=col)
        {
            
            a[row][j] = a[row][j]/a[row][col];
        }
    }
    a[row][col] = 1.0/a[row][col];
    for(int i=0; i<=m+1; i++)
    {
            
        if(i!=row)
        {
            
            for(int j=0; j<=n1; j++)
            {
            
                if(j!=col)
                {
            
                    a[i][j] = a[i][j] - a[i][col]*a[row][j];
                    if(fabs(a[i][j])<DBL_EPSILON)
                    {
            
                        a[i][j] = 0.0;
                    }
                }
            }
            a[i][col] = - a[i][col]*a[row][col];
        }
    }
    /*********end***************/
    swapbasic(row,col);
}
//交换基本变量row和非基本变量col的位置
void LinearProgram::swapbasic(int row,int col)
{
            
    int temp = basic[row];
    basic[row] = nonbasic[col];
    nonbasic[col] = temp;
}
//对一般的线性规划问题执行两阶段单纯形算法
int LinearProgram::compute()
{
            
    if(error>0)
    {
            
        return error;
    }
    if(m!=m1)
    {
            
        error = phase1();
        if(error>0)
        {
            
            return error;
        }
    }
    return phase2();
}
//构造初始基本可行解的第一阶段单纯形算法由phase1()实现
//辅助目标函数存储在数组a的第trows行
int LinearProgram::phase1()
{
            
    error = simplex(m+1);
    if(error>0)
    {
            
        return error;
    }
    for(int i=1; i<=m; i++)
    {
            
        if(basic[i]>n2)
        {
            
            if(a[i][0]>DBL_EPSILON)
            {
            
                return 3;
            }
            for(int j=1; j<=n1; j++)
            {
            
                if(fabs(double(a[i][j]))>=DBL_EPSILON)
                {
            
                    pivot(i,j);
                    break;
                }    
            }
        }
    }
    return 0;
}
//第二阶段根据第一阶段找到的基本可行解,对原来的目标函数用单纯形算法求解
//原目标函数存储在数组a的第0行
int LinearProgram::phase2()
{
            
    return simplex(0);
}
//执行两阶段单纯形算法
void LinearProgram::solve()
{
            
    cout<<endl<<"* * * 线性规划---单纯形算法 * * *"<<endl<<endl;
    error = compute();
    switch(error)
    {
            
        case 0:output();break;
        case 1:cout<<"输入数据错误--"<<endl;break;
        case 2:cout<<"无界解--"<<endl;break;
        case 3:cout<<"无可行解--"<<endl;
    }
    cout<<"计算结束"<<endl;
}
//输出结果
void LinearProgram::output()
{
            
    int width = 8,*basicp;
    double zero = 0.0;
    basicp = new int[n+m+1];
    setbasic(basicp);
    cout.setf(ios::fixed|ios::showpoint|ios::right);
    cout.precision(4);
    cout<<endl<<"最优值:"<<-minmax*a[0][0]<<endl<<endl;
    cout<<"最优解:"<<endl<<endl;
    for(int j=1; j<=n; j++)
    {
            
        cout<<"x"<<j<<" =";
        if(basicp[j]!=0)
        {
            
            cout<<setw(width)<<a[basicp[j]][0];
        }
        else
        {
            
            cout<<setw(width)<<zero;
        }
        cout<<endl;
    }
    cout<<endl;
    delete []basicp;
} 
void LinearProgram::setbasic(int * basicp)
{
            
    for(int i=0;i<=n+m;i++)
    {
            
        basicp[i] = 0;
    }
    for(int i=1;i<=m;i++)
    {
            
        basicp[basic[i]]=i;
    }
}

如果对你有所帮助,感谢点赞加收藏!

关于接下来的实验内容,我也会在【WRITE-BUG数字空间】更新,也可以为大家带来更好的观感,带来更多的分享,欢迎大家前来浏览。

算法设计与分析:线性规划问题和单纯形算法(作业-必做)(头歌实验) -文章频道 - 我的学习圈 - 个人学习圈 (writebug.com)icon-default.png?t=N3I4https://www.writebug.com/article/f5406a00-f3e5-11ed-93f4-0242ac14000d

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UnityVR--Managers--对象池1

本篇中使用的API&#xff1a;gameObject.CompareTag("标签")、UnityEvent()事件管理、ObjectPool<GameObject>&#xff08;&#xff09;对象池 参照unity官方教程&#xff1a;Hi ObjectPool 目录 1. 应用场景 2. 对象池的原理 3. 查看资源消耗情况 4. 不使用…

mysql 备库延迟问题

备库延迟原因&#xff1a; log传送开销小&#xff0c;消费relay log 超时 备库性能不如主库 备库承担更多SQL分析 主库是多线程执行&#xff0c;备库是单线程执行解析relay log 处理方法&#xff1a; 主备使用相同的机器 备库关闭log实时落盘 增加从库数量&#xff0c;…

Sentinel-2数据下载及处理

数据下载网站&#xff1a;欧空局官网&#xff08;需注册并登录&#xff09; https://scihub.copernicus.eu/dhus/#/home 哨兵2 L1C数据波段信息 哨兵2 L1C数据时间&#xff1a;2015-06-23至now 由于数据量大&#xff0c;考虑服务器压力&#xff0c;哨兵2号数据直接下载的时间跨…

[web安全原理分析]-XXE漏洞入门

前言 XXE漏洞 XXE漏洞全称(XML External Entity Injection)即xml外部实体注入漏洞&#xff0c;XXE漏洞发生在应用程序解析XML输入时&#xff0c;没有禁止外部实体的加载&#xff0c;导致可加载恶意外部文件&#xff0c;造成文件读取、命令执行、内网端口扫描、攻击内网网站、…

头歌计算机组成原理实验—运算器设计(10) 第10关:补码一位乘法器设计

第10关&#xff1a;补码一位乘法器设计 实验目的 学生掌握补码一位乘法运算的基本原理&#xff0c;熟练掌握 Logisim 寄存器电路的使用&#xff0c;能在 Logisim 平台中设计实现一个8*8 位的补码 Booth一位乘法器。 视频讲解 ####实验内容 在 alu.circ 文件中的补码一位乘法…

Linux基础——权限

1. Linux下的用户 在 Linux 操作系统中&#xff0c;有两种主要类型的用户账户&#xff0c;分别是普通用户账户和超级用户账户&#xff08;也称为 root 用户账户&#xff09;。 普通用户账户&#xff08;user&#xff09;是在 Linux 系统上创建的普通账户&#xff0c;可以用于日…

图片隐写(一)

文件隐藏 binwalk binwalk -e filename foremost foremost filename steghide & stegseek Install sudo apt-get install steghidestegseek Use steghide extract -sf filename -p passwordtime stegseek secret.file aaa.txt dd 文本隐藏 二进制文件末尾 or 文…

ffmpeg rtsp解析

一、 rtsp 协议说明 rtsp的协议层级 rtsp 属于应用层&#xff0c; 使用tcp传输&#xff0c;主要是传递服务器的一些信息&#xff0c;实现流连接。播放 暂停 销毁等控制 rtp 实现音视频数据包的发送&#xff0c;通过RTSP等协议的SDP信息协商好了RTP数据包的发送目的和传输方式…

UNIX网络编程卷一 学习笔记 第十四章 高级I/O函数

有3种方式可在涉及套接字的IO操作上设置超时方法&#xff1a; 1.调用alarm&#xff0c;它在指定超时期满时产生SIGALRM信号。此方法涉及信号处理&#xff0c;而信号处理在不同的实现上存在差异&#xff0c;且此方法可能干扰进程中已经执行过的alarm调用&#xff0c;可能使之前已…

【LLM系列之Tokenizer】如何科学地训练一个LLM分词器

1 背景与基础 1.1 为什么需要分词 对于人而言&#xff0c;在我们学会阅读之前&#xff0c;仍然可以理解语言。比如当你开始上学时&#xff0c;即使你不知道名词和动词之间的区别&#xff0c;但是你已经可以和你的同学交谈了&#xff0c;比如“我喜欢吃香蕉”&#xff0c;孩子…

vmware ubuntu突然无法联网的一种解决方案

记录一下vmware突然无法联网的一种解决方案。此法未必适用所有无法联网情形。Good Luck then. 今天使用vmware的ubuntu 18.04时&#xff0c;突然无法联网。Firefox在访问百度时显示“The proxy server is refusing connections”&#xff0c;随即检查了浏览器的proxy设置&#…

详解Jetpack Compose中的状态管理与使用

前言 引用一段官方描述&#xff0c;如下 由于 Compose 是声明式工具集&#xff0c;因此更新它的唯一方法是通过新参数调用同一可组合项。这些参数是界面状态的表现形式。每当状态更新时&#xff0c;都会发生重组。因此&#xff0c;TextField 不会像在基于 XML 的命令式视图中那…

头歌计算机组成原理实验—运算器设计(9)第9关:原码一位乘法器设计

第9关&#xff1a;原码一位乘法器设计 实验目的 学生掌握原码一位乘法运算的基本原理&#xff0c;熟练掌握 Logisim 寄存器电路的使用&#xff0c;能在 Logisim 平台中设计实现一个 8*8位的无符号数乘法器。 视频讲解 ####实验内容 在 alu.circ 文件中的原码一位乘法器子电…

分布式消息中间件RocketMQ概述

RocketMQ 概述 MQ概述 MQ简介 ​ MQ&#xff0c;Message Queue&#xff0c;是一种提供消息队列服务的中间件&#xff0c;也称为消息中间件&#xff0c;是一套提供了消息生产、存储、消费全过程API的软件系统。消息即数据。一般消息的体量不会很大。 MQ用途 在网络上上可以查…

React学习笔记五-props

此文章是本人在学习React的时候&#xff0c;写下的学习笔记&#xff0c;在此纪录和分享。此为第五篇&#xff0c;主要介绍react中的props。 目录 1.props的基本使用 2.props的批量传递 2.1展开运算符的复习 2.1.1数组中的展开运算符 2.1.2函数中的展开运算符 2.1.3构造字面…

部署图的画法

部署图画法 1.部署图 1.1含义 部署图是把软件制品装配到计算机节点以及配置软件环境的工作 软件部署包含环境部署和软件制品部署 1.2软件部署 软件部署通过部署图对软件进行建模 1.3部署图 部署图常见的有制品 节点 设备 运行环境和部署规范 1.4部署图关系 在UML&…

UnityVR--Managers--对象池2

目录 前言 基本结构 对象池代码 对象池管理器代码 使用 总结 前言 经过上一篇对象池1的了解&#xff0c;已经做到了使用Unity自带的ObjectPool进行内存优化。本篇自己构建一个对象池管理器&#xff08;Manager&#xff09;&#xff0c;实现对象池的创建、删除、加载资源…

机器视觉工程师很苦吗?年轻人不怕苦,就怕学不到东西,机器视觉销售>项目经理>视觉>电气>机械>老板

年轻人不怕苦&#xff0c;就怕学不到东西。 对于年轻人来说&#xff0c;需要规划&#xff0c;更需要发展。如果学不到东西&#xff0c;就会限制其发展&#xff0c;最重要的体现就是限制待遇上限。 一个非标自动化公司出差的频次&#xff08;各个公司略有差别&#xff0c;大多…

062:cesium设置泛光折线材质(material-6)

第062个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中设置泛光折线材质,请参考源代码,了解PolylineGlowMaterialProperty的应用。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共89行)相关API参考:专…

蓝桥:前端开发笔面必刷题——Day2 数组(三)

文章目录 &#x1f4cb;前言&#x1f3af;两数之和 II&#x1f4da;题目内容✅解答 &#x1f3af;移除元素&#x1f4da;题目内容✅解答 &#x1f3af;有序数组的平方&#x1f4da;题目内容✅解答 &#x1f3af;三数之和&#x1f4da;题目内容✅解答 &#x1f4dd;最后 &#x…