算法设计与分析实验报告c++实现(最近点对问题、循环赛日程安排问题、排序问题、棋盘覆盖问题)

news2024/11/24 23:03:59

一、实验目的

1.加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。

二、实验任务

1、最近对问题
设p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n个点构成的集合S,设计算法找出集合S中距离最近的点对。
(1)分别用蛮力法和分治法求解最近对问题;
(2)分析算法的时间性能,设计实验程序验证分析结论。
2、循环赛日程安排问题
设有n=2k个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次。

3、排序问题
目前已知有几十种排序算法,请查找资料,并尽可能多地实现多种排序算法,并分析算法的时间复杂度。比较各种算法的优劣(冒泡排序、选择排序、插入排序、二分插入排序、希尔排序、归并排序、堆排序、快速排序等,需比较分析各种算法的时间复杂度及排序的稳定性)

4、用分治策略,设计解棋盘覆盖问题的一个简洁算法

三、实验设备及编程开发工具

编程开发工具:Microsoft Visual c++

四、实验过程设计(算法设计过程)

(一)最近对问题

1、基本算法思想
蛮力法:在蛮力法实现最近点对问题中,将问题简化:距离最近的点对可能多于一对,找出一对即可,另外只考虑二维平面中的情况。此处考虑到直接用公式计算其距离(欧几里得距离)。通过遍历所有点集,计算出每一个点对的距离,计算出最近的距离并输出。避免同一对点计算两次,只考虑i<j的点对(pi,pj)。
分治法:在利用分治法思想解决此问题时,首先考虑将最近对问题进行分治,设计其分治策略。将集合S分成两个子集S1和S2,根据平衡子问题原则,每个子集中的点数大致都为n/2。这样分治后,最近点对将会出现三种情况:在S1中,在S2中或者最近点对分别在集合S1和S2中。利用递归分析法分别计算前两种情况,第三种方法另外分析。求解出三类子情况后,再合并三类情况,比较分析后输出三者中最小的距离。
2、源程序

#include<iostream>
#include<stdio.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<windows.h>
using namespace std;
 
struct point {
    double x;
    double y;
}P[100];
double distance(point p1, point p2) {
    return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
}
bool cmp1(point p1, point p2) {
    return p1.x < p2.x;
}
bool cmp2(point p1, point p2) {
    return p1.y < p2.y;
}
//蛮力法
double get_min(int n)
{
    double min = sqrt((P[0].x - P[1].x)*(P[0].x - P[1].x) + (P[0].y - P[1].y)*(P[0].y - P[1].y));//设置第一个计算值最短距离
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            double t = sqrt((P[i].x - P[j].x)*(P[i].x - P[j].x) + (P[i].y - P[j].y)*(P[i].y - P[j].y));
            if (min>t)
                min = t;
        }//循环比较计算值
    }
    return min;
}
//分治法
double nearest_pair(point S[],int left,int right) {
    cout << left << " " << right << endl;
    if (right-left == 1) {
        return distance(S[right], S[left]);
    }
    if (right - left == 2) {
        double d1 = distance(S[right], S[left]);
        double d2 = distance(S[right], S[right + 1]);
        double d3 = distance(S[right + 1], S[left]);
        d2 = min(d1, d2);
        d3 = min(d2, d3);
        return d3;
    }
    int m = (right+left) / 2;
    double d1 = nearest_pair(S,left, m);
    double d2 = nearest_pair(S, m+1,right);
    //sort(S+right, S+left, cmp2);
    double d = min(d1, d2);
    int l = left, r = right;
    while (S[l].x < S[m].x - d && l <= right);
        l++;
    while (S[r].x > S[m].x + d && r>=left)
        r++;
    sort(S + 1, S + r + 1, cmp2);
    double d3;
    for (int i = l; i <= r; i++) {
        for (int j = i + 1; j <= r; j++) {
            if (S[j].y - S[i].y >= d) {
                break;
            }
            else {
                d3 = distance(S[i], S[j]);
                if (d3 < d)
                    d = d3;
            }
        }
    }
    return d;
}
int main()
{
    int n;
    cout << "Input n:";//设置平面中点的个数
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cout << "Input the " << i << "th number:";
        cin >> P[i].x >> P[i].y;
    }//逐个设置第i个点的坐标
    sort(P + 1, P + n+1, cmp1);
    for ( i = 1; i <= n; i++) {
        cout << P[i].x << " " << P[i].y << endl;
    }
    double m = get_min(n);
    cout <<"蛮力法结果:"<< m << endl;//蛮力法输出结果
    double m2 = nearest_pair(P, 1, n);
    cout <<"分治法结果:" <<m2 << endl;//分治法输出结果
    system("pause");
    return 0;
}

