实验2.3 m_Coloring算法时间复杂性分析
实验目的
(1)实验比较数据输入规模对算法执行时间的影响。
(2)实验比较不同算法对问题求解时间的影响。
(3)掌握算法时间效率的分析方法。
实验任务
(1)阅读并理解实验2.3的源代码。
(2)分析实验2.3源代码中mColoring函数的时间复杂性。
(3)用C++语言实现该算法,绘制不同的m、n组合时算法的时间复杂度曲线和运行时间曲线,并进行简要分析。
(4)撰写实验报告,实验报告内容包括实验目的、实验任务、实验环境、实验步骤、实验结果和实验总结等部分。
实验步骤及结果
实验预习
mColoring算法时间复杂性分析
用C/C++语言实现的源代码
#include <iostream>
#include <ctime>
#include <fstream>
using namespace std;
class Color
{
friend int mColoring(int, int, int **);
public:
bool Ok(int k);
void Backtrack(int t);
int n, m, **a, *x;
long sum;
};
int mColoring(int n, int m, int **a);
int main(void)
{
ofstream ofs;
// 三种曲线对应不同的文件名 m变化n不变--exp2_3_mdnb.txt n变化m不变--exp2_3_mbnd.txt 一起变化--exp2_3_mdnd.txt
ofs.open("exp2_3_mdnd.txt", ios::out);
int n, m, **a, sum;
// 如果要得一个变量不动另一个变量变化的结果将下面双重for循环改为单层
// m = 8; // m不变n从1到10 修改单层循环对n赋值
// n = 9; // n不变m从1到10 修改单层循环对m赋值
// m分别为6和7 n从1到10
for (int k = 6; k <= 7; ++k)
{
m = k;
for (int j = 1; j <= 10; ++j)
{
clock_t start, end;
double run_millisecond;
n = j;
// 将图设置为空图
a = new int *[n + 1];
for (int i = 0; i <= n; i++)
a[i] = new int[n + 1];
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
{
a[i][j] = 0;
a[j][i] = a[i][j];
}
}
// 对算法运行时间计时
start = clock();
sum = mColoring(n, m, a);
end = clock();
run_millisecond = double(end - start) / CLK_TCK * 1000;
for (int i = 0; i <= n; ++i)
{
delete[] a[i];
}
delete[] a;
// 将结果写入文件
ofs << m << "," <<n<<","<< sum << "," << run_millisecond << endl;
}
}
ofs.close();
cout << "搞定" << endl;
system("pause");
return 0;
}
bool Color::Ok(int k)
{
for (int j = 1; j <= n; j++)
if ((a[k][j] == 1) && (x[j] == x[k]))
return false;
return true;
}
void Color::Backtrack(int t)
{
sum++;
if (t > n)
{
// sum++;
return;
}
else
{
for (int i = 1; i <= m; i++)
{
x[t] = i;
if (Ok(t))
Backtrack(t + 1);
x[t] = 0;
}
}
}
int mColoring(int n, int m, int **a)
{
Color X;
X.n = n;
X.m = m;
X.a = a;
X.sum = 0;
int *p = new int[n + 1];
for (int i = 0; i <= n; i++)
p[i] = 0;
X.x = p;
X.Backtrack(1);
delete[] p;
return X.sum;
}
上机实验
m不变n变化时的时间复杂度和运行时间曲线
m = 8 图为空图
图1 m不变n变化的算法时间复杂度曲线图
图2 m不变n变化的算法运行时间曲线图
可以看出,颜色个数不变的情况下,当节点个数n在8之后时,每次增加节点个数都会引起指数级时间复杂度和算法运行时间的增加。
n不变m变化时的时间复杂度和运行时间曲线
n = 9 图为空图
图3 n不变m变化的算法时间复杂度曲线图
图4 n不变m变化的算法运行时间曲线图
可以看出,在节点个数不变的情况下,当颜色个数n在6之后时,每次增加颜色个数都会引起指数级时间复杂度和算法运行时间的增加。
m在两种变化下,变量n的时间复杂度和运行时间曲线
m = 6 及 m = 7 图为空图
图5 m在两种变化下变量n的算法时间复杂度曲线图
图6 m在两种变化下变量n的算法运行时间曲线图
可以看出,在m为不同的数时,n在8之前增加引起的时间复杂度和算法运行时间的增加十分微弱,8之后时间复杂度和算法运行时间呈指数级增加,并且m越大增加越多。
绘制n=10时例2.5代码的递归树
程序验证:
实验总结
深刻认识到了输入数据的规模对于算法执行时间的影响,对算法时间复杂度的理解更为深入。对于不同算法求解同一问题时,理解了时间复杂度更小的算法在求解时间上所占据的优势。学习了算法时间效率的分析方法,可以通过算法执行次数以及算法运行时间两个方面来分析算法的时间效率,并可以通过图表直观地将结果表示出来。