日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

蛮力法的相关问题总结

發布時間:2024/3/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蛮力法的相关问题总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天想寫寫關于蠻力法的一些問題,也給之后自己留下一個筆記。
蠻力法關鍵------依次處理所有元素

1.查找問題中的蠻力法

  • 順序查找
int SeqSearch(int r[],int n,int k) { i=n; while(i>0&&r[i]!=k)i--;return i; }

上述算法基本語句是i>0和r[i]!=k,其執行次數為:
O(n)
改進的順序查找
將帶查找值放在查找方向的盡頭處,免去在查找過程中每一次比較后都要判斷查找位置是否越界,從而提高查找速度。

int SeqSearch(int r[],int n,int k) { r[0]=k;i=n; while(r[i]!=k)i--;return i; }

此算法的基本語句是r[i]!=k,其執行次數為:(n+1)/2
O(n)數量級相同,系數相差一半

  • 串匹配問題
//文本 T[0...n-1]長度為n //模式P[0....m-1]長度為m //查找不成功返回-1 forint i=0;i<=n-m;i++{j=0;while(j<m&&P[j]==T[i+j])j++;if(i==m)return i;return -1; }

考慮最壞的情況,每趟不成功匹配都發生在串T的最后一個字符,在(i-1)趟不成功的匹配中共比較了(i-1)m次,第i趟成功的匹配共比較了m次,所以總共比較了im 次,因此平均比較次數是:m(n-m+2)/2

