《数据结构、算法与应用C++语言描述》-队列的应用-工厂仿真

工厂仿真

完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_19Factory simulation/

问题描述

一个工厂有m台机器。工厂的每项任务都需要若干道工序才能完成。每台机器都执行一道工序,不同的机器执行不同的工序。一台机器一旦开始执行一道工序就不会中断,直到该工序完成为止。

举例

例 9-3 考察一个工厂,它有 3 台机器(m=3),有 4 项任务(n=4)。假设这 4 项任务都在0时刻出现,而且在仿真期间不再有新的任务。仿真过程一直持续到所有任务完成为止。

三台机器为 M1、M2 和 M3,它们的转换状态所花费的时间分别为2、3 和 1。因此,当一道工序完成时,机器M1必须等待2个时间单元才能启动下一道工序,机器M2必须等待3个时间单元才能启动下一道工序,机器M3必须等待1个时间单元才能启动下一道工序。
图9-16a分别列出了4项任务的特征。例如,1号任务有3道工序。每道工序用形如(机器,时间)的数对来描述。1号任务的第一道工序在M1上完成,需要2个时间单元;第二道工序在M2上完成,需要4个时间单元;第三道工序在 M1上完成,需要1个时间单元。各项任务的长度分别为7、6、8和4。

在这里插入图片描述

仿真从 0时刻开始。第一个事件即启动事件出现在 0时刻。此时,每个机器队列中的第一个任务被调度到相应的机器上执行。1号任务的第一道工序被调度到M1上执行,2号任务的第一道工序被调度到 M3 上执行。这时 M1 的队列中仅剩 3 号任务,而 M3 的队列中仅剩 4号任务,M2的队列仍然为空。这样,1号任务成为M1上的活动任务,2号任务成为M3上的活动任务,M2仍然为空闲。M1的结束时间变成2(当前时刻0+工序时间2),M3的结束时间变成 4。
下一个事件在时刻2出现,这个时刻是根据机器完成时间的最小值来确定的。在时刻2,M1 完成了它的当前活动工序。这个工序是 1 号任务的工序。1 号任务被移动到 M2 上以执行下一道工序。这时的 M2 是空闲的,因此立即执行 1 号任务的第二道工序,这道工序将在第 6时刻完成(当前时刻2+工序时间4)。M1进入转换工序(即转换状态)并持续2个时间单元。M1的活动任务被设置为C(转换状态),其完成时刻为4。

在时刻 4,M1 和 M3 完成了各自的当前工序。M1 完成的是“转换”工序,开始执行新的任务,从队列中选择第一个任务——3号任务。3 号任务第一个工序的长度为4,因此该工序的结束时间为8,M1的完成时间变为8。2号任务在M3上完成其第一道工序之后移至M1上继续执行,由于 M1正忙,所以 2号任务被放入 M1 的队列。M3进入转换状态,转换状态的结束时刻为 5。以此类推,能够推出剩余的事件序列。

在这里插入图片描述

代码

main.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			main()函数,控制运行所有的测试函数
*/#include "_22factorySim.h"int main()
{factorySimTest();return 0;
}

_22factorySim.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月17日09点22分
Last Version:			V1.0
Descriptions:			工厂仿真头文件
*/
#pragma once
#include <iostream>
#include "_1myExceptions.h"
#include "_22task.h"
#include "_22job.h"
#include "_22machine.h"
#include "_22eventList.h"
#ifndef _FACTORYSIM_H_
#define _FACTORYSIM_H_
/*测试函数*/
void factorySimTest();
/*输入工厂数据*/
void inputData();
/*启动仿真*/
void startShop();
/*修改机器状态*/
job* changeState(int theMachine);
/*处理所有任务*/
void simulate();
/*把一项任务移至下一道工序对应的机器*/
bool moveToNextMachine(job* theJob);
/*输出每台机器的等待时间*/
void outputStatistics();
#endif

