MATLAB 部分函数在C++中的转化

来源:互联网 发布:软件开发是什么专业 编辑:程序博客网 时间:2024/06/01 09:09

最近帮一位博三的学长翻译了一份MATLAB的代码,学长是控制专业的,没有系统学过数据结构和算法,只学过基础的C语言,做科研的大部分程序都是用MATLAB写的,MATLAB功能确实强大,但是程序的执行效率非常低,在我帮忙写的这份代码里,学长是在做一个调度算法,是一个NP问题,代码就有2000多行,其中包含了大量的暴力计算,其他同行用类似的算法用C写的程序一般在几百秒能跑出来的程序,MATLAB跑了上万秒,根本不在一个数量级,通过将MATLAB代码转化为C++可以大幅提高程序的执行效率,我在“翻译”代码的过程中也对程序进行了优化,但是翻译的过程中遇到很多MATLAB自带的函数,非常麻烦,要手动实现,在这里我把实现方法记录一下。后面学习到更多的之后还会继续来补充。


setC=setdiff(setA,setB);

这句话意思是给两个集合,然后返回setA-(setA交setB)。

vector<int>setdiff(vector<int>a,vector<int>b){    vector<int>r;    bool have[400];    for(int i=0;i<D;i++){//D是a和b里元素的数据上限,全局变量,在这个项目里,a和b的元素大小都是小于D的,而且D一般不超过400,我就空间换时间了        have[i]=0;    }    int lb=b.size();    for(int i=0;i<lb;i++){        have[b[i]]=1;    }    int la=a.size();    for(int i=0;i<la;i++){        if(!have[a[i]]){            r.push_back(a[i]);        }    }    return r;}

R=randperm(N);

返回一个大小是N的集合,其中是1~N的随机数,且不重复。

C++项目中用的数组下标都是从0开始的,MATLAB都是从1开始的,因此我在写这个函数的时候,把他生成的元素范围调整到了0~N-1,如果有需求,改一下就好。

struct num{//先声明一个结构体(相当于pair的功能了),key值是v    int index;    int v;    friend bool operator<(const num&a,const num&b){        return a.v<b.v;    }};int* randperm(int N){//生成N个不同的0-N-1的随机数    num A[300];//这个项目的数据范围N最大是120,如果有其他需求改成vector也可以    for(int i=0;i<N;i++){        A[i].index=i;        A[i].v=rand();    }    sort(A,A+N);    int x[300];    for(int i=0;i<N;i++){        x[i]=A[i].index;    }    return x;}

B=sortrows(A,col);

函数的意思是将矩阵A按照第|col|列排序,如果col>0就升序,如果col<0就降序,我的实现思路还是另起一个元素,其中包含两个值,一个是每行的索引值,另一个就是第col列的key值,取出来单独排序,然后再根据排序完的key值所对应的索引值还原出整个矩阵。

sortrows在这个程序中用的次数很多,而且排序的矩阵的列数又各有不同,由于c++传参的时候如果要传二维数组,要规定数组的第二维的大小,如果每次传进来前都要复制到一个规定大小的数组,运算后再转换回去,势必会影响程序执行效率。而且学长经常乱用sortrows,有时候就为了取个极值,或者就想得到sortrows之后的矩阵的索引值,就把整个数组sortrows一遍,实在是过于消耗时间,因此我没有写专门的函数,对于每次sortrows,我都根据程序的目的手动实现了。

struct sorte{//索引排序元素    int index;    int v;    sorte(){};    sorte(int V,int i){        index=i;        v=V;    }    friend bool operator<(const sorte &a,const sorte &b){        if(a.v==b.v)return a.index<b.index;        else return a.v<b.v;    }};sorte temp[400];int G[maxN][20];int temp_cnt=0;for(int j=0;j<D;j++){    temp[temp_cnt++]=sorte(G[j][8],temp_cnt);}sort(temp,temp+temp_cnt);
如果就为了得到索引值,这样就够了,如果还需要还原出排序完的矩阵,temp里得到了索引值之后,先把原来的保存一下,然后再按照索引值复制回来就行了。


1 0
原创粉丝点击