2.排序問題中的蠻力法

  • 選擇排序
  • void SelectSort(int r[],int n){for(int i=0;i<n-1;i++){index=i;for(j=i+1;j<=n;j++)if(r[j]<r[index])index=j;if(index!=i)r[i]------r[index] //交換這兩的元素位置} }

    基本語句是內層循環體中的比較語句r[j]<r[index],執行次數n(n-1)/2,O(n^2)
    3. 冒泡排序

    void Sort(int r[],int n){for(i=1;i<=n-1;i++){for(j=1;j<=n-i;j++)if(r[j]>r[j+1])r[j]----r[j+1] //交換元素} }

    組合問題中的蠻力法

  • 生成排列對象
    用蠻力法生成{1,2…,n}的所有n!個排列。
  • 例:

    開始 1

    插入 2 12 21

    插入3 123 132 312 213 231 321

    //偽代碼: //先生成初始排列{1};for(i=2;i<=n;i++)for(j=1;j<=(i-1)!;j++)for(k=i;k>=1;k--)將i插入到第j個排列中的第k個位置;

    借鑒代碼https://blog.csdn.net/wlk1229/article/details/7596837

    /*蠻力法解決全排列問題*/ #include<iostream> #include<string> using namespace std;void insert(char c1[], char c2[], char c, int i) //將c 插入c1 并將c1復制到c2 {int j;for (j = 0; j < i; j++)c2[j] = c1[j];c2[i] = c;for (j = i + 1; j <= strlen(c1) + 1; j++)c2[j] = c1[j - 1]; }void perml(int n)//為生成排列集合元素的個數 {int i, j, k, m = 1;char **c[2];//采用兩個字符序列存儲,分別存儲i-1和i的全排列c[1] = new char*[1];c[1][0] = new char[2];c[1][0][0] = '1'; c[1][0][1] = 0;for (i = 2; i <= n; i++){m = m*(i - 1);c[i % 2] = new char*[m*i];for (j = 0; j < m; j++){for (k = 0; k < i; k++){c[i % 2][j*i + k] = new char[i + 1];insert(c[(i + 1) % 2][j], c[i % 2][j*i + k], char(i + '0'), k);}delete[] c[(i + 1) % 2][j];}delete[] c[(i + 1) % 2];}for (i = 0; i < m*n; i++){cout << "第" << i + 1 << "排列:" << c[n % 2][i] << endl;delete[] c[n % 2][i];} }int main() {perml(3);return 0; }
  • 生成子集
    字典序
  • list_1=[] list_2=[] answer=[] n=int(input("input:")) for i in range(0,n):list_1.append(input("input:"))list_2.append(0) sum1=0 i=n-1 print(answer) while sum1<n:i=n-1if list_2[i]==0:list_2[i]=1else:list_2[i]=0while i>0:if list_2[i-1]==1:list_2[i-1]=0i=i-1else:list_2[i-1]=1breaksum1=sum(list_2)for i in range(0,n):if list_2[i]==1:answer.append(list_1[i])print(answer)answer.clear()
  • 0/1背包問題
    用蠻力法解決0/1背包問題,需要考慮給定的n個物品集合的所有子集,找出所有可能的子集,計算每個子集的總價值,然后在他們中找到價值最大的子集。對于一個具有n個元度的集合,其子集的數量是2^n,所以無論生成子集的算法效率有多高,蠻力法都會導致一個2的n次方的算法。
    自己寫的有點糙,還是根據上面那個代碼改進著來的
  • list_weight=[] list_vlaue=[] list_2=[] maxweight=int(input("輸入背包最大容量:")) n=int(input("input n:")) for i in range(0,n):list_weight.append(int(input("輸入第"+str(i+1)+"件物品的重量:")))list_vlaue.append(int(input("輸入第"+str(i+1)+"件物品的價值:")))list_2.append(0) sum1=0 sumw=0 sumv=0 i=n-1 while sum1<n:i=n-1sw=0sv=0if list_2[i]==0:list_2[i]=1else:list_2[i]=0while i>0:if list_2[i-1]==1:list_2[i-1]=0i=i-1else:list_2[i-1]=1breaksum1=sum(list_2)for i in range(0,n):if list_2[i]==1:sw=sw+list_weight[i]sv=sv+list_vlaue[i]if sw<maxweight and sv>sumv:sumw=swsumv=svprint(sumv)
    • 任務分配問題
      假設有n個任務需要分配給n個人執行,每個任務只分配給一個人,每個人只分配一個任務,且第j個任務分配給第i個人的成本是C [ i, j ]1<=i,j<=n),任務分配問題要求找出總成本最小的分配方案。

    圖問題中的蠻力法

    • 哈密頓回路問題
      對給定的無向圖G=(V,E),首先生成圖中所有的頂點的排列對象(vi1,vi2,)然后依次考察每個排列對象是否滿足一下兩個條件:1.相鄰頂點之間存在邊;2.最后一個頂點和第一個頂點之間存在邊 滿足這倆條件的回路就是哈密頓回路。
      考察所有點的排列對象,O(n!)

    • TSP問題
      旅行家要旅行n個城市然后回到出發城市,要求各個城市經歷且經歷一次,并要求所走的路程最短。用蠻力法解決,找出所有可能的旅行路線,從中選取路徑長度最短的簡單回路。

    幾何問題中的蠻力法

    • 最近對問題
      最近對問題要求找出一個包含n個點的集合中距離最近的兩個點;蠻力法求解是分別計算呢每一對點之間的距離,然后找出距離最小的那一對,為了避免對同一對點計算兩次距離,只考慮i<j的那些點對(pi,pj)
      大致思路如下 O(n^2)
    int ClosesPoints(int n,int x=[],int y[],int &index1,int &index2){minDist=無窮大for(int i=1;i<n;i++)for(int j=i+1;j<n;j++){d=(x[i]-x[j])^2+(y[i]-y[j])^2;if(d<minDist){ minDist=d;index1=i;index2=j;}} return minDist; }
    • 凸包問題
      一個點集S的凸包是包含S的最小凸集合,其中,最小是指S的凸包一定是所有包含S的凸集合的子集,對于平面上的n個點的集合S,他的凸包就是包含所有這些點的最小凸多邊形。蠻力法解決凸包問題的基本思想:對于一個由n 個點構成的集合S中的兩個點P1和P2,當且僅當該集合中的其他點都位于穿過這兩點的直線的同一邊時,他們的連線就是該集合凸包邊界的一部分。對每一對頂點都檢驗一遍之后,免租條件的線段構成了該凸包的邊界。
      在平面上 穿過兩點的直線是 ax+by=c (a=y2-y1,b=x1-x2,c=x1y2-x2y1)
      這條線吧平面分成零分半平面,其中一個的點滿足 ax+by>c
      另一個ax+by<c
      時間復雜性是O(n的 三次方)
      步驟:
      將點集里面的所有點兩兩配對,組成 n(n-1)/2 條直線。
      對于每條直線,再檢查剩余的 (n-2) 個點是否在直線的同一側。
      如何判斷一個點 p3 是在直線 p1p2 的左邊還是右邊呢?(坐標:p1(x1,y1),p2(x2,y2),p3(x3,y3)) ???
      https://blog.csdn.net/u011001084/article/details/72768075
      借鑒某一大佬寫的可視化版本凸包問題
    import random import matplotlib.pyplot as pinput = int(input('輸入生成點的數量:')) dot = [[0] * 3 for i in range(input)] x = [[0] * 2 for a in range(int(input * (input - 1) / 2))] y = [[0] * 2 for b in range(int(input * (input - 1) / 2))] fg = p.figure() cn = fg.add_subplot(1, 1, 1) cn.set_xlim(0, 1000) cn.set_ylim(0, 1000) p.ion() for i in range(input):dot[i][0] = random.randrange(1000)dot[i][1] = random.randrange(1000)dot[i][2] = 0def judge(inp):n = 0for i in range(inp):for j in range(i + 1, inp):a = dot[j][1] - dot[i][1]b = dot[i][0] - dot[j][0]c = (dot[i][0] * dot[j][1]) - (dot[i][1] * dot[j][0])sign1 = 0sign2 = 0x[n][0] = dot[i][0]x[n][1] = dot[j][0]y[n][0] = dot[i][1]y[n][1] = dot[j][1]n += 1for k in range(inp):if k == j or k == i:continueif a * dot[k][0] + b * dot[k][1] == c:sign1 += 1sign2 += 1if a * dot[k][0] + b * dot[k][1] > c:sign1 += 1if a * dot[k][0] + b * dot[k][1] < c:sign2 += 1if (sign1 == (inp - 2)) or (sign2 == (inp - 2)):dot[i][2] = 1dot[j][2] = 1cn.scatter(dot[i][0], dot[i][1], color='g', marker='.')cn.scatter(dot[j][0], dot[j][1], color='g', marker='.')cn.plot(x[n - 1], y[n - 1], color='b')cn.scatter(dot[i][0], dot[i][1], color='g', marker='.')cn.scatter(dot[j][0], dot[j][1], color='g', marker='.')cn.plot(x[n - 1], y[n - 1], color='r')p.pause(0.1)cn.lines.pop()judge(input) print("凸包極點:") for i in range(input):if dot[i][2] == 1:print((dot[i][0], dot[i][1]))

    總結

    以上是生活随笔為你收集整理的蛮力法的相关问题总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。