_22factorySim.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月17日09点22分
Last Version:			V1.0
Descriptions:			工厂仿真cpp文件,使用了数组队列
*/
#include "_22factorySim.h"
using namespace std;
/*全局变量*/
int timeNow = 0;//当前时间,初始状态为0
int numMachines;//机器数量
int numJobs;//任务数量
eventList* eList;//事件表的指针
machine* mArray;//机器数组
int largeTime = 10000;//在这个时间之前所有机器都已经完成工作void factorySimTest()
{inputData();//获取机器和任务的数据startShop();//装入初始任务simulate();//执行所有任务outputStatistics();//输出在每台机器上的等待时间
}/*输入工厂数据*/
void inputData()
{//输入工厂数据cout << "Enter number of machines and jobs:";while (!(cin >> numMachines>>numJobs)){cin.clear();//清空标志位while (cin.get() != '\n')//删除无效的输入continue;cout << "Enter number of machines and jobs:";}if (numMachines < 1 || numJobs < 1)throw illegalInputData("number of machines and jobs must be >=1");//生成事件和机器队列eList = new eventList(numMachines, largeTime);//初始化时所有机器都空闲mArray = new machine[numMachines + 1];//mArray[0]未使用//输入机器的转换时间int ct;for (int j = 1; j <= numMachines; j++){cout << "Enter change-over times for machines " << j << " :";while (!(cin >> ct)){cin.clear();//清空标志位while (cin.get() != '\n')//删除无效的输入continue;cout << "Enter change-over times for machines " << j << " :" ;}if (ct < 0)throw illegalInputData("change-over time must be >= 0");mArray[j].changeTime = ct;//这里没问题,但是警告我也不知道为什么}//输入任务job* theJob;int numTasks, firstMachine, theMachine, theTaskTime;for (int i = 1; i <= numJobs; i++){cout << "Enter number of tasks for job " << i << " :";while (!(cin >> numTasks)){cin.clear();//清空标志位while (cin.get() != '\n')//删除无效的输入continue;cout << "Enter number of tasks for job " << i << " :";}firstMachine = 0;//第一道工序的机器if (numTasks < 1)throw illegalInputData("each job must have > 1 task");//生成任务theJob = new job(i);//job的id为icout << "Enter the tasks (machine,time) in process order" << endl;for (int j = 1; j <= numTasks; j++){while (!(cin >> theMachine>>theTaskTime)){cin.clear();//清空标志位while (cin.get() != '\n')//删除无效的输入continue;cout << "Error!Please re-enter:" << endl;}if (theMachine < 1 || theTaskTime<1 || theMachine>numMachines)throw illegalInputData("bad machines number or task time");if (j == 1)firstMachine = theMachine;//处理任务的第一台机器theJob->addTask(theMachine, theTaskTime);}mArray[firstMachine].jobQ.push(theJob);//将任务输入到机器的队列中}
}
/*启动仿真*/
void startShop()
{//在每台机器上装载其第一个任务for (int p = 1; p <= numMachines; p++)changeState(p);
}
/*修改机器状态*/
job* changeState(int theMachine)
{//机器theMachine上的工序完成了,调度下一道工序//返回值是在机器theMachine上刚刚完成的任务job* lastJob;if (mArray[theMachine].activeJob == nullptr){//处于空闲或转换状态lastJob = nullptr;if (mArray[theMachine].jobQ.empty())//没有等待执行的任务eList->setFinishTime(theMachine, largeTime);else{//从队列中提取任务,在机器上执行mArray[theMachine].activeJob = mArray[theMachine].jobQ.front();mArray[theMachine].jobQ.pop();mArray[theMachine].totalWait += (timeNow - mArray[theMachine].activeJob->arrivalTime);mArray[theMachine].numTasks++;cout << "(" << mArray[theMachine].activeJob->taskQ.front().machine << "," << mArray[theMachine].activeJob->taskQ.front().time << ")" << "finished!" << endl;//cout << "timeNow = " << timeNow << endl;int t = mArray[theMachine].activeJob->removeNextTask();eList->setFinishTime(theMachine, timeNow + t);}}else{//在机器theMachine上刚刚完成一道工序//设置转换时间lastJob = mArray[theMachine].activeJob;mArray[theMachine].activeJob = nullptr;eList->setFinishTime(theMachine, timeNow + mArray[theMachine].changeTime);}return lastJob;
}
/*处理所有任务*/
void simulate()
{//处理所有未处理的任务while (numJobs > 0){//至少有一个任务未处理int nextToFinish = eList->nextEventMachine();timeNow = eList->nextEventTime(nextToFinish);//cout << "sim timeNow = " << timeNow << endl;//改变机器nextToFinist上的任务job* theJob = changeState(nextToFinish);//把任务theJob调度到下一台机器//如果任务theJob完成,则减少任务数if (theJob != nullptr && !moveToNextMachine(theJob))numJobs--;}
}
/*把一项任务移至下一道工序对应的机器*/
bool moveToNextMachine(job* theJob)
{//调度任务theJob到执行其下一道工序的机器//如果任务已经完成,则返回falseif (theJob->taskQ.empty()){cout << "Job " << theJob->id << " has completed at " << timeNow <<" Total wait was " << (timeNow - theJob->length) << endl;return false;}else{//任务theJob有下一道工序//确定执行下一道工序的机器int p = theJob->taskQ.front().machine;//把任务插入机器p的等待任务队列mArray[p].jobQ.push(theJob);theJob->arrivalTime = timeNow;//如果机器p空闲,则改变它的状态if (eList->nextEventTime(p) == largeTime)changeState(p);return true;}
}
/*输出每台机器的等待时间*/
void outputStatistics()
{cout << "Finish time = " << timeNow << endl;for (int p = 1; p <= numMachines; p++){cout << "Machine " << p << " completed " << mArray[p].numTasks << " tasks" << endl;cout << "The total wait time was " << mArray[p].totalWait << endl;cout << endl;}
}