(二)循环赛日程安排问题

1、基本算法思想
假设n位选手被顺序编号为1,2,…,n,比赛的日程表是一个n行n-1列的表格,i行j列的表格内容是第i号选手在第j天的比赛对手。
根据分而治之的原则,可从其中一半选手(2^(n-1位)的比赛日程,导出全体n位选手的日程,最终细分到只有两位选手的比赛日程出发。
2、源程序

#include<stdio.h>
#include<math.h>
#define N 50
void GameTable(int k,int array[][N]);
void print(int k,int array[][N]);         //输出二维数组 
main()
{
    int k;
    int array[N][N];
    printf("参赛选手的人数为n(n=2^k),请输入k 的值:");
    do
    {
         scanf("%d",&k);
        if(k>0)
        {
            GameTable(k,array);
            print(k,array);
        }
        else
          printf("您输入的数据有误,请重新输入"); 
    }while(k!=0);//排除输入错误k值

}
void GameTable(int k,int array[][N])//数组下标从1开始
{
    int i,j,s,t;
    int n=1;
    for(i=1;i<=k;i++)
        n*=2;                       //求总人数
    for(i=1;i<=n;i++)
        array[1][i]=i;                  //第一行排1-8
    int m=1;                          //用来控制每一次填表时i行j列的起始填充位置
    for(s=1;s<=k;s++)                 //s指对称赋值的总循环次数,即分成几大步进行制作日程表
    {
        n=n/2;
        for(t=1;t<=n;t++)              //t指明内部对称赋值的循环次数
            for(i=m+1;i<=2*m;i++)
                for(j=m+1;j<=2*m;j++)
                {
                    array[i][j+(t-1)*m*2]=array[i-m][j+(t-1)*m*2-m];       //右上角等于左上角的值
                    array[i][j+(t-1)*m*2-m]=array[i-m][j+(t-1)*m*2];       //左下角等于右上角的值
                }
        m*=2;
    }
    
}
void print(int k,int array[][N])
{
    int i,j;
    int num=pow(2,k);
    printf("%d人的循环赛日程表如下:\n",num);
    for(i=1;i<=num;i++)                           //输出二维数组 
    {
        for(j=1;j<=num;j++)
        {
            printf("%d\t",array[i][j]);
        }
         printf("\n");
    }
}

(三)排序问题

(1)直接插入排序

将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。

void InsertSort(int a[], int n)
{
	for(int i= 1; i<n; i++){
		if(a[i] < a[i-1]){//若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
			int j= i-1;	
			int x = a[i];		 //复制为哨兵,即存储待排序元素
			a[i] = a[i-1];           //先后移一个元素
			while(x < a[j]){	 //查找在有序表的插入位置
				a[j+1] = a[j];
				j--;		 //元素后移
			}
			a[j+1] = x;		 //插入到正确位置
		}
		print(a,n,i);			//打印每趟排序的结果 
	}
}

(2)希尔排序

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

void ShellInsertSort(int a[], int n, int dk)
{
	for(int i= dk; i<n; ++i){
		if(a[i] < a[i-dk]){			//若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
			int j = i-dk;	
			int x = a[i];			//复制为哨兵,即存储待排序元素
			a[i] = a[i-dk];			//首先后移一个元素
			while(x < a[j]){		//查找在有序表的插入位置
				a[j+dk] = a[j];
				j -= dk;			 //元素后移
			}
			a[j+dk] = x;			//插入到正确位置
		}
		print(a, n,i );
	}
	
}
 
/**
 * 先按增量d(n/2,n为要排序数的个数进行希尔排序
 *
 */
void shellSort(int a[], int n){
 
	int dk = n/2;
	while( dk >= 1  ){
		ShellInsertSort(a, n, dk);
		dk = dk/2;
	}
}

(3)简单选择排序

int SelectMinKey(int a[], int n, int i)
{
	int k = i;
	for(int j=i+1 ;j< n; ++j) {
		if(a[k] > a[j]) k = j;
	}
	return k;
}
 
/**
 * 选择排序
 *
 */
void selectSort(int a[], int n){
	int key, tmp;
	for(int i = 0; i< n; ++i) {
		key = SelectMinKey(a, n,i);           //选择最小的元素
		if(key != i){
			tmp = a[i];  a[i] = a[key]; a[key] = tmp; //最小元素与第i位置元素互换
		}
		print(a,  n , i);
	}
}

(4)冒泡排序

两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

void BubbleSort(int *p, int length)
{
    for (int i = 0; i < length-1; i++)
    {
        for (int j =length-1; j>=i;j--)
        {
            if (p[j-1] > p[j])
            {
                swap(p[j-1], p[j]);
            }
        }
    }
}

(5)堆排序

堆排序的基本思想(利用堆,如大顶堆进行排序):将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将它与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余n-1个序列重新构造成一个堆,这样就会得到n个元素的次小值。如此反复执行,便能得到一个有序序列。

//构造最大堆void MaxHeapFixDown(int *p, int i, int length) {
    int j = 2 * i + 1;
    int temp = p[i];
    while (j<length) {
        if (j + 1<length && p[j]<p[j + 1])
            ++j;
        if (temp>p[j])
            break;
        else {
            p[i] = p[j];
            i = j;
            j = 2 * i + 1;
        }
    }
    p[i] = temp;
}
//堆排序void HeapSort(int *p, int length) {
    for (int i = length / 2 - 1; i >= 0; i--)
    {
        MaxHeapFixDown(p, i, length);
    }
    for (int i = length - 1; i >= 1; i--)
    {
        swap(p[i], p[0]);
        MaxHeapFixDown(p, 0, i);
        cout << "i的值:" << i << " 排序:";
        ergodic(p, 9);
    }
}

