基本算法之蛮力法

来源:互联网 发布:单身为什么不好 知乎 编辑:程序博客网 时间:2024/04/29 23:39

选择排序(不稳定)

void SelectionSort(int *a,int n)  {
    int i,j,min;
    int temp;
    for(i=0;i!=n-1;++i)    {
        min=i;    
        for(j=i+1;j!=n;++j)    {
        
        if(a[j]<a[min])    {
        
            min=j;
        }
        
        
        }
    if(min!=i)    {
    temp=a[min];
    a[min]=a[i];
    a[i]=temp;
    
    }
    }
}


冒泡排序(稳定的)


void BubbleSort(int *a,int n)    {


int i,j,temp;


for(i=1;i!=n;++i)
    for(j=0;j!=n-i;++j)    {
            
        if(a[j+1]<a[j])    {
    
            temp=a[j+1];
            a[j+1]=a[j];
            a[j]=temp;
        }
    
    }
}





顺序查找,将查找键置于末尾可以避免反复判断是否到达数组末尾

int SequentialSearch(int *a,int n,int K)    {

    a[n]=K;
    int i=0;
    while(a[i]!=K)    {
        ++i;
    
    }
    if(i!=n)
        return i;
    else
        return -1;

}


//    蛮力法 实现字符串匹配

算法的最差效率为O(mn);

该算法的平均效率比最差效率要好的多,在查找随即文本的时候显示出线性的效率-----O(n);

int BruteForceStringMatch(int n,char *T,int m,char* P)    {

    int i,j;
    for(i=0;i<=n-m;++i)    {
        j=0;
        while(j<m&&P[j]==T[i+j])    {
        ++j;
        
        }
        if(j==m)
            return i;
    }
    return -1;
}



//  蛮力法求最近对问题

float BruteForceClosestPoint(vector<Point> pcollection,int &index1,int &index2)    {
    
    float dmin=MAXDIN;
    float tempmin;
    int i,j;
    int n=pcollection.size();
    
    for(i=0;i!=n-1;++i)
        for(j=i+1;j!=n;++j)    {
        
            tempmin=(pcollection[i].x-pcollection[j].x)*(pcollection[i].x-pcollection[j].x)+(pcollection[i].y-pcollection[j].y)*(pcollection[i].y-pcollection[j].y);
            if(dmin>tempmin)    {
            
                dmin=tempmin;
                index1=i;
                index2=j;
            }
        
        
        }
  return sqrt(dmin);


}

其中 index1和index2 分别表示最近点对在容器中的位置,  返回最近点对的距离;在编代码的过程中还得到了一个 结论:  在容器中还没有赋值之前,不能用下标的方法进行赋值,下标的方法只能是访问容器中已有的数据或是赋值以后进行更改操作。


求凸包中极点的算法

#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct Point{
    float x;
    float y;
};

typedef struct PointPair{
    Point a;
    Point b;
};


int _tmain(int argc, _TCHAR* argv[])
{
    
    Point PointCollection[7];
    PointPair PairCollection[7];
    cout<<"shru"<<endl;
    int i=0;
    for(;i!=7;++i)    {
        cin>>PointCollection[i].x>>PointCollection[i].y;
        //cout<<endl;
    }
    i=0;
    int j=0;
    float a,b,c;
    int k=0;
    
    int num1=0,num2=0;
    int num3=0;
    for(i=0;i<6;++i)
        for(j=i+1;j!=7;++j)    {
            a=PointCollection[i].y-PointCollection[j].y;
            b=PointCollection[j].x-PointCollection[i].x;
            c=PointCollection[j].x*PointCollection[i].y-PointCollection[i].x*PointCollection[j].y;
            
            for(k=0;k!=7;++k){
            
                if(k!=i&&k!=j)    {
                
                    if(PointCollection[k].x *a+b*PointCollection[k].y>=c){
                    
                        ++num1;

}
                        else if(PointCollection[k].x *a+b*PointCollection[k].y<=c){
                    
                        ++num2;

                    }
               }
         }

            if(num1==5||num2==5)    {
                PairCollection[num3].a=PointCollection[i];
                PairCollection[num3].b=PointCollection[j];
                num3++;
            }
            num1=0;
            num2=0;
      }
    
    for(i=0;i!=num3;++i)
        cout<<"{  ""("<<PairCollection[i].a.x<<","<<PairCollection[i].a.y<<")"<<"--"<<PairCollection[i].b.x<<","<<PairCollection[i].b.y<<")"<<"  }"<<endl;
    system("pause");
    return 0;
}

其中PointPair类型为点对类型,用于存放凸包边对应的两个顶点,我假设只输入7个点,当点的数量为其他是少许修改就可以了。


递归法求全排列

思路:对三个数进行求全排列GetPermutation(1,2,3),需要执行以下操作1+GetPermutation(2,3),2+GetPermutation(1,3),3+GetPermutation(2,1),

当只剩下一个数时则打印出数组中的数据,此时得到一个全排列。

  //交换两个数

void Swap(int &a,int &b)    {

    int temp;
    temp=a;
    a=b;
    b=temp;

}

void GetPermutation(int *a,int first,int last)    {
    
    int i;
    if(first==last){
        
        for(i=0;i<=last;++i)    {
             cout<<a[i]<<" ";
 }
     cout<<endl;
    }

    else{
    
        for(i=first;i<=last;++i)    {
            Swap(a[first],a[i]);
            GetPermutation(a,first+1,last);
            Swap(a[first],a[i]);
        }
    }
}

