演算法篇 10 回溯法 工作分配 世界名畫監視

2021-07-25 13:09:09 字數 2390 閱讀 9794

本系列所有**

n個工作分給n個人,將i工作給j號人所需費用為c[i][j],設計一演算法為每人分配一工作,並且耗費最小。

這題也是一簡單的排列樹問題,方式類似於旅行售貨員問題,不同之處在於這裡不需要判斷是否有迴路,所以變得更簡單了。

程式源**:

#include #include //工作分配問題-回溯法

//排列樹

using namespace std;

class workassign

}public:

intsolve(int n_,int *time_,int *best,int max_time)

};int main()

; intwu[n+1];

workassignwa;

cout<

缺點分析:

在這裡同樣沒有加限界函式,其中一限界方法同於旅行售貨員問題,若當前耗費超過以求出的最優耗費,則不必搜尋當前結點的子樹。

題目:世界名畫陳列館由m×n個排列成矩形陣列的陳列室組成。為了防止名畫被盜,需要在陳列室中設定警衛機械人哨位。每個警衛機械人除了監視它所在的陳列室外,還可以監視與它所在的陳列室相鄰的上、下、左、右4 個陳列室。試設計乙個安排警衛機械人哨位的演算法,使得名畫陳列館中每乙個陳列室都在警衛機械人的監視之下,且所用的警衛機器人數最少。

欲監視這個m*n矩陣,我們先來假設在安排第n號房間時,從0~(n-1)號房間安排完畢,即下圖黑色陰影部分安排完畢,在安排?所標位置時,可安放機械人位置為五個有五角星標註的位置,經過分析可知上、左五角星不可能獲得最優安排,因為他們安排後分別只能多監視1、2個房間,所以下一步應安排在中、右、下這三位置中某乙個。

那麼判斷回溯結束即時房間全部安全,即不安全房間為0,此時應記錄當前最優解與當前全域性最優解比較。回溯時我們要變動對房間的監視情況,用一整數表示某房間監視情況,有一機械人監視到他就+1,此時該房間若為1則不安全房間減一,這樣在回溯時取消機械人後就應考慮-1,若該房間為0則不安全房間加一。

程式源**:

#include //世界名畫排列問題

//回溯法

//演算法時間複雜度不理想啊,7*7矩陣以上複雜度陡增。

//8*8矩陣用我這電腦跑了近50分鐘

using namespace std;

class point

point()};

class monitor else

//上if(t.x-1>0&&t.y>0&&t.x-1<=m&&t.y<=n)

//右if(t.x>0&&t.y+1>0&&t.x<=m&&t.y+1<=n)

//下if(t.x+1>0&&t.y>0&&t.x+1<=m&&t.y<=n)

//左if(t.x>0&&t.y-1>0&&t.x<=m&&t.y-1<=n)

}voidrecover(point &t)

else

//上if(t.x-1>0&&t.y>0&&t.x-1<=m&&t.y<=n)

//右if(t.x>0&&t.y+1>0&&t.x<=m&&t.y+1<=n)

//下if(t.x+1>0&&t.y>0&&t.x+1<=m&&t.y<=n)

//左

if(t.x>0&&t.y-1>0&&t.x<=m&&t.y-1<=n)

}pointfindnotsafe(point &t)const

//(t.x+1,t.y)

x2.x = t.x+1;

x2.y = t.y;

if (x2.x > 0 && x2.y > 0&& x2.x <= m && x2.y <= n)

}public:

intsolve(int m_,int n_,bool *res)

result = res;

bestc = m*n;

curr_c = 0;

not_safe=m*n; //當前不安全房間數

backtrack(point(1,1));

free(rooms);

free(robot);

return bestc;

}};

void show(int m_,int n_,bool *res)

cout<

}} int main(int argc,char *argv)

執行結果分析:

演算法時間複雜度不理想啊,7*7矩陣以上複雜度陡增。

8*8矩陣用我這電腦跑了近50分鐘 。優化方向應是增加一些剪枝函式加以限制。

提到過結點控制,但是我此時沒有想出來。

演算法入門(4) 回溯法

1 概念 回溯演算法實際上乙個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就 回溯 返回,嘗試別的路徑。回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術...

演算法實驗4《回溯法》

1.編寫乙個簡單的程式,解決8皇后問題。include using namespace std bool backtrack int list 8 int t return false intmain 2.批處理作業排程問題 問題描述 給定n個作業的集合j j1,j2,jn 每乙個作業ji都有兩項任...

演算法入門經典7 4回溯法

7.4.1八皇后問題 首先,得重新介紹一下遞迴。這是非常必要的,因為事先我沒有在意這個,導致我理解。困難 遞迴就是 乙個過程或函式在其定義或說明中又直接或間接呼叫自身的一種方法,它通常把乙個大型複雜的問題層層轉化為乙個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要...