《算法导论》上机总结
突然想到把所有的上机都总结一下。如果有错误还请不吝斧正。
目录
首先说明一下代码格式:我这边所有的东西基本都写到 了一起。就像这样:
然后运行的时候只要把我代码中的Test函数放到主函数里就可以了。就像这样(记得把头文件加进去):
实验一 排序算法
插入排序算法(直接插入、二分插入)
合并排序算法
快速排序算法
随机快速排序算法
计数排序算法
基数排序算法
桶排序算法(没写)
直接插入排序.h
#pragma once
typedef int dataType;
/*打印数组*/
void PrintArray(dataType arr[], int length);
/*数组初始化*/
void InitArray(dataType arr[], int length);
/*直接插入排序*/
void DirectInsertSort(dataType arr[], int length);
/*直接插入排序的测试函数*/
void TestDirectInsrtSort();
直接插入排序.cpp
#include "直接插入排序.h"
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
/*打印数组*/
void PrintArray(dataType arr[], int length)
{
for (int i = 0; i < length; i++)
{
if (arr[i] > 0)
cout << arr[i] << " ";
}
cout << endl;
}
/*数组初始化*/
void InitArray(dataType arr[], int length)
{
srand((unsigned)time(NULL));/*设置随机数种子*/
arr[0] = -1;/*第一位要留出来用来插入*/
for (int i = 1; i < length; i++)
{
arr[i] = rand() % 91 + 10;/*rand()%(Y-X+1)+X,生成X-Y之间的数*/
}
}
/*直接插入排序*/
void DirectInsertSort(dataType arr[], int length)
{
arr[0] = arr[1];/*先把数组第一个数组插入到第一位*/
for (int i = 2; i < length; i++)
{
for (int j = i - 2; j >= 0; j--)
{
/*如果未排序的数比已经排序好的最后一个数要大,就插入到末尾,同时对下一个进行判断*/
if (arr[i] >= arr[j])
{
arr[j + 1] = arr[i];
break;
}
/*否则就将前面的数一个个后移*/
else
{
arr[j + 1] = arr[j];
if (0 == j)
arr[0] = arr[i];
}
}
}
/*排序完成后最后一位置空*/
arr[length - 1] = -1;
}
/*直接插入排序的测试函数*/
void TestDirectInsrtSort()
{
int length;
cout << "输入你理想的数组长度:";
cin >> length;
length++;/*我们的需要的数组得多一位*/
dataType *arr = new dataType[length + 1];/*创建一个一维数组*/
InitArray(arr, length);/*初始化数组*/
PrintArray(arr, length);/*打印这个数组*/
DirectInsertSort(arr, length);/*对这个数组进行直接插入排序*/
PrintArray(arr, length);/*再次打印这个数组*/
delete[] arr;/*销毁这个数组*/
}
实验结果:
二分排序.h
#pragma once
typedef int dataType;
/*打印数组*/
void PrintTwoSortArray(dataType arr[], int length);
/*数组初始化*/
void InitTwoSortArray(dataType arr[], int length);
/*二分排序*/
void TwoSort(dataType arr[], int length);
/*二分排序的测试函数*/
void TestTwoSort();
二分排序.cpp
#include "二分排序.h"
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
/*打印数组*/
void PrintTwoSortArray(dataType arr[], int length)
{
for (int i = 0; i < length; i++)
{
if (arr[i] > 0)
cout << arr[i] << " ";
}
cout << endl;
}
/*数组初始化*/
void InitTwoSortArray(dataType arr[], int length)
{
srand((unsigned)time(NULL));/*设置随机数种子*/
arr[0] = -1;/*第一位要留出来用来插入*/
for (int i = 1; i < length; i++)
{
arr[i] = rand() % 91 + 10;/*rand()%(Y-X+1)+X,生成X-Y之间的数*/
}
}
/*二分排序*/
void TwoSort(dataType arr[], int length)
{
/*一开始我们还是先把第一个数字插入到数组头部*/
arr[0] = arr[1];
/*接下来才开始二分插入,从arr[2]开始插入,所以i=2*/
for (int i = 2; i < length; i++)
{
int left = 0;
int right = i - 2;/*arr[i-2]才是已经排序好的数组的最后一位*/
while (left <= right)
{
int mid = (left + right) >> 1;/*相当于(left + right)÷2*/
/*调整要折半的数组范围,根据left与right的值来变化*/
if (arr[mid] > arr[i])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
for (int j = i - 2; j > right; j--)
{
arr[j + 1] = arr[j];
}
arr[right + 1] = arr[i];
}
arr[length - 1] = -1;/*最后一位置空*/
}
/*二分排序的测试函数*/
void TestTwoSort()
{
int length;
cout << "输入你想要的数组长度:";
cin >> length;
length++;/*我们的需要的数组得多一位*/
dataType *arr = new dataType[length];/*创建一个一维数组*/
InitTwoSortArray(arr, length);/*初始化数组*/
PrintTwoSortArray(arr, length);/*打印这个数组*/
TwoSort(arr, length);/*对这个数组进行直接插入排序*/
PrintTwoSortArray(arr, length);/*再次打印这个数组*/
delete[] arr;/*销毁这个数组*/
}
实验结果:
合并排序(归并排序)算法.h
#pragma once
typedef int dataType;
/*打印数组*/
void PrintMergeArray(dataType arr[], int length);
/*数组初始化*/
void InitMergeArray(dataType arr[], int length);
/*合并*/
void Merge(dataType sourceArr[], dataType tempArr[], int start, int middle, int end);
/*分解递归*/
void MergeSort(dataType sourceArr[], dataType tempArr[], int start, int end);
/*归并排序测试函数*/
void TestMergeSort();
合并排序(归并排序)算法.cpp
#include "归并排序.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
using namespace std;
/*打印数组*/
void PrintMergeArray(dataType arr[], int length)
{
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
if ((i + 1) % 10 == 0)/*每输出5个数字就换行*/
cout << endl;
}
cout << endl;
}
/*数组初始化*/
void InitMergeArray(dataType arr[], int length)
{
srand((unsigned)time(NULL));/*设置随机数的种子*/
for (int i = 0; i < length; i++)
{
arr[i] = rand() % 100 + 1;/*数组为1~100的随机数*/
}
}
/*合并*/
void Merge(dataType sourceArr[], dataType tempArr[], int start, int middle, int end)
/*sourceArr[]是原数组,tempArr[]中间临时数组*/
{
int i = start, j = middle + 1, k = start;/*i~mid为左边数组,j~end为右边数组*/
/*我们要把左边和右边数组归并在一起*/
while (i != middle + 1 && j != end + 1)/*如果左右两个数组都还有数残留*/
{
if (sourceArr[i] > sourceArr[j])/*左边数组第一个数大于右边数组第一个数,就把右边数组第一个数放到合并数组的第一位*/
tempArr[k++] = sourceArr[j++];
else/*反之,把左边数组第一个数放到合并数组的第一位*/
tempArr[k++] = sourceArr[i++];
}
/*如果其中一个数组结束了而另一个数组还没有结束,就把另一个数组剩下的数都放到合并的数组里*/
while (i != middle + 1)
{
tempArr[k++] = sourceArr[i++];
}
while (k != end + 1)
{
tempArr[k++] = sourceArr[j++];
}
/*把合并后的数组放到原数组中*/
for (i = start; i <= end; i++)
{
sourceArr[i] = tempArr[i];
}
}
/*分解递归*/
void MergeSort(dataType sourceArr[], dataType tempArr[], int start, int end)
{
int middle;
if (start < end)/*如果数组中还有超过两个数就继续递归*/
{
middle = (start + end) >> 1;/*middle = (start + end)÷2*/
MergeSort(sourceArr, tempArr, start, middle);/*对左边的数组进行分解*/
MergeSort(sourceArr, tempArr, middle + 1, end);/*对右边的数组进行分解*/
Merge(sourceArr, tempArr, start, middle, end);/*将左右分解完成后的数组进行归并*/
}
}
/*归并排序测试函数*/
void TestMergeSort()
{
int length;
cout << "输入你期望的数组长度:";
cin >> length;
dataType *sourceArr = new dataType[length];
dataType *tempArr = new dataType[length];
InitMergeArray(sourceArr, length);
for (int i = 0; i < length; i++)
{
tempArr[i] = sourceArr[i];
}
cout << "原来的数组为:" << endl;
PrintMergeArray(sourceArr, length);
MergeSort(sourceArr, tempArr, 0, length - 1);
cout << "归并排序后的数组为:" << endl;
PrintMergeArray(sourceArr, length);
delete[] sourceArr;
delete[] tempArr;
}
实验结果:
快速排序算法.h(随机快速排序算法写在一起了)
#pragma once
typedef int dataType;
/*打印数组*/
void PrintQuickArray(dataType arr[], int length);
/*初始化数组*/
void InitQuickArray(dataType arr[], int length);
/*快速排序递归部分*/
void QuickSort(dataType arr[], int left, int right);
/*快速排序主体部分*/
int Partition(dataType arr[], int left, int right);
/*快速排序的随机化版本*/
int RandomPartition(dataType arr[], int left, int right);
/*快速排序测试函数*/
void TestQuickSort();
快速排序算法.cpp
#include "快速排序.h"
#include <stdlib.h>
#include <time.h>
#include <iostream>
using namespace std;
/*打印数组*/
void PrintQuickArray(dataType arr[], int length)
{
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
if ((i + 1) % 15 == 0)/*如果一排超过15个数就换行*/
cout << endl;
}
cout << endl; cout << endl;
}
/*初始化数组*/
void InitQuickArray(dataType arr[], int length)
{
srand((unsigned)time(NULL));/*建立随机数种子*/
for (int i = 0; i < length; i++)
{ /*一句废话:虽然这里可以不要花括号,我总觉得有了比较庄重!*/
arr[i] = rand() % 100 + 1;/*arr[i]的值:1-100之间*/
}
}
/*快速排序递归部分*/
void QuickSort(dataType arr[], int left, int right)
{
if (left < right)
{
int middle = Partition(arr, left, right);/*arr[middle]左边的数都小于它,右边的数都大于它*/
QuickSort(arr, left, middle - 1);/*对左边的数进行快排*/
QuickSort(arr, middle + 1, right);/*对右边的数进行快排*/
}
}
/*快速排序主体部分*/
int Partition(dataType arr[], int left, int right)
{
if (left >= right)/*此时两个光标重合,代表已经整理完成一个组*/
return 0;
/*①首先我们设定一个key*/
int key = arr[left];
while (left < right)
{
while (left<right&&arr[right] >= key)/*②right光标从右往左 ←,找到一个数小于key*/
{
right--;
}
/*把这个数赋值给left光标所在的位置*/
arr[left] = arr[right];
while (left < right&&arr[left] <= key)/*③left光标从左往右→,找到一个数大于key*/
{
left++;
}
/*把这个数赋值给right光标所在的位置*/
arr[right] = arr[left];
}
/*④left与right光标重合,把key赋值给这两个光标重合的位置*/
arr[left] = key;
/*返回重合的位置的下标*/
return left;
}
/*快速排序的随机化版本*/
int RandomPartition(dataType arr[], int left, int right)
{
srand((unsigned)time(NULL));/*建立随机种子*/
int random = rand() % (right - left + 1) + left;/*random就是一个随机的位置*/
/*将arr[random]与arr[left]进行交换*/
dataType temp = arr[left];
arr[left] = arr[random];
arr[random] = temp;
return Partition(arr, left, right);
}
/*快速排序测试函数*/
void TestQuickSort()
{
int length;
cout << "输入你理想的数组长度:";
cin >> length;/*输入*/
cout << endl;
dataType *arr = new dataType[length];/*动态建立数组*/
InitQuickArray(arr, length);/*初始化这个数组*/
cout << "初始化后的数组: ";
PrintQuickArray(arr, length);
QuickSort(arr, 0, length - 1);/*对这个数组进行快速排序.第length个数下标为length-1*/
cout << "快排后的数组: ";
PrintQuickArray(arr, length);
/*随机快排的测试,记得把QuickSort里的Partition换成RandomPartition*/
/*cout << endl; cout << endl;
cout << "随机快排后的数组:";
PrintQuickArray(arr, length);*/
delete[] arr;/*最后要销毁这个数组*/
}
实验结果:
计数排序算法.h
#pragma once
typedef int dataType;
/*打印数组*/
void PrintCountArray(dataType arr[], int length);
/*初始化数组*/
void InitCountArray(dataType arr[], int length);
/*计数排序*/
void CountSort(dataType arr[], int length);
/*计数排序测试函数*/
void TestCountSort();
计数排序算法.cpp
#include "计数排序.h"
#include <stdlib.h>
#include <time.h>
#include <iostream>
using namespace std;
/*打印数组*/
void PrintCountArray(dataType arr[], int length)
{
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
if ((i + 1) % 15 == 0)
cout << endl;
}
cout << endl; cout << endl;
}
/*初始化数组*/
void InitCountArray(dataType arr[], int length)
{
srand((unsigned)time(NULL));
for (int i = 0; i < length; i++)
{
arr[i] = rand() % 100 + 1;/*arr[i]在1-100之间*/
}
}
/*计数排序*/
void CountSort(dataType arr[], int length)
{
dataType *temp = new dataType[length];/*构造一个临时数组*/
int i, j;
for (i = 0; i < length; i++)/*这个临时数组每个数赋值为0*/
temp[i] = 0;
for (i = 0; i < length; i++)
{
int count = 0;
for (j = 0; j < length; j++)/*扫描待排序数组*/
{
if (arr[j] < arr[i])/*统计比arr[i]小的数*/
count++;
}
while (temp[count] != 0)/*如果排的位置已经有了,就往后移(防止两个或多个数相同带来错误)*/
count++;
temp[count] = arr[i];/*把数放到对应位置*/
}
for (i = 0; i < length; i++)/*把排好序的数组赋值给原数组*/
{
arr[i] = temp[i];
}
delete[] temp;/*销毁这个临时数组*/
}
/*计数排序测试函数*/
void TestCountSort()
{
int length;
cout << "输入你期望的数组长度:";
cin >> length;
dataType *arr = new dataType[length];
InitCountArray(arr, length);
cout << "输出待排序的数组:" << endl;
PrintCountArray(arr, length);
CountSort(arr, length);
cout << "输出排序后的数组:" << endl;
PrintCountArray(arr, length);
delete[] arr;
cout << endl;
cout << endl;
cout << "测试一下有多个数相同的情况:" << endl;
cout << "这是我们自定义的数组:" << endl;
dataType arr2[15] = { 6,6,6,8,8,8,8,20,1,3,5,6,7,15,15 };
PrintCountArray(arr2, 15);
CountSort(arr2, 15);
cout << "输出排序后的数组:" << endl;
PrintCountArray(arr2, 15);
}
实验结果:
基数排序算法.h
#pragma once
/*打印数组*/
void PrintRadixArray(int arr[], int length);
/*初始化数组*/
void InitRadixArray(int arr[], int length);
/*获取数组中最大的数*/
int GetMaxNum(int arr[], int length);
/*获取数字的位数*/
int GetLoopTimes(int num);
/*进行基数排序*/
void RadixSort(int arr[], int length, int loop);
/*程序运行控制*/
void ControlRadixSort(int arr[], int length);
/*基数排序测试函数*/
void TestRadixSort();
基数排序算法.cpp
#include "基数排序.h"
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <iostream>
using namespace std;
/*打印数组*/
void PrintRadixArray(int arr[], int length)
{
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
if ((i + 1) % 15 == 0)
cout << endl;
}
cout << endl; cout << endl;
}
/*初始化数组*/
void InitRadixArray(int arr[], int length)
{
srand((unsigned)time(NULL));
for (int i = 0; i < length; i++)
{
arr[i] = rand() % 1000 + 1;/*arr[i]在1-1000之间*/
}
}
/*获取数组中最大的数*/
int GetMaxNum(int arr[], int length)
{
int max = 0;
for (int i = 0; i < length; i++)
{
if (max < arr[i])
max = arr[i];
}
return max;
}
/*获取数字的位数*/
int GetLoopTimes(int num)
{
int count = 1;
num /= 10;
while (num != 0)
{
count++;
num /= 10;
}
return count;
}
/*进行基数排序*/
void RadixSort(int arr[], int length, int loop)
{
/*1、我们建立一批桶子*/
int buckets[10][10] = { 0 };/*全部赋值为0*/
/*如何求每一位上的数:
如256,它的个位=(256/1)%10=6
它的十位=(256/10)%10=5
它的百位=(256/100)%10=2
temp就是其中的1、10、100 */
int temp = (int)pow(10, loop - 1);
int i, j, k;
k = 0;
for (i = 0; i < length; i++)
{
int arrIndex = (arr[i] / temp) % 10;/*2、求出它的个位或十位或百位上的数*/
for (j = 0; j < 10; j++)
{
if (buckets[arrIndex][j] == 0)/*如果这个位置是空的*/
{
buckets[arrIndex][j] = arr[i];//3、把它放到arrIndex号桶的正确位置*/
break;
}
}
}
/*4、将桶中的数倒回到arr数组中*/
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++)
{
if (buckets[i][j] != 0)
{
arr[k] = buckets[i][j];
buckets[i][j] = 0;
k++;
}
}
}
}
/*程序运行控制*/
void ControlRadixSort(int arr[], int length)
{
int max = GetMaxNum(arr, length);
int loop = GetLoopTimes(max);
/*对每一位进行桶分配*/
for (int i = 1; i <= loop; i++)
{
RadixSort(arr, length, i);
}
}
/*基数排序测试函数*/
void TestRadixSort()
{
int length;
cout << "输入你期望的数组长度:";
cin >> length;
int *arr = new int[length];
InitRadixArray(arr, length);
cout << "输出待排序的数组:" << endl;
PrintRadixArray(arr, length);
ControlRadixSort(arr, length);
cout << "输出排序后的数组:" << endl;
PrintRadixArray(arr, length);
delete[] arr;
}
实验结果:
实验二 Strassen’s 矩阵乘法和最近点对算法
1.利用计算机程序设计语言,实现教材第 28.2 章介绍的“Strassen’s 矩阵乘法算法”,自主
生成两个 8×8 的矩阵,检验算法的正确性并输出算法结果。
2.比较 Strassen’s 矩阵乘法算法和数学定义的矩阵乘法算法效率之间的区别,并用直观的表
达方式把两种不同矩阵乘法的效率随矩阵维数的变化趋势。(没做)
3.利用计算机程序设计语言,实现教材第 33.4 章介绍的“最近点对算法”,在拟定的二维空间
点集上检验算法的正确性并输出算法结果。
矩阵乘法的Strassen方法.h
#pragma once
template<typename T>
class Strassen_class {
public:
/*矩阵相加*/
void ADD(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize);
/*矩阵相减*/
void SUB(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize);
/*朴素算法实现*/
void MUL(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize);
/*A,B矩阵赋值*/
void FillMatrix(T** MatrixA, T** MatrixB, int length);
/*打印矩阵*/
void PrintMatrix(T **MatrixA, int MatrixSize);
/*Strassen算法实现*/
void Strassen(int N, T **MatrixA, T **MatrixB, T **MatrixC);
};
/*测试Strassen函数*/
void TestStrassen();
矩阵乘法的Strassen方法.cpp
#include "stdafx.h"
#include "矩阵乘法的Strassen方法.h"
#include <stdlib.h>
#include <time.h>
#include <iostream>
using namespace std;
/*
c++使用二维数组,申请动态内存方法
申请
int **A;
A = new int *[desired_array_row];
for ( int i = 0; i < desired_array_row; i++)
A[i] = new int [desired_column_size];
释放
for ( int i = 0; i < your_array_row; i++)
delete [] A[i];
delete[] A;
*/
/*矩阵相加*/
template<typename T>
void Strassen_class<T>::ADD(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize)
{
for (int i = 0; i < MatrixSize; i++)
for (int j = 0; j < MatrixSize; j++)
MatrixResult[i][j] = MatrixA[i][j] + MatrixB[i][j];
}
/*矩阵相减*/
template<typename T>
void Strassen_class<T>::SUB(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize)
{
for (int i = 0; i < MatrixSize; i++)
for (int j = 0; j < MatrixSize; j++)
MatrixResult[i][j] = MatrixA[i][j] - MatrixB[i][j];
}
/*朴素算法实现*/
template<typename T>
void Strassen_class<T>::MUL(T** MatrixA, T** MatrixB, T** MatrixResult, int MatrixSize)
{
for (int i = 0; i < MatrixSize; i++)
for (int j = 0; j < MatrixSize; j++)
{
MatrixResult[i][j] = 0;
for (int k = 0; k < MatrixSize; k++)
{
MatrixResult[i][j] = MatrixResult[i][j] + MatrixA[i][k] * MatrixA[k][j];
}
}
}
/*A,B矩阵赋值*/
template<typename T>
void Strassen_class<T>::FillMatrix(T** MatrixA, T** MatrixB, int length)
{
srand((unsigned)time(NULL));
for(int i=0;i<length;i++)
for (int j = 0; j < length; j++)
{
MatrixA[i][j] = rand() % 5;
MatrixB[i][j] = rand() % 5;
}
}
/*打印矩阵*/
template<typename T>
void Strassen_class<T>::PrintMatrix(T **MatrixA, int MatrixSize)
{
cout << endl;
for (int i = 0; i < MatrixSize; i++)
{
for (int j = 0; j < MatrixSize; j++)
cout << MatrixA[i][j] << " ";
cout << endl;
}
cout << endl;
}
/*Strassen算法实现*/
template<typename T>
void Strassen_class<T>::Strassen(int N, T **MatrixA, T **MatrixB, T **MatrixC)
{
int halfSize = N / 2;
int newSize = N / 2;
int i, j;
/*分治门槛,小于这个值时不再进行递归计算,而是采用常规矩阵计算方法*/
if (N <= 64)
MUL(MatrixA, MatrixB, MatrixC, N);
else
{
T** A11;
T** A12;
T** A21;
T** A22;
T** B11;
T** B12;
T** B21;
T** B22;
T** C11;
T** C12;
T** C21;
T** C22;
T** P1;
T** P2;
T** P3;
T** P4;
T** P5;
T** P6;
T** P7;
T** aResult;
T** bResult;
A11 = new T *[newSize];
A12 = new T *[newSize];
A21 = new T *[newSize];
A22 = new T *[newSize];
B11 = new T *[newSize];
B12 = new T *[newSize];
B21 = new T *[newSize];
B22 = new T *[newSize];
C11 = new T *[newSize];
C12 = new T *[newSize];
C21 = new T *[newSize];
C22 = new T *[newSize];
P1 = new T *[newSize];
P2 = new T *[newSize];
P3 = new T *[newSize];
P4 = new T *[newSize];
P5 = new T *[newSize];
P6 = new T *[newSize];
P7 = new T *[newSize];
aResult = new T *[newSize];
bResult = new T *[newSize];
int newLength = newSize;
/*把一维数组二维化*/
for (i = 0; i < newSize; i++)
{
A11[i] = new T [newSize];
A12[i] = new T [newSize];
A21[i] = new T [newSize];
A22[i] = new T [newSize];
B11[i] = new T [newSize];
B12[i] = new T [newSize];
B21[i] = new T [newSize];
B22[i] = new T [newSize];
C11[i] = new T [newSize];
C12[i] = new T [newSize];
C21[i] = new T [newSize];
C22[i] = new T [newSize];
P1[i] = new T [newSize];
P2[i] = new T [newSize];
P3[i] = new T [newSize];
P4[i] = new T [newSize];
P5[i] = new T [newSize];
P6[i] = new T [newSize];
P7[i] = new T [newSize];
aResult[i] = new T [newSize];
bResult[i] = new T [newSize];
}
/*将输入矩阵分解成4个子矩阵*/
for (i = 0; i < N / 2; i++)
{
for (j = 0; j < N / 2; j++)
{
A11[i][j] = MatrixA[i][j];
A12[i][j] = MatrixA[i][j + N / 2];
A21[i][j] = MatrixA[i + N / 2][j];
A22[i][j] = MatrixA[i + N / 2][j + N / 2];
B11[i][j] = MatrixB[i][j];
B12[i][j] = MatrixB[i][j + N / 2];
B21[i][j] = MatrixB[i + N / 2][j];
B22[i][j] = MatrixB[i + N / 2][j + N / 2];
}
}
/*计算P1-P7*/
/*P1=A11*(B11-B22)*/
SUB(B11, B22, bResult, halfSize);
Strassen(halfSize, A11, bResult, P1);
/*P2=(A11+A12)*B22*/
ADD(A11, A12, aResult, halfSize);
Strassen(halfSize, aResult, B22, P2);
/*P3=(A21+A22)*B11*/
ADD(A21, A22, aResult, halfSize);
Strassen(halfSize, aResult, B11, P3);
/*P4=A22*(B21-B11)*/
SUB(B11, B11, bResult, halfSize);
Strassen(halfSize, A22, bResult, P4);
/*P5=(A11+A22)*(B11+B22)*/
ADD(A11, A22, aResult, halfSize);
ADD(B11, B22, bResult, halfSize);
Strassen(halfSize, aResult, bResult, P5);
/*P6=(A12-A22)*(B21+B22)*/
SUB(A12, A22, aResult, halfSize);
ADD(B21, B22, bResult, halfSize);
Strassen(halfSize, aResult, bResult, P6);
/*P7=(A11-A21)*(B11+B12)*/
SUB(A11, A21, aResult, halfSize);
ADD(B11, B12, bResult, halfSize);
Strassen(halfSize, aResult, bResult, P7);
/*计算C11、C12、C21、C22*/
/*C11=P5+P4-P2+P6*/
ADD(P5, P4, aResult, halfSize);
SUB(P2, P6, bResult, halfSize);
SUB(aResult, bResult, C11, halfSize);
/*C12=P1+P2*/
ADD(P1, P2, C12, halfSize);
/*C21=P3+P4*/
ADD(P3, P4, C21, halfSize);
/*C22=P5+P1-P3-P7*/
ADD(P5, P1, aResult, halfSize);
ADD(P3, P7, bResult, halfSize);
SUB(aResult, bResult, C22, halfSize);
/*组合小矩阵到一个大矩阵*/
for (int i = 0; i < N / 2; i++)
{
for (int j = 0; j < N / 2; j++)
{
MatrixC[i][j] = C11[i][j];
MatrixC[i][j + N / 2] = C12[i][j];
MatrixC[i + N / 2][j] = C21[i][j];
MatrixC[i + N / 2][j + N / 2] = C22[i][j];
}
}
/*释放矩阵内存空间*/
for (int i = 0; i < newLength; i++)
{
delete[] A11[i]; delete[] A12[i]; delete[] A21[i]; delete[] A22[i];
delete[] B11[i]; delete[] B12[i]; delete[] B21[i]; delete[] B22[i];
delete[] C11[i]; delete[] C12[i]; delete[] C21[i]; delete[] C22[i];
delete[] P1[i]; delete[] P2[i]; delete[] P3[i]; delete[] P4[i];
delete[] P5[i]; delete[] P6[i]; delete[] P7[i];
delete[] aResult[i]; delete[] bResult[i];
}
delete[] A11; delete[] A12; delete[] A21; delete[] A22;
delete[] B11; delete[] B12; delete[] B21; delete[] B22;
delete[] C11; delete[] C12; delete[] C21; delete[] C22;
delete[] P1; delete[] P2; delete[] P3; delete[] P4; delete[] P5;
delete[] P6; delete[] P7;
delete[] aResult;
delete[] bResult;
}
}
/*测试Strassen函数*/
void TestStrassen()
{
/*定义Strassen_class类对象*/
Strassen_class<int> stra;
int MatrixSize = 0;
/*存放矩阵A*/
int** MatrixA;
/*存放矩阵B*/
int** MatrixB;
/*存放结果矩阵*/
int** MatrixC;
clock_t startTime_For_Normal_Multipilication;
clock_t endTime_For_Normal_Multipilication;
clock_t startTime_For_Strassen;
clock_t endTime_For_Strassen;
srand((unsigned)time(NULL));
cout << "\n请输入矩阵大小(必须是2的幂指数值(例如:32,64,512,..): ";
cin >> MatrixSize;
int N = MatrixSize;//for readiblity.
//申请内存
MatrixA = new int *[MatrixSize];
MatrixB = new int *[MatrixSize];
MatrixC = new int *[MatrixSize];
for (int i = 0; i < MatrixSize; i++)
{
MatrixA[i] = new int[MatrixSize];
MatrixB[i] = new int[MatrixSize];
MatrixC[i] = new int[MatrixSize];
}
stra.FillMatrix(MatrixA, MatrixB, MatrixSize); //矩阵赋值
/*暴力算法测试*/
cout << "朴素矩阵算法开始时钟: " << (startTime_For_Normal_Multipilication = clock());
stra.MUL(MatrixA, MatrixB, MatrixC, MatrixSize);//朴素矩阵相乘算法 T(n) = O(n^3)
cout << "\n朴素矩阵算法结束时钟: " << (endTime_For_Normal_Multipilication = clock());
cout << "\n矩阵运算结果... \n";
stra.PrintMatrix(MatrixC, MatrixSize);
/*Strassen算法测试*/
cout << "\nStrassen算法开始时钟: " << (startTime_For_Strassen = clock());
stra.Strassen(N, MatrixA, MatrixB, MatrixC); //strassen矩阵相乘算法
cout << "\nStrassen算法结束时钟: " << (endTime_For_Strassen = clock());
cout << "\n矩阵运算结果... \n";
stra.PrintMatrix(MatrixC, MatrixSize);
cout << "矩阵大小 " << MatrixSize;
cout << "\n朴素矩阵算法: "
<< (endTime_For_Normal_Multipilication - startTime_For_Normal_Multipilication)
<< " Clocks.."
<< (endTime_For_Normal_Multipilication - startTime_For_Normal_Multipilication) / CLOCKS_PER_SEC
<< " Sec";
cout << "\nStrassen算法:"
<< (endTime_For_Strassen - startTime_For_Strassen)
<< " Clocks.."
<< (endTime_For_Strassen - startTime_For_Strassen) / CLOCKS_PER_SEC
<< " Sec\n";
}
运行结果
最近点对问题.h
#pragma once
#define NO_DISTANCE 1000000
/*定义二维点Point*/
typedef struct Point
{
/*x,y分别为二维点的横、纵坐标,范围[-100,100]*/
float x, y;
}Point;
/*用随机函数对点数组points中的二维数组进行初始化*/
void SetPoints(Point *points, int length);
/*平面内任意两点距离公式*/
float Distance(Point a, Point b);
/*暴力解法*/
float SimplePair(Point points[], int length, Point &a, Point &b);
/*自定义排序规则:依照结构体成员中x变量的升序排序*/
bool CmpX(Point a, Point b);
/*求出最近点对,记录在a、b中,并返回最短距离*/
float ClosestPair(Point points[], int length, Point &a, Point &b);
/*测试函数*/
void TestClosePair();
最近点对问题.cpp
#include "stdafx.h"
#include "最近点对问题.h"
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
using namespace std;
/*用随机函数对点数组points中的二维数组进行初始化*/
void SetPoints(Point *points, int length)
{
srand((unsigned)time(NULL));
for (int i = 0; i < length; i++)
{
points[i].x = (rand() % 20000) / 100.0 - 100;
points[i].y = (rand() % 20000) / 100.0 - 100;
}
}
/*平面内任意两点距离公式*/
float Distance(Point a, Point b)
{
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
/*暴力解法*/
float SimplePair(Point points[], int length, Point &a, Point &b)
{
/*记录集合points中最近两点的距离*/
float distance=1000000.0;
/*临时记录最短距离*/
float temp=0;
for(int i=0;i<length;i++)
for (int j = i+1; j < length; j++)
{
temp = Distance(points[i], points[j]);
if (temp < distance)
{
distance = temp;
a = points[i];
b = points[j];
}
}
return distance;
}
/*自定义排序规则:依照结构体成员中x变量的升序排序*/
bool CmpX(Point a, Point b)
{
return a.x < b.x;
}
/*求出最近点对,记录在a、b中,并返回最短距离*/
float ClosestPair(Point points[], int length, Point &a, Point &b)
{
/*记录集合points中最近两点的距离*/
float distance;
/*记录分割后两个子集中各自最小点对的距离*/
float d1, d2;
/*用于控制for循环的变量*/
int i, j, k;
/*保存分割中两个子集中最小点对*/
Point a1, b1, a2, b2;
/*若只有一个点,定义为最大距离,表示不可达*/
if (length < 2)return NO_DISTANCE;
if (length == 2)
{
a = points[0];
b = points[1];
distance = Distance(a, b);
}
else
{
/*开辟两个子集*/
Point *pts1 = new Point[length/2+1];
Point *pts2 = new Point[length/2+1];
/*sort:对给定区间所有元素进行排序*/
/*Sort函数有三个参数:
(1)第一个是要排序的数组的起始地址。
(2)第二个是结束的地址(最后一位要排序的地址的下一地址)
(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。*/
/*调用algorithm库中的sort函数对points进行升序排序*/
sort(points, points + length, CmpX);
/*排完序后的中间下标值,即中位数*/
float mid = points[(length - 1) / 2].x;
/*把左半边的值赋值给pts1*/
for (size_t i = 0; i < length / 2; i++)
pts1[i] = points[i];
/*把右半边的值赋值给pts2*/
for (int j = 0, i = length / 2; i < length; i++)
pts2[j++] = points[i];
/*分治求解左半边子集的最远点*/
d1 = ClosestPair(pts1, length / 2, a1, b1);
/*分治求解右半边子集的最远点*/
d2 = ClosestPair(pts2, length-length / 2, a2, b2);
if (d1 < d2)
{
distance = d1;
a = a1;
b = b1;
}
else
{
distance = d2;
a = a2;
b = b2;
}
/*求跨越分割线的最近点对*/
Point *pts3 = new Point[length];
for (i = 0, k = 0; i < length; i++)
if (abs(points[i].x - mid) <= distance)
pts3[k++] = points[i];
for (i = 0; i < k; i++)
for (j = i + 1; j <= i + 7 && j < k; j++)
{
if (Distance(pts3[i], pts3[j]) < distance)
{
distance = Distance(pts3[i], pts3[j]);
a = pts3[i];
b = pts3[j];
}
}
}
return distance;
}
/*测试函数*/
void TestClosePair()
{
/*记录随机生成的点对数*/
int amount;
Point a, b;
Point A, B;
float distance;
float distance2;/*暴力解法*/
cout << "请输入二维点对个数:";
cin >> amount;
if (amount < 2)
cout << "请输入大于等于2的点个数!" << endl;
else
{
cout << endl << "随机生成的" << amount << "个二维点对如下:" << endl;
Point *points = new Point[amount];
SetPoints(points, amount);
for (int i = 0; i < amount; i++)
{
printf("(%.2f,%.2f) ", points[i].x, points[i].y);
if (0 == (i + 1) % 5)
cout << endl;
}
distance = ClosestPair(points, amount, a, b);
distance2 = SimplePair(points, amount, A, B);
cout << endl << "按横坐标排序后的点对如下:" << endl;
for (int i = 0; i < amount; i++)
{
printf("(%.2f,%.2f) ", points[i].x, points[i].y);
if (0 == (i + 1) % 5)
cout << endl;
}
cout << endl;
printf("最近点对为:(%.2f,%.2f)和(%.2f,%.2f),\n", a.x, a.y, b.x, b.y);
cout << "它们之间的距离为:" << distance << endl;
cout << endl;
printf("暴力解法最近点对为:(%.2f,%.2f)和(%.2f,%.2f),\n", A.x, A.y, B.x, B.y);
cout << "暴力解法的距离为:" << distance2 << endl;
}
}
运行结果
实验三:作业排程和最长共同子序列算
1.描述并实现动态规划的作业排程算法,并显示下图的排程结果
2.描述并实现最长共同子序列动态规 划 算 法 , 并 显 示 S1=
ACCGGTCGAGATGCAG,S2 = GTCGTTCGGAATGCAT 的最长共同子序列。
任务一:
装配线调度问题.h
#pragma once
/* 7 9 3 4 8
2 2 3 1 3 3
0 0
4 2 1 2 2 6
8 5 6 4 5
*/
/*最快的路线*/
void FastWay();
/*打印路线*/
void PrintStations();
装配线调度问题.cpp
#include "stdafx.h"
#include "装配线调度问题.h"
#include <stdio.h>
/*
f1[j]= e1+a1,1 ,j=1
min( f[1][j-1]+a[1][j] , f[2][j-1]+t[2][j-1]+a[1][j] )
f2[j]= e2+a2,1 ,j=1
min( f[2][j-1]+a[2][j] , f[1][j-1]+t[1][j-1]+a[2][j] )
*/
int f_star, l_star;
int f[3][6];
int l[3][6];
int a[3][6] = { { 0,0,0,0,0,0 },{ 0,7,9,3,4,8 },{ 0,8,5,6,4,5 } };/*第一条线和第二条线*/
int t[3][5] = { { 0,0,0,0,0 },{ 0,2,3,1,3 },{ 0,2,1,2,2 } };/*第一个缓冲和第二个缓冲*/
int e[3] = { 0,2,4 };
int x[3] = { 0,3,6 };
/*最快的路线*/
void FastWay()
{
int j;
f[1][1] = e[1] + a[1][1];
f[2][1] = e[2] + a[2][1];
for (j = 2; j < 6; j++)
{
/*遍历上面的结点*/
if (f[1][j - 1] + a[1][j] <= f[2][j - 1] + t[2][j - 1] + a[1][j])/*往上面直接走比较快*/
{
f[1][j] = f[1][j - 1] + a[1][j];
l[1][j] = 1;/*走第一条路*/
}
else/*往下面直接走比较快*/
{
f[1][j] = f[2][j - 1] + t[2][j - 1] + a[1][j];
l[1][j] = 2;/*走第2条路*/
}
/*遍历下面的结点*/
if (f[2][j - 1] + a[2][j] <= f[1][j - 1] + t[1][j - 1] + a[2][j])
{
f[2][j] = f[2][j - 1] + a[2][j];
l[2][j] = 2;
}
else
{
f[2][j] = f[1][j - 1] + t[1][j - 1] + a[2][j];
l[2][j] = 1;
}
}
/*走到最后如果上面的路比下面的路短*/
if (f[1][5] + x[1] <= f[2][5] + x[2])
{
f_star = f[1][5] + x[1];
l_star = 1;
}
else
{
f_star = f[2][5] + x[2];
l_star = 2;
}
}
/*打印路线*/
void PrintStations()
{
FastWay();
int j;
int i = l_star;/*决定最后是哪条路*/
for (j = 2; j < 6; j++)
{
i = l[i][j];
printf("line %d,station %d\n", i, j-1);
}
printf("line %d,station %d\n", i, 5);
printf("最短为:%d",f_star);
}
运行结果
任务二:
最长共同子序列.h
#pragma once
#include <iostream>
#include <vector>
using namespace std;
/*求解最长共同子序列*/
void LCS(string A, string B);
/*测试函数*/
void TestLCS();
最长共同子序列.cpp
#include "stdafx.h"
#include "最长共同子序列.h"
/*
C[i][j]= 0 i=0 或 j=0
C[i-1][j-1]+1 x[i]= y[j]
max( C[i][j-1],C[i-1][j] ) x[i]≠y[j]
*/
/*求解最长共同子序列*/
void LCS(string A, string B)
{
int i;
int j;
int **C;
C = new int *[A.size() +1];/*A.size()=16*/
for (int k = 0; k <= A.size(); k++)
C[k] = new int[B.size() +1];
/*初始化C[0][j]=0*/
for (i = 0; i <= A.size(); i++)
for (j = 0; j <= B.size(); j++)
{
C[i][j] = 0;
}
for (i = 1; i <= A.size(); i++)
{
for (j = 1; j <= B.size(); j++)
{
if (A[i-1] == B[j-1])
{
C[i][j] = C[i - 1][j - 1] + 1;
}
else if (C[i][j - 1] >= C[i - 1][j])
{
C[i][j] = C[i][j - 1];
}
else
{
C[i][j] = C[i - 1][j];
}
}
}
cout << "共同子序列的长度为:";
cout<< C[A.size()][ B.size()];
int aPos = A.size();
int bPos = B.size();
int commonLen = C[aPos][bPos];//最后一个元素的值就是最长共同子序列的长度
int k = commonLen;
string common;//共同子序列
common.resize(commonLen);
//从两序列最后一个字符开始往前走,有一个字符串Over就结束
while (aPos && bPos)
{
//两序列最后一个元素相等,则同时往前走一步
if (C[aPos][bPos] == C[aPos - 1][bPos] + 1)
{
common[--k] = A[--aPos];
--bPos;
}
else if (C[aPos - 1][bPos] >= C[aPos][bPos - 1])
{
--aPos;/*行*/
}
else
{
--bPos;/*列*/
}
}
cout << endl;
cout << "子串为:";
for (int i = 0; i < commonLen; i++)
{
cout << common[i];
}
cout << endl;
}
void TestLCS()
{
string A = "ACCGGTCGAGATGCAG";
string B = "GTCGTTCGGAATGCAT";
LCS(A, B);
}
运行结果
实验四:单源最短路径和全点对最短路径算法
1.描述并实现单源最短路径算法,显示在下图上的运算结果
2.描述并实现全点对最短路径算法,显示在下图上的运算结果
任务一
单源最短路径.h
#pragma once
#define INFINITY 100/*无穷大*/
#define DOTNUMBER 5/*点数*/
#define LINENUMBER 10/*边数*/
struct Line/*一条边*/
{
int start;/*起点*/
int end;/*终点*/
int weight;/*权重*/
};
struct Vertex
{
int smallCost;/*最小开销*/
int father;/*父结点*/
};
/*v个结点,s为起点,初始化*/
void InitSingleSource(int s);
/*松弛函数*/
void RelaxSingleSource(int s);
/*Bellman-Ford算法*/
bool Bellman_Ford(int s);
/*打印*/
void PrintSingleSource(int src, int des);
void TestSingleSource();
单源最短路径.cpp
#include "stdafx.h"
#include "单源最短路径.h"
#include <iostream>
#include <stdio.h>
using namespace std;
//#define INFINITY 100/*无穷大*/
//#define DOTNUMBER 5/*点数*/
//#define LINENUMBER 10/*边数*/
struct Vertex vertex[DOTNUMBER];/*5个节点*/
struct Line line[LINENUMBER];/*10条边*/
/*s为起点,初始化*/
void InitSingleSource(int s)
{
for (int i = 0; i < DOTNUMBER; i++)
{
vertex[i].smallCost = INFINITY;/*初始化为无穷大*/
vertex[i].father = -1;/*初始化父结点为NULL*/
}
vertex[s].smallCost = 0;/*初始化起点权重为0*/
}
/*松弛函数*/
void RelaxSingleSource(int s)
{
/*If v.d>u.d + w(u, v)
v.d = u.d + w(u, v)
v.π = u*/
int i;
for (i = 0; i < DOTNUMBER; i++) {
for (int j = 0; j <LINENUMBER; j++) {//arr是边集,e是边数,V是点集
int start = line[j].start;/*边的起点x*/
int end = line[j].end;/*边的终点y*/
int weight = line[j].weight;/*边的权重z*/
/*如果边的起点≠无穷大 且 边的终点的最小开销>边的起点的最小开销+边的权重*/
if (vertex[start].smallCost != INT_MAX && vertex[end].smallCost>vertex[start].smallCost + weight)
{
/*边的终点的最小开销=边的起点的最小开销+边的权重*/
vertex[end].smallCost = vertex[start].smallCost + weight;
vertex[end].father = start;/*边的终点的父结点=边的起点*/
}
}
}
}
/*Bellman-Ford算法*/
bool Bellman_Ford(int s)
{
RelaxSingleSource(s);
int i;
for (i = 0; i <= LINENUMBER; i++) /*遍历每一条边*/
{
int start = line[i].start;/*边的起点x*/
int end = line[i].end;/*边的终点y*/
int weight = line[i].weight;/*边的权重z*/
/*如果边的起点的最小开销≠无穷 且 边的终点的最小开销>边的起点的最小开销+权重*/
if (vertex[start].smallCost != INT_MAX && vertex[end].smallCost>vertex[start].smallCost + weight)
return false;/*表示有负的环路*/
}
return true;
}
/*打印*/
void PrintSingleSource(int src,int des)
{
if (des == src)
{
switch (des)
{
case 0:cout << 's'; break;
case 1:cout << 't'; break;
case 2:cout << 'x'; break;
case 3:cout << 'y'; break;
case 4:cout << 'z'; break;
default:
break;
}
}
else
{
PrintSingleSource(src, vertex[des].father);
switch (des)
{
case 0:cout << "-->" << 's'; break;
case 1:cout << "-->" << 't'; break;
case 2:cout << "-->" << 'x'; break;
case 3:cout << "-->" << 'y'; break;
case 4:cout << "-->" << 'z'; break;
default:
break;
}
}
}
void TestSingleSource()
{
InitSingleSource(0);/*初始化*/
int s = 0; int i;
line[0] = { 0,1,6 };
line[1] = { 0,3,7 };
line[2] = { 1,2,5 };
line[3] = { 2,1,-2 };
line[4] = { 1,3,8 };
line[5] = { 3,2,-3 };
line[6] = { 3,4,9 };
line[7] = { 4,2,7 };
line[8] = { 1,4,-4 };
line[9] = { 4,0,2 };
if (Bellman_Ford(s))
PrintSingleSource(0, 4);
else
cout << "!empty" << endl;
}
运行结果
任务二
点对最短路径.h
#pragma once
#include <iostream>
#include <vector>
#define POINTSIZE 5/*点的个数*/
using namespace std;
/*初始化路径*/
void InitPointPair(vector<vector<int>> &array, vector<vector<int>> &Path);
/*Floyd算法*/
void Floyd_Warshall(vector<vector<int>> &Distance, vector<vector<int>> &Path, vector<vector<int>> &Array);/*返回一个二维数组指针*/
/*显示计算结果*/
void ShowResult(vector<vector<int>> &Distance, vector<vector<int>> &Path);
/*打印矩阵*/
void ShowVector(vector<vector<int>> &vec);
void test();
点对最短路径.cpp
#include "stdafx.h"
#include "点对最短路径.h"
/*初始化路径*/
void InitPointPair(vector<vector<int>> &array, vector<vector<int>> &Path)
{
for (int i = 0; i < POINTSIZE; i++)
{
for (int j = 0; j < POINTSIZE; j++)
{
if (array[i][j] < INT_MAX)
Path[i][j]=j;
}
}
}
/*Floyd算法*/
void Floyd_Warshall(vector<vector<int>> &Distance, vector<vector<int>> &Path, vector<vector<int>> &Array)/*返回一个二维数组指针*/
{
Distance = Array;
for (int k = 0; k < POINTSIZE; k++)
{
for (int i = 0; i < POINTSIZE; i++)
{
for (int j = 0; j < POINTSIZE; j++)
{
if (Distance[i][j] > Distance[i][k] + Distance[k][j])
{
Distance[i][j] = Distance[i][k] + Distance[k][j]; //发现了更短的距离,取代前者
Path[i][j] = Path[i][k]; //更新路径
}
}
}
}
}
/*显示计算结果*/
void ShowResult(vector<vector<int>> &Distance, vector<vector<int>> &Path)
{
for (int i = 0; i < POINTSIZE; i++)
{
for (int j = 0; j < POINTSIZE; j++)
{
printf("结点%d到结点%d的最短路径是为%d,\t", i, j, Distance[i][j]);
int k = Path[i][j];
if (k == -1)
cout << "路径不存在!" << endl;
else
{
/*打印i->j的路径*/
cout << "("<<i;
while (k != j)
{
cout << "->" << k;
k = Path[k][j];
}
cout << "->" << j<<")"<<endl;
}
}
}
}
/*打印矩阵*/
void ShowVector(vector<vector<int>> &vec)
{
for (int i = 0; i < POINTSIZE; i++)
{
for (int j = 0; j < POINTSIZE; j++)
{
if (vec[i][j] < INT_MAX / 2)
cout << vec[i][j] << " ";
else
cout << "∞" << " ";
}
cout << endl;
}
}
void test()
{
//vector<vector<int> > Array;/*邻接矩阵*/
vector<vector<int> > Path;/*计算路径*/
vector<vector<int> > Distance;/*计算距离*/
Path = vector<vector<int> >(POINTSIZE, vector<int>(POINTSIZE, -1));/*数组元素的初始值为-1*/
vector<vector<int> > Array(5, vector<int>(5,INT_MAX / 2));/*vector<int>(5, INT_MAX / 2)*/
Array[0][1] = 3; Array[0][2] = 8; Array[0][4] = -4;
Array[1][3] = 1; Array[1][4] = 7;
Array[2][1] = 4;
Array[3][0] = 2; Array[3][2] = -5;
Array[4][3] = 6;
for (int i = 0; i <POINTSIZE; ++i) Array[i][i] = 0;/*自己到自己的距离=0*/
InitPointPair(Array, Path);/*初始化*/
cout << "初始化的邻接矩阵为:" << endl;
ShowVector(Array);
cout << endl << "Floyd计算后的邻接矩阵为:" << endl;
Floyd_Warshall(Distance, Path, Array);
ShowVector(Distance);
cout << "每两个结点之间的路径:" << endl;
ShowResult(Distance, Path);
/*vector<vector<int>> W(5, vector<int>(5, INT_MAX / 2));
W[0][1] = 3; W[0][2] = 8; W[0][4] = -4;
W[1][3] = 1; W[1][4] = 7;
W[2][1] = 4;
W[3][0] = 2; W[3][2] = -5;
W[4][3] = 6;
for (int i = 0; i < W.size(); ++i) W[i][i] = 0;
Floyd_Warshall fw(W);
cout << "初始化的邻接矩阵为:" << endl;
fw.show_vec(W);
cout << endl << "Floyd计算后的邻接矩阵为:" << endl;
fw.show_vec(fw.floyd_warshall());
cout << "每两个结点之间的路径:" << endl;
fw.show_path();
vector<vector<int>>*/
}
运行结果
好了,全部结束了,这边并不全是我本人自己写的,很多都是借鉴网上一些大触的作品,感谢无私奉献的各位大触!
最后,希望你有所收获。