示例:int a[3]={0,1,2},GetPermutation(a,0,2)


蛮力法求旅行商问题

思路:旅行商问题其实是最小哈密顿回路问题,首先需要求出所有节点的全排列,然后分别求出每条路径的花费,最终得出最小花费及路径,本程序只输出了最小花费,并且是以有4个节点为假设的,当节点数为其他时类似。

#include "stdafx.h"
#include<iostream>
using namespace std;
int perarr[50][4];       //   存放所有排列的全局数组
int pernum=0;         //   存放得到的排列个数

/*    求全排列   */

void Swap(int &a,int &b)    {

    int temp;
    temp=a;
    a=b;
    b=temp;

}

void GetPermutation(int *a,int first,int length)    {
    
    int i;
    if(first==length){
        
        for(i=0;i<=length;++i)    {
            
            cout<<a[i]<<" ";
            perarr[pernum][i]=a[i];
        
        }
        ++pernum;
        cout<<endl;
    }

    else{
    
        for(i=first;i<=length;++i)    {
            Swap(a[first],a[i]);
            GetPermutation(a,first+1,length);
            Swap(a[first],a[i]);
        }
    }
}

/*    求全排列   */


int _tmain(int argc, _TCHAR* argv[])
{
    int a[4];
    int i;
    int inf[4][4];
    int num,j;
    //  初始化图
    for(i=0;i<4;++i)
        for(j=0;j<4;++j)    {
            if(i==j)
                inf[i][j]=0;
            else
            inf[i][j]=10000;
            
        
        }
    //填写每条路径的花费

    cout<<"输入边的条数:"<<endl;
    cin>>num;
    cout<<"输入个边:"<<endl;
    int firstvex,secondvex;
    for(i=0;i<num;++i)    {
        cin>>firstvex>>secondvex;
        cin>>inf[firstvex][secondvex];
        inf[secondvex][firstvex]=inf[firstvex][secondvex];
    
    }
    
//    初始化节点编号,0,1,2,3
    for(i=0;i<4;++i)    {
    a[i]=i;
    
    };

    GetPermutation(a,0,3);           //  获取全排列 存放在perarr中
    int min=10000;
    int cost;    
   

   //计算每个排列的花费,并不断输出每个排列及其花费,以及当前最小的花费

   for(i=0;i<pernum;++i)
    {
        cost=0;
        for(j=0;j<3;++j)    {
            cost+=inf[perarr[i][j]][perarr[i][j+1]];
            cout<<perarr[i][j]<<" ";
        }
        cout<<perarr[i][j]<<" "<<perarr[i][0];
        cost+=inf[perarr[i][j]][perarr[i][0]];
        cout<<"   本次cost为:"<<cost;
        if(cost<min)    {
        
        min=cost;
        }
        cout<<"    当前最小cost为:"<<min<<endl;

    
    }
    cout<<endl<<"最小路径成本:"<<min<<endl;
    system("pause");    
    return 0;
}


蛮力法求01背包问题

思路: 分别对n个物品的所有子集计算,找出最大价值且满足背包容量;其中对没个子集都有对应的一个长度为n的二进制表示其对物品是取还是不取。

#include "stdafx.h"
#include<iostream>
using namespace std;
#define  MAXNUM 10;
struct good{
    int id;
    float weight;
    float value;

};
// 将数字a转化为二进制样式,以此来表示2的n次方种情况
void ConvertBinary(int a,int bin[10])    {
    int i;
    for(i=0;i<10;++i)    {
        bin[i]=0;
    
    }
    for(i=0;i<10;++i)    {
        bin[i]=a%2;
        a=a/2;
        if(a==0)
            break;
    }
}

void KnapsackBrute(int n,int knapsackcontain,good goodarr[10],int combination_result[10],float &maxvalue)    {

    int i,j,k;
    int bin[10];
    

    float totalvalue;
    float totalweight;
    maxvalue=0;
    for(i=0;i<pow(float(2),float(n));++i)    {                               //  pow(2,n)   是指2的n次方
        ConvertBinary(i,bin);

            totalvalue=0;
            totalweight=0;
        for(j=0;j<n;++j)    {

            if(bin[j]==1)    {
                
                totalvalue+=goodarr[j].value;
                totalweight+=goodarr[j].weight;
            }
        }
        if(totalweight<=knapsackcontain&&totalvalue>maxvalue)    {
        
            maxvalue=totalvalue;
            for(k=0;k<n;++k)
                combination_result[k]=bin[k];
        
        }
        
    }

}
int _tmain(int argc, _TCHAR* argv[])
{
    
    int combination_result[10];
    float maxvalue=0;
    int goodnum=0,knapsackcontain=0;
    good goodarr[10];
    cout<<"请输入物品的个数(<10)以及背包的最大容量:"<<endl;
    cin>>goodnum>>knapsackcontain;

    cout<<"请输入每一个物品的编号、重量以及价值:"<<endl;
    int i;
    for(i=0;i<goodnum;++i)    {
        cin>>goodarr[i].id>>goodarr[i].weight>>goodarr[i].value;
    }

    KnapsackBrute(goodnum,knapsackcontain,goodarr,combination_result,maxvalue);

    
    for(i=0;i<goodnum;++i)    {
        if(combination_result[i]==1)
            cout<<goodarr[i].id<<"("<<goodarr[i].weight<<","<<goodarr[i].value<<")"<<"   ";
    
    }
    cout<<endl<<"最大价值为:"<<maxvalue;
    system("pause");
    return 0;
}

原创粉丝点击