(6)归并排序

归并排序就是利用归并思想实现的排序方法。原理:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列长度为1,然后再两两归并,得到[n/2]个长度为2或1的有序子序列;再两两归并….,如此重复,直到的一个长度为n的有序序列为止,称为2路归并排序。

//将r[i…m]和r[m +1 …n]归并到辅助数组rf[i…n]
void Merge(ElemType *r,ElemType *rf, int i, int m, int n)
{
	int j,k;
	for(j=m+1,k=i; i<=m && j <=n ; ++k){
		if(r[j] < r[i]) rf[k] = r[j++];
		else rf[k] = r[i++];
	}
	while(i <= m)  rf[k++] = r[i++];
	while(j <= n)  rf[k++] = r[j++];
}

void MergeSort(ElemType *r, ElemType *rf, int lenght)
{ 
	int len = 1;
	ElemType *q = r ;
	ElemType *tmp ;
	while(len < lenght) {
		int s = len;
		len = 2 * s ;
		int i = 0;
		while(i+ len <lenght){
			Merge(q, rf,  i, i+ s-1, i+ len-1 ); //对等长的两个子表合并
			i = i+ len;
		}
		if(i + s < lenght){
			Merge(q, rf,  i, i+ s -1, lenght -1); //对不等长的两个子表合并
		}
		tmp = q; q = rf; rf = tmp; //交换q,rf,以保证下一趟归并时,仍从q 归并到rf
	}
}

(7)快速排序

1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序