_22task.h

每个工序都由两部分构成:machine(执行该工序的机器)和time(完成该工序所需要的时间)。

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月17日09点22分
Last Version:			V1.0
Descriptions:			工序:包括执行该工序的机器machine和完成该工序所需要的时间time
*/
#pragma once
#ifndef _TASK_H_
#define _TASK_H_
#include<iostream>
using std::ostream;
/*工序:包括执行该工序的机器machine和完成该工序所需要的时间time*/
struct task
{int machine;int time;task(int theMachine = 0, int theTime = 0){machine = theMachine;time = theTime;}friend ostream& operator<<(ostream& out, const task x){out << "(" << x.machine << "," << x.time << ")";return out;}
};
#endif

_22job.h

每项任务都有一个工序表,每道工序按表中的顺序执行。可以把工序表描述成一个队列工taskQ。为了计算一项任务的总等待时间,需要知道该任务的长度和完成时间。完成时间通过计时确定,任务长度为各工序时间之和。为了计算任务长度,我们定义一个数据成员length。

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月17日09点22分
Last Version:			V1.0
Descriptions:			任务
*/
#pragma once
#ifndef _JOB_H_
#define _JOB_H_
#include <queue>
#include "_22task.h"
/*任务*/
struct job
{queue<task> taskQ;//任务的工序队列int length;//被调度的工序时间之和int arrivalTime;//到达当前队列的时间int id;//任务标识符job(int theId = 0){id = theId;length = 0;arrivalTime = 0;}void addTask(int theMachine, int theTime){//添加任务task theTask(theMachine, theTime);taskQ.push(theTask);}/*删除任务的下一道工序,返回它的时间;更新长度*/int removeNextTask(){int theTime = taskQ.front().time;taskQ.pop();length += theTime;return theTime;}
};
#endif

_22machine.h

