蛮力法的相关问题总结
今天想寫(xiě)寫(xiě)關(guān)于蠻力法的一些問(wèn)題,也給之后自己留下一個(gè)筆記。
蠻力法關(guān)鍵------依次處理所有元素
1.查找問(wèn)題中的蠻力法
- 順序查找
上述算法基本語(yǔ)句是i>0和r[i]!=k,其執(zhí)行次數(shù)為:
O(n)
改進(jìn)的順序查找
將帶查找值放在查找方向的盡頭處,免去在查找過(guò)程中每一次比較后都要判斷查找位置是否越界,從而提高查找速度。
此算法的基本語(yǔ)句是r[i]!=k,其執(zhí)行次數(shù)為:(n+1)/2
O(n)數(shù)量級(jí)相同,系數(shù)相差一半
- 串匹配問(wèn)題
考慮最壞的情況,每趟不成功匹配都發(fā)生在串T的最后一個(gè)字符,在(i-1)趟不成功的匹配中共比較了(i-1)m次,第i趟成功的匹配共比較了m次,所以總共比較了im 次,因此平均比較次數(shù)是:m(n-m+2)/2
2.排序問(wèn)題中的蠻力法
基本語(yǔ)句是內(nèi)層循環(huán)體中的比較語(yǔ)句r[j]<r[index],執(zhí)行次數(shù)n(n-1)/2,O(n^2)
3. 冒泡排序
組合問(wèn)題中的蠻力法
用蠻力法生成{1,2…,n}的所有n!個(gè)排列。
例:
開(kāi)始 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個(gè)排列中的第k個(gè)位置;借鑒代碼https://blog.csdn.net/wlk1229/article/details/7596837
/*蠻力法解決全排列問(wèn)題*/ #include<iostream> #include<string> using namespace std;void insert(char c1[], char c2[], char c, int i) //將c 插入c1 并將c1復(fù)制到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)//為生成排列集合元素的個(gè)數(shù) {int i, j, k, m = 1;char **c[2];//采用兩個(gè)字符序列存儲(chǔ),分別存儲(chǔ)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; }字典序
用蠻力法解決0/1背包問(wèn)題,需要考慮給定的n個(gè)物品集合的所有子集,找出所有可能的子集,計(jì)算每個(gè)子集的總價(jià)值,然后在他們中找到價(jià)值最大的子集。對(duì)于一個(gè)具有n個(gè)元度的集合,其子集的數(shù)量是2^n,所以無(wú)論生成子集的算法效率有多高,蠻力法都會(huì)導(dǎo)致一個(gè)2的n次方的算法。
自己寫(xiě)的有點(diǎn)糙,還是根據(jù)上面那個(gè)代碼改進(jìn)著來(lái)的
- 任務(wù)分配問(wèn)題
假設(shè)有n個(gè)任務(wù)需要分配給n個(gè)人執(zhí)行,每個(gè)任務(wù)只分配給一個(gè)人,每個(gè)人只分配一個(gè)任務(wù),且第j個(gè)任務(wù)分配給第i個(gè)人的成本是C [ i, j ]1<=i,j<=n),任務(wù)分配問(wèn)題要求找出總成本最小的分配方案。
圖問(wèn)題中的蠻力法
-
哈密頓回路問(wèn)題
對(duì)給定的無(wú)向圖G=(V,E),首先生成圖中所有的頂點(diǎn)的排列對(duì)象(vi1,vi2,)然后依次考察每個(gè)排列對(duì)象是否滿足一下兩個(gè)條件:1.相鄰頂點(diǎn)之間存在邊;2.最后一個(gè)頂點(diǎn)和第一個(gè)頂點(diǎn)之間存在邊 滿足這倆條件的回路就是哈密頓回路。
考察所有點(diǎn)的排列對(duì)象,O(n!) -
TSP問(wèn)題
旅行家要旅行n個(gè)城市然后回到出發(fā)城市,要求各個(gè)城市經(jīng)歷且經(jīng)歷一次,并要求所走的路程最短。用蠻力法解決,找出所有可能的旅行路線,從中選取路徑長(zhǎng)度最短的簡(jiǎn)單回路。
幾何問(wèn)題中的蠻力法
- 最近對(duì)問(wèn)題
最近對(duì)問(wèn)題要求找出一個(gè)包含n個(gè)點(diǎn)的集合中距離最近的兩個(gè)點(diǎn);蠻力法求解是分別計(jì)算呢每一對(duì)點(diǎn)之間的距離,然后找出距離最小的那一對(duì),為了避免對(duì)同一對(duì)點(diǎn)計(jì)算兩次距離,只考慮i<j的那些點(diǎn)對(duì)(pi,pj)
大致思路如下 O(n^2)
- 凸包問(wèn)題
一個(gè)點(diǎn)集S的凸包是包含S的最小凸集合,其中,最小是指S的凸包一定是所有包含S的凸集合的子集,對(duì)于平面上的n個(gè)點(diǎn)的集合S,他的凸包就是包含所有這些點(diǎn)的最小凸多邊形。蠻力法解決凸包問(wèn)題的基本思想:對(duì)于一個(gè)由n 個(gè)點(diǎn)構(gòu)成的集合S中的兩個(gè)點(diǎn)P1和P2,當(dāng)且僅當(dāng)該集合中的其他點(diǎn)都位于穿過(guò)這兩點(diǎn)的直線的同一邊時(shí),他們的連線就是該集合凸包邊界的一部分。對(duì)每一對(duì)頂點(diǎn)都檢驗(yàn)一遍之后,免租條件的線段構(gòu)成了該凸包的邊界。
在平面上 穿過(guò)兩點(diǎn)的直線是 ax+by=c (a=y2-y1,b=x1-x2,c=x1y2-x2y1)
這條線吧平面分成零分半平面,其中一個(gè)的點(diǎn)滿足 ax+by>c
另一個(gè)ax+by<c
時(shí)間復(fù)雜性是O(n的 三次方)
步驟:
將點(diǎn)集里面的所有點(diǎn)兩兩配對(duì),組成 n(n-1)/2 條直線。
對(duì)于每條直線,再檢查剩余的 (n-2) 個(gè)點(diǎn)是否在直線的同一側(cè)。
如何判斷一個(gè)點(diǎn) p3 是在直線 p1p2 的左邊還是右邊呢?(坐標(biāo):p1(x1,y1),p2(x2,y2),p3(x3,y3)) ???
https://blog.csdn.net/u011001084/article/details/72768075
借鑒某一大佬寫(xiě)的可視化版本凸包問(wèn)題
總結(jié)
以上是生活随笔為你收集整理的蛮力法的相关问题总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: flink 的用途 场景
- 下一篇: 测试的生命周期