void swap(int *a, int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int partition(int a[], int low, int high)
{
	int privotKey = a[low];								//基准元素
	while(low < high){								    //从表的两端交替地向中间扫描
		while(low < high  && a[high] >= privotKey) --high;  //从high 所指位置向前搜索,至多到low+1 位置。将比基准元素小的交换到低端
		swap(&a[low], &a[high]);
		while(low < high  && a[low] <= privotKey ) ++low;
		swap(&a[low], &a[high]);
	}
	print(a,10);
	return low;
}
void quickSort(int a[], int low, int high){
	if(low < high){
		int privotLoc = partition(a,  low,  high);  //将表一分为二
		quickSort(a,  low,  privotLoc -1);			//递归对低子表递归排序
		quickSort(a,   privotLoc + 1, high);		//递归对高子表递归排序
	}
}

(四)棋盘覆盖问题

1、基本算法原理
当k>0时,将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘(a)所示。特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为棋盘1×1
2、源代码

//棋盘覆盖问题
/*
(tr,tc)是棋盘左上角的方格坐标
(dr,dc)是特殊方格所在的坐标
size是棋盘的行数和列数
*/
#include<iostream>
using namespace std;
int board[1025][1025];
static int tile = 1;
void ChessBoard(int tr,int tc,int dr,int dc,int size)
{
	if(size==1) 
		return ;//递归边界
	int t=tile++;//L型骨牌号
	int s=size/2;//分割棋盘
	//覆盖左上角子棋盘
	if(dr<tr+s && dc<tc+s)
		ChessBoard(tr,tc,dr,dc,s);//特殊方格在此棋盘中
	else //此棋盘中无特殊方格,用t号L型骨牌覆盖右下角
	{
		board[tr+s-1][tc+s-1]=t;
		//覆盖其余方格
		ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
	}
	//覆盖右上角子棋盘
	if(dr<tr+s && dc>=tc+s)
		ChessBoard(tr,tc+s,dr,dc,s);//特殊方格在此棋盘中
	else //此棋盘中无特殊方格,用t号L型骨牌覆盖左下角
	{
		board[tr+s-1][tc+s]=t;
		//覆盖其余方格
		ChessBoard(tr,tc+s,tr+s-1,tc+s,s);
	}
	//覆盖左下角子棋盘
	if(dr>=tr+s && dc<tc+s)//特殊方格在此棋盘中
		ChessBoard(tr+s,tc,dr,dc,s);
	else //此棋盘中无特殊方格,用t号L型骨牌覆盖右上角
	{
		board[tr+s][tc+s-1]=t;
		//覆盖其余方格
		ChessBoard(tr+s,tc,tr+s,tc+s-1,s);
	}
	//覆盖右下角子棋盘
	if(dr>=tr+s && dc>=tc+s)//特殊方格在此棋盘中
		ChessBoard(tr+s,tc+s,dr,dc,s);
	else //此棋盘中无特殊方格,用t号L型骨牌覆盖左上角
	{
		board[tr+s][tc+s]=t;
		//覆盖其余方格
		ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
	}
}
int main()
{
	int i,j;
	int k;//棋盘大小为2^k
	cout<<"棋盘大小为2^k,请输入k的值:";
	while(cin>>k)
	{
		int size = 1<<k;
		int x,y;//x,y为特殊方格的坐标
		cout<<"请输入特殊方格的坐标:";
		cin>>x>>y;
		board[x][y]=0;
		ChessBoard(0, 0, x, y, size);
		for(i=0; i<size; i++)
		{
			for(j = 0; j < size; j++)
				cout<< board[i][j]<<"\t";
				cout<<"\n";
		}
	}
return 0;
}

五、实验结果及算法复杂度分析
(一)最近对问题
1、实验结果

img

2、时间复杂度
蛮力法:O(n^2)
分治法:O(nlog2n)
(二)循环赛日程安排问题
1、实验结果

img

2、时间复杂度
时间复杂度:O(2^k * 2^k)

(三)排序问题
1、实验结果

1、直接插入排序

img

2、 希尔排序

img

3、简单选择排序

img

4、冒泡排序

img

5、 堆排序

img

7、快速排

img

2、时间复杂度
1、直接插入排序时间复杂度:O(n^2);
2、 希尔排序时间复杂度:O(n^2);
3、简单选择排序时间复杂度:O(n^2);
4、冒泡排序时间复杂度:O(n^2);
5、 堆排序时间复杂度:O(nlog2n);
6、 归并排序时间复杂度:O(n
log n);
7、快速排序时间复杂度:0(n^2)。

(四)棋盘覆盖问题
1、实验结果

img

2、时间复杂度
最坏时间复杂度:O(4^k)

实验小结(包括问题和解决方法、心得体会等)

本次实验的中心思想就是分治法,在课堂教学中老师就对分治法进行了比较深刻的讲解,再加上在网上百度就对分治法有了比较清楚的认识,字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。在通过实验的四道题目的实践,相信自己对分治法已经足够掌握了。

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

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

相关文章

《剑指 Offer》专项突破版 - 面试题 107 : 矩阵中的距离(C++ 实现)

题目链接&#xff1a;矩阵中的距离 题目&#xff1a; 输入一个由 0、1 组成的矩阵 M&#xff0c;请输出一个大小相同的矩阵 D&#xff0c;矩阵 D 中的每个格子是矩阵 M 中对应格子离最近的 0 的距离。水平或竖直方向相邻的两个格子的距离为 1。假设矩阵 M 中至少有一个 0。 …

Google 推出 Gemini 1.5 Pro能处理音频;iOS 18或带来Safari 浏览助手;Llama 3 开源模型下个月推出

Google 推出 Gemini 1.5 Pro 公共预览版&#xff0c;能处理音频 Google 宣布将通过其 AI 应用平台 Vertex AI 向公众提供 Gemini 1.5 Pro&#xff0c;并且还赋予其「听力」&#xff0c;帮助用户处理音频内容。 用户可以上传会议录音、电视节目等音频内容&#xff0c;无需书面记…

Python计算多个表格中多列数据的平均值与标准差并导出为新的Excel文件

本文介绍基于Python语言&#xff0c;对一个或多个表格文件中多列数据分别计算平均值与标准差&#xff0c;随后将多列数据对应的这2个数据结果导出为新的表格文件的方法。 首先&#xff0c;来看一下本文的需求。现有2个.csv格式的表格文件&#xff0c;其每1列表示1个变量&#x…

如何入门做物联网系统压测?

文章目录 一、政策解读二、MQTT 压测常见场景三、MQTT常见业务场景1、并发连接2、消息吞吐量测试2.1 1 对 12.2 多对1&#xff08;上报&#xff09;2.3 1对多2.4 其它场景 三、MQTT常见性能指标四、MQTT常见性能工具1、emqtt-bench2、JMeter 五、小结 一、政策解读 微信公众号…

功能测试_验证标题长度合法性_边界值法

验证标题长度合法性&#xff08;标题长度大于0&#xff0c;小于等于30个字符&#xff09; 开内闭外&#xff0c;保留1和31

《web应用技术》第三次课后练习

实验目的&#xff1a; 1、springboot入门程序撰写并启动 2、使用postman练习参数的获取。 参考&#xff1a;Day04-10. Web入门-SpringBootWeb-快速入门_哔哩哔哩_bilibili

Java | Leetcode Java题解之第16题最接近的三数之和

题目&#xff1a; 题解&#xff1a; class Solution {public int threeSumClosest(int[] nums, int target) {Arrays.sort(nums);int n nums.length;int best 10000000;// 枚举 afor (int i 0; i < n; i) {// 保证和上一次枚举的元素不相等if (i > 0 && nums…

除了谷歌卫星图还有哪些可以平替的卫星影像图源~~

这几天&#xff08;2024-03-27&#xff09;朋友们都开始反应之前我们分享的ArcGIS直接连接谷歌影像还有GlobalMapper下载地址无效了&#xff01; ArcGIS快速添加无偏移谷歌Google影像 如何轻松下载指定区域的谷歌影像 经过测试&#xff0c;没有错&#xff01;它又被墙了&…

【python】python网易云音乐用户数据分析可视化(源码+数据+报告)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

【计算机毕业设计】网上宠物商店管理系统——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

DS数模-Mathorcup妈妈杯C题思路

2024Mathorcup数学建模挑战赛&#xff08;妈妈杯&#xff09;C题保姆级分析完整思路代码数据教学 C题题目&#xff1a;物流网络分拣中心货量预测及人员排班 接下来我们将按照题目总体分析-背景分析-各小问分析的形式来 总体分析&#xff1a;题目要求我们处理的是一个关于物流…

AMD Tensile 简介与示例

按照知其然&#xff0c;再知其所以然的认知次序进行 1&#xff0c;下载代码 git clone --recursive https://github.com/ROCm/Tensile.git 2&#xff0c;安装 Tensile cd Tensile mkdir build cd build ../Tensile/bin/Tensile ../Tensile/Configs/rocblas_dgemm_nn_asm_full…

可视化大屏的应用(9):智慧旅游和智慧景区

可视化大屏在智慧旅游领域具有多种价值&#xff0c;可以为旅游管理者和游客提供更加便捷、优质的服务和体验。本期大千UI工场带来智慧旅游和智慧景区的可视化大屏界面&#xff0c;供大家欣赏。 可视化大屏在智慧旅游领域的价值如下&#xff1a; 提供全面的信息展示&#xff0…

突破界限:iCan 进入元宇宙的旅程如何改变了台湾文化的游戏规则

台湾游戏公司 iCan Entertainment 通过其子公司 iFA Capital, LTD&#xff0c;在2022年7月踏上了一段充满激情的 Web3 之旅。 旨在融合创意、文化和尖端技术&#xff0c;他们深入探索了区块链&#xff0c;专注于创建独特的 NFT 和元宇宙体验。通过结合营销和创新&#xff0c;他…

QGIS下载高清影像!看过来,这里有个最方便快捷的方法。

今天&#xff0c;我们再介绍一个十分简单的高清影像下载方法。利用QGIS的导出功能或者地图转栅格功能。轻松实现。 我们之前介绍了不同的下载方法也可以去查看。 ArcGIS下载在线地图影像上篇&#xff08;手工版&#xff09; 如何轻松下载指定区域的谷歌影像 今天&#xff0c…

水电智能远程抄表系统

水电智能远程抄表系统是一种应用先进技术实现水电抄表的智能化管理系统&#xff0c;通过远程抄表、数据传输和智能分析&#xff0c;实现了对水电使用情况的实时监测和管理。本文将从系统特点、构成以及带来的效益三个方面展开介绍。 系统特点 1.远程抄表&#xff1a;系统能够…

【强化学习实践】Gym+倒立单摆+创建自己的环境

一、Gym Gym是OpenAI开发的一个强化学习算法测试环境集合包。Gym提供了多种标准的环境&#xff0c;包括经典的游戏&#xff08;如Atari游戏&#xff09;、机器人模拟任务以及其他各种类型的问题&#xff0c;供开发者测试和训练强化学习智能体。在Gym环境中&#xff0c;开发者可…

Rust语言入门第三篇-输出到命令行+占位符

文章目录 Rust语言入门第三篇-输出到命令行介绍println! 和 print!占位符{}java 对比Rust的输出到命令行占位符输出到命令行占位符 Rust语言入门第三篇-输出到命令行 介绍 在学习 Rust 语言之前&#xff0c;掌握如何将文字输出到命令行几乎是必不可少的。这是因为在学习阶段&…

数据转换 | Matlab基于GADF格拉姆角差场一维数据转二维图像方法

目录 效果分析基本介绍程序设计参考资料获取方式 效果分析 基本介绍 GADF&#xff08;Gramian Angular Difference Field&#xff09;是一种将时间序列数据转换为二维图像的方法之一。它可以用于提取时间序列数据的特征&#xff0c;并可应用于各种领域&#xff0c;如时间序列分…

神经网络模型底层原理与实现9-可解释性

必要性&#xff1a;在金融、医药、自动驾驶方面&#xff0c;模型必须可解释&#xff0c;知道分类错在哪才可以更好的改进模型 解释的两类方法&#xff1a; 1.找出为什么模型认为图片是一只猫的原因 具体操作&#xff1a;a.把图片中的一部分删掉&#xff0c;如果分类错了很多&…