每台机器都有转换时间、当前任务和等待任务的队列。由于每项任务在任何时刻只会在一台机器队列中,因此所有队列的空间总量以任务的数目为限。不过,任务在各个机器队列中的分布随着仿真过程的进展会不断变化。有的队列在某一时刻可能很长。如果使用链队列,就可以把机器队列所需要的空间限制为 n 个节点的空间,其中 n 是任务个数。

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月17日09点22分
Last Version:			V1.0
Descriptions:			机器
*/
#pragma once
#ifndef _MACHINE_H_
#define _MACHINE_H_
#include<queue>
#include "_22job.h"
/*机器*/
struct machine
{queue<job*> jobQ;//本机器的等待处理的任务队列int changeTime;//本机器的转换时间int totalWait;//本机器的总体延时int numTasks;//本机器处理的工序数量job* activeJob;//本机器当前处理的任务machine(){changeTime = 0;totalWait = 0;numTasks = 0;activeJob = nullptr;}
};
#endif

_22eventList.h

所有机器的完成时间都存储在一个事件表中。为了从一个事件转向下一个事件,我们需要在机器的完成时间中确定最小者。仿真器还需要一个操作,来设置一台特定机器的完成时间。每当一个新任务被调度到一台机器上运行时就要执行该操作。当一台机器空闲时,其完成时间被设置成一个很大的数 largeTime。

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月17日09点22分
Last Version:			V1.0
Descriptions:			事件
*/
#pragma once
#ifndef _EVENTLIST_H_
#define _EVENTLIST_H_
class eventList
{
public:/*为m台机器,初始化其完成时间*/eventList(int theNumMachines, int theLargeTime){if (theNumMachines < 1)throw illegalParameterValue("number of machines must be >= 1");numMachines = theNumMachines;finishTime = new int[numMachines + 1];//所有机器都空闲,用大的完成时间初始化for (int i = 1; i <= numMachines; i++)finishTime[i] = theLargeTime;}/*返回值是处理下一项工序的机器,某个机器完成了*/int nextEventMachine(){int p = 1;int t = finishTime[1];for (int i = 2; i <= numMachines; i++){if (finishTime[i] < t){p = i;t = finishTime[i];}}return p;}/*知道处理下一项工序的机器,获取该机器的完成时间*/int nextEventTime(int theMachine){return finishTime[theMachine];}/*设置机器的完成时间*/void setFinishTime(int theMachine, int theTime){finishTime[theMachine] = theTime;}
private:int* finishTime;//机器完成时间数组int numMachines;//机器数量
};
#endif

_1myExceptions.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			综合各种异常
*/
#pragma once
#ifndef _MYEXCEPTIONS_H_
#define _MYEXCEPTIONS_H_
#include <string>
#include<iostream>using namespace std;// illegal parameter value
class illegalParameterValue
{
public:illegalParameterValue(string theMessage = "Illegal parameter value"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// illegal input data
class illegalInputData
{
public:illegalInputData(string theMessage = "Illegal data input"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// illegal index
class illegalIndex
{
public:illegalIndex(string theMessage = "Illegal index"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// matrix index out of bounds
class matrixIndexOutOfBounds
{
public:matrixIndexOutOfBounds(string theMessage = "Matrix index out of bounds"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// matrix size mismatch
class matrixSizeMismatch
{
public:matrixSizeMismatch(string theMessage ="The size of the two matrics doesn't match"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// stack is empty
class stackEmpty
{
public:stackEmpty(string theMessage ="Invalid operation on empty stack"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// queue is empty
class queueEmpty
{
public:queueEmpty(string theMessage ="Invalid operation on empty queue"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// hash table is full
class hashTableFull
{
public:hashTableFull(string theMessage ="The hash table is full"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// edge weight undefined
class undefinedEdgeWeight
{
public:undefinedEdgeWeight(string theMessage ="No edge weights defined"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};// method undefined
class undefinedMethod
{
public:undefinedMethod(string theMessage ="This method is undefined"){message = theMessage;}void outputMessage() {cout << message << endl;}
private:string message;
};
#endif

运行结果

"C:\Users\15495\Documents\Jasmine\prj\_Algorithm\Data Structures, Algorithms and Applications in C++\_19Factory simulation\cmake-build-debug\_19Factory_simulation.exe"
Enter number of machines and jobs:3 4
Enter change-over times for machines 1 :2
Enter change-over times for machines 2 :3
Enter change-over times for machines 3 :1
Enter number of tasks for job 1 :3
Enter the tasks (machine,time) in process order
1 2
2 4
1 1
Enter number of tasks for job 2 :2
Enter the tasks (machine,time) in process order
3 4
1 2
Enter number of tasks for job 3 :2
Enter the tasks (machine,time) in process order
1 4
2 4
Enter number of tasks for job 4 :2
Enter the tasks (machine,time) in process order
3 1
2 3
(1,2)finished!
(3,4)finished!
(2,4)finished!
(1,4)finished!
(3,1)finished!
(2,3)finished!
(1,2)finished!
Job 2 has completed at 12 Total wait was 6
Job 4 has completed at 12 Total wait was 8
(1,1)finished!
Job 1 has completed at 15 Total wait was 8
(2,4)finished!
Job 3 has completed at 19 Total wait was 11
Finish time = 19
Machine 1 completed 4 tasks
The total wait time was 18Machine 2 completed 3 tasks
The total wait time was 10Machine 3 completed 2 tasks
The total wait time was 5Process finished with exit code 0

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

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

相关文章

Python数据结构:集合(set)详解

1.集合的概念 在Python中&#xff0c;集合&#xff08;Set&#xff09;是一种无序、不重复的数据类型&#xff0c;它的实现基于哈希表&#xff0c;是由唯一元素组成的。集合中不允许有重复的元素&#xff0c;即相同元素只能出现一次。Python中的集合类似于数学中的集合&#xf…

Java14新增特性

前言 前面的文章&#xff0c;我们对Java9、Java10、Java11、Java12 、Java13的特性进行了介绍&#xff0c;对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 今天我们来一起看一下Java14这个版本的一些重要信息 版本介绍 Java 14…

JNDI注入

1、什么是 JNDI JNDI(Java Naming and Directory Interface, Java命名和目录接口)&#xff0c;JNDI API 映射为特定的命名&#xff08;Name&#xff09;和目录服务&#xff08;Directory&#xff09;系统&#xff0c;使得Java应用程序可以和这些命名&#xff08;Name&#xff…

【Shell脚本11】Shell 函数

Shell 函数 linux shell 可以用户定义函数&#xff0c;然后在shell脚本中可以随便调用。 shell中函数的定义格式如下&#xff1a; [ function ] funname [()]{action;[return int;]}说明&#xff1a; 1、可以带function fun() 定义&#xff0c;也可以直接fun() 定义,不带任何…

旺店通·企业版对接打通金蝶云星空查询调拨单接口与分布式调入单新增接口

旺店通企业版对接打通金蝶云星空查询调拨单接口与分布式调入单新增接口 源系统:旺店通企业版 旺店通是北京掌上先机网络科技有限公司旗下品牌&#xff0c;国内的零售云服务提供商&#xff0c;基于云计算SaaS服务模式&#xff0c;以体系化解决方案&#xff0c;助力零售企业数字化…

Android framework添加自定义的Product项目,lunch目标项目

文章目录 Android framework添加自定义的Product项目1.什么是Product&#xff1f;2.定义自己的Product玩一玩 Android framework添加自定义的Product项目 1.什么是Product&#xff1f; 源码目录下输入lunch命令之后&#xff0c;简单理解下面这些列表就是product。用于把系统编…

如何显示标注的纯黑mask图

文章目录 前言一、二分类mask显示二、多分类mask显示 前言 通常情况下&#xff0c;使用标注软件标注的标签图看起来都是纯黑的&#xff0c;因为mask图为单通道的灰度图&#xff0c;而灰度图一般要像素值大于128后&#xff0c;才会逐渐显白&#xff0c;255为白色。而标注的时候…

sass 生成辅助色

背景 一个按钮往往有 4 个状态。 默认状态hover鼠标按下禁用状态 为了表示这 4 个状态&#xff0c;需要设置 4 个颜色来提示用户。 按钮类型一般有 5 个&#xff1a; 以 primary 类型按钮为例&#xff0c;设置它不同状态下的颜色&#xff1a; <button class"btn…

IP-guard Webserver view 远程命令执行漏洞【2023最新漏洞】

IP-guard Webserver view 远程命令执行漏洞【2023最新漏洞】 一、漏洞描述二、漏洞影响三、漏洞危害四、FOFA语句五、漏洞复现1、手动复现yaml pocburp发包 2、自动化复现小龙POC检测工具下载地址 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传…

R程序 示例4.3.2版本包 在centos进行编译部署

为了在CentOS上下载和编译R语言4.3.2包&#xff0c;可以按照以下步骤进行操作&#xff1a; 1.首先&#xff0c;需要安装一些必要的依赖项。可以使用以下命令安装它们&#xff1a; sudo yum install -y epel-release sudo yum install -y gcc gcc-c gcc-gfortran readline-dev…

Linux 使用随记

Linux 使用随记 shell 命令行模式登录后所取得的程序被成为shell&#xff0c;这是因为这个程序负责最外层的跟用户&#xff08;我们&#xff09;通信工作&#xff0c;所以才被戏称为shell。 命令 1、命令格式 command [-options] parameter1 parameter2 … 1、一行命令中第…

C#几种截取字符串的方法

在C#编程中&#xff0c;经常需要对字符串进行截取操作&#xff0c;即从一个长字符串中获取所需的部分信息。本文将介绍几种常用的C#字符串截取方法&#xff0c;并提供相应的示例代码。 目录 1. 使用Substring方法2. 使用Split方法3. 使用Substring和IndexOf方法4. 使用Regex类…

HBase学习笔记(3)—— HBase整合Phoenix

目录 Phoenix Shell 操作 Phoenix JDBC 操作 Phoenix 二级索引 HBase整合Phoenix Phoenix 简介 Phoenix 是 HBase 的开源 SQL 皮肤。可以使用标准 JDBC API 代替 HBase 客户端 API来创建表&#xff0c;插入数据和查询 HBase 数据 使用Phoenix的优点 在 Client 和 HBase …

uni-app报错“本应用使用HBuilderX x.x.x 或对应的cli版本编译,而手机端SDK版本是x.x.x不匹配的版本可能造成应用异常”

uniapp开发的一个跨平台软件&#xff0c;在安卓模拟器上启动的时候报警告&#xff1a; 官方给的解释&#xff1a;uni-app运行环境版本和编译器版本不一致的问题 - DCloud问答 解决办法有两个 方法一&#xff1a;添加忽略警告的配置 项目根目录下找到 manifest.json&#xf…

计算机毕业设计 基于SpringBoot的销售项目流程化管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

微信小程序 解决tab页切换过快 数据出错问题

具体问题&#xff1a;切换tab页切换过快时,上一个列表接口未响应完和当前列表数据冲突 出现数据错误 具体效果如下&#xff1a; 解决方式&#xff1a;原理 通过判断是否存在request 存在中断 并发送新请求 不存在新请求 let shouldAbort false; // 添加一个中断标志 let re…

量化交易:使用 python 进行股票交易回测

执行环境: Google Colab 1. 下载数据 import yfinance as yfticker ZM df yf.download(ticker) df2. 数据预处理 df df.loc[2020-01-01:].copy()使用了 .loc 方法来选择索引为 ‘2020-01-01’ 以后的所有行数据。通过 .copy() 方法创建了一个这些数据的副本&#xff0c;确…

星宿UI2.51资源付费变现小程序 支持流量主广告投放

目前&#xff0c;最新版的星宿UI是2.51版本。要搭建星宿UI&#xff0c;您需要准备备用域名、服务器和微信小程序账号。星宿UI提供了多项功能&#xff0c;包括文章展示、文章分类、资源链接下载和轮播图等。此外&#xff0c;还支持直接下载附件功能。这些功能使得星宿UI非常适合…

阶段七-Day01-SpringMVC

一、Sping MVC的介绍 1. 使用Front(前端)设计模式改写代码 1.1 目前我们的写法 目前我们所写的项目&#xff0c;持久层、业务层的类都放入到Spring容器之中了。他们之间需要注入非常方便&#xff0c;只需要通过Autowired注解即可。 但是由于Servlet整个生命周期都是被Tomca…