贪心法

贪心法贪心法贪心算法并不是从整体最优上加以考虑 而是从局部最优考虑 每次总是做出当前看起来最好的选择 在某种意义上的局部最优选择 最优子结构性质 贪心选择性质 1 nbsp 活动安排 问题描述 设有 n 个活动集合 E 1 2 n 其中每个活动 i 都要求使用同一资源 而在同一时间内只有一个活动能使用这一资源 每个活动 i 都有一个要求使用该资源的起始

贪心法

<*> 贪心算法并不是从整体最优上加以考虑, 而是从局部最优考虑, 每次总是做出当前看起来最好的选择,在某种意义上的局部最优选择;

<*> 最优子结构性质 :

<*>贪心选择性质:


贪心法




1、  活动安排 :

问题描述 :设有n个活动集合E = {1 ,2,…,n} ,其中每个活动i都要求使用同一资源, 而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间Si和一个结束时间fi , 且Si < fi 。如果选择活动i ,则它在半开区间[Si , fi]内占用资源。若区间[Si,fi)与区间不相交,则称活动i和活动j是相容的, 也就是说Si >= fj || Sj >= fi 为真时 ,活动i和活动j是相容的。

要求:要在所给的活动集中选出最大的相容子集合;

code>> #include         #include           #include             using namespace std; class Activity { public : int id; int s;//活动开始时间 int f;//活动结束时间 public: Activity() { cin >>this->s >> this->f; } friend void Arrange(); bool operator<(Activity &A1) { if (this->f < A1.f) { return true; } else { return false; } } }; //活动集E:所给活动的集合 vector               E;//竟然要加class vector                 A;//相容标记集合 void Arrange() { sort(E.begin() + 1, E.end());//将活动按非减序列排列 int j = 0; for (int i = 1; i < E.size(); i++) { if (E[i].s >= E[j].f) { A[i] = true; j = i; } } for (int i = 0; i < A.size(); i++) { if (A[i]) { cout << E[i].id<<" "; } } } int main() { int n;//活动数量 cin >> n; E.push_back(Activity()); E[0].s = 0; E[0].f = 0; for (int i = 1; i <= n; i++) { E.push_back(Activity()); E[i].id = E[i].s; } for (int i = 0; i <= n; i++) { A.push_back(false); } Arrange(); return 0; }                              


2、 背包问题:

给定n种物品和一个背包。物品i的重量是wi ,其价值为vi,背包的容量为c , 问应该如何选择把哪一个物品装入背包中,使得装入背包中的物品的总价值最大?

0-1背包问题:不能部分装入物品,

背包问题:可选择装入部分物品

贪心法



code>> #include           #include             #include               #include                 using namespace std; class WP { public : float w; float p; public : WP(float w, float p) { this->w = w; this->p = p; } bool operator<(WP wp) { if (1.0*w/p < 1.0*wp.w/wp.p) { return true; } else { return false; } } }; class Knapsack { public : vector                   wp; int n; float c; public : Knapsack() { cin >> this->n >> this->c; wp.push_back(WP(0 , 0)); for (int i = 1; i <= n; i++) { int in1, in2; cin>>in1>>in2; wp.push_back(WP(in1, in2)); } } }; vector < float > x; Knapsack ks; void GreedyKP() { x.push_back(0); sort(ks.wp.begin() + 1, ks.wp.end()); int sum = 0; int i; for (int i = 1; i < ks.n; i++) { x.push_back(0); } for (i = 1; i <= ks.n; i++) { if (ks.wp[i].w < ks.c) { x[i] = 1; ks.c -= ks.wp[i].w; } else { break; } } if (i < ks.n + 1) { x.push_back(1.0*ks.c/ks.wp[i].w); } for (int i = 1; i < x.size(); i++) { cout << ks.wp[i].w << " : " <                                             

3、  最优装载 :

问题描述:有一批集装箱要装上载重量为c的轮船。其中集装箱i的重量为wi , 最优装载问题要求在装载体积不受限制的情况下,将尽可能多的集装箱装上船;

贪心法



code>> #include 
   
     #include 
    
      #include 
     
       #include 
      
        using namespace std; //最优装载问题 class Loading { public : vector 
       
         w; float c; int n; public : Loading() { cin >> this->n >> this->c; w.push_back(0); for (int i = 1; i <= this->n; i++) { float in1; cin >> in1; this->w.push_back(in1); } } }; vector 
        
          x; Loading L = Loading(); void Load() { sort(L.w.begin()+1, L.w.end()); for (int i = 0; i <= L.n; i++) { x.push_back(0); } for (int i = 1; i < L.n; i++) { if (L.w[i] <= L.c) { x[i] = 1; L.c -= L.w[i]; } else { break; } } for (int i = 1; i <= L.n; i++) { if (x[i] == 1) { cout.precision(4); cout << "weght : " << L.w[i] << endl; } } } int main() { Load(); return 0; } 
         
        
       
      
     
   


4、  哈弗曼编码 :

问题描述:

贪心法

code>> Huffman.cpp #include"BinaryTree.h" #include 
   
     #include 
    
      #include 
     
       #include 
      
        using namespace std; typedef BinaryTree 
       
         HuffmanTree; typedef BinaryNode 
        
          HuffmanNode; class FC { public : float m_f; char m_c; public : FC(float f = 0 , char c = ' ') { m_f = f; m_c = c; } bool operator==(float f) { if (m_f == f) { return true; } else { return false; } } }; class Huffman { public : Huffman() { cin >> n; fc.push_back(FC()); fc[0].m_f = 10000; for (int i = 1; i <= n; i++) { float in1; char in2; cin >> in1; cin >> in2; fc.push_back(FC(in1, in2)); } //生成单结点树 for (int i = 0 ; i <= n; i++) { HuffmanTree z; z.MakeTree(fc[i].m_f , HuffmanTree() , HuffmanTree()); HT.push_back(z); } } public : int n;//字符总数 vector 
         
           fc;//字符出现的频率表 vector 
          
            HT; }; Huffman huff = Huffman(); vector 
           
             code; //构建哈弗曼树 HuffmanTree MakeHuffmanTree() { //建优先级队列 priority_queue 
            
              > Q; for (int i = 0; i <= huff.n; i++) { Q.push(huff.HT[i]); } for (int i = 1; i < huff.n; i++) { HuffmanTree x, y ,z; x = Q.top(); Q.pop(); y = Q.top(); Q.pop(); float w = x.m_root->m_data + y.m_root->m_data; z.MakeTree(w , x , y); Q.push(z); } return Q.top(); } //生成编码 void Huffmancode(HuffmanNode* root) { if (root != NULL) { if (root->m_pleft == NULL && root->m_pright == NULL) { vector 
             
               ::iterator iter = find(huff.fc.begin() + 1, huff.fc.end(), root->m_data) ; cout << iter->m_c <<"的编码 : "; for (int i = 1; i < code.size(); i++) { cout << code[i]; } cout << endl; } if (root->m_pleft != NULL) { code.push_back(0); Huffmancode(root->m_pleft); } if (root->m_pright != NULL) { code.push_back(1); Huffmancode(root->m_pright); } } code.pop_back(); } //译码 void Interpret(vector 
              
                s , HuffmanNode* root) { HuffmanNode* p = root; for (int i = 0; i < s.size(); i++) { if (NULL == p->m_pleft && NULL == p->m_pright) { vector 
               
                 ::iterator iter = find(huff.fc.begin() + 1, huff.fc.end(), p->m_data); cout << iter->m_c; p = root; } if (0 == s[i]) { p = p->m_pleft; } if (1 == s[i]) { p = p->m_pright; } } cout << endl; } int main() { HuffmanTree htree; htree = MakeHuffmanTree(); code.push_back(-1); Huffmancode(htree.m_root); vector 
                
                  scode; char in; while ((in = getchar()) != '#') { scode.push_back(in-48); } //前提Huffman树已建立 Interpret(scode , htree.m_root); return 0; } //上面用到的二叉树头文件BinaryTree.h #include 
                 
                   //定义结点类型 template 
                  
                    class BinaryTree;//预引用 template 
                   
                     class BinaryNode { public: BinaryNode() :m_pleft(NULL), m_pright(NULL) {};//无参构造函数 BinaryNode(Type item, BinaryNode 
                    
                      *pleft = NULL, BinaryNode 
                     
                       *pright = NULL) :m_data(item), m_pLeft(pleft), m_pright(pright) {};//含参构造函数 //friend //friend class BinaryTree 
                      
                        ; public : BinaryNode 
                       
                         *m_pleft, *m_pright; Type m_data; }; //定义二叉树 template 
                        
                          class BinaryTree { public: BinaryTree() : m_root(NULL){ }; void MakeTree(Type item, BinaryTree 
                         
                           LBTree, BinaryTree 
                          
                            RBTree ) { m_root = new BinaryNode 
                           
                             (); m_root->m_data = item; m_root->m_pleft = LBTree.m_root; m_root->m_pright = RBTree.m_root; } friend bool operator<(BinaryTree 
                            
                              BT1 , BinaryTree 
                             
                               BT2) { if (BT1.m_root->m_data < BT2.m_root->m_data) { return false; } else { return true; } } public: BinaryNode 
                              
                                *m_root; 
                               };  
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
   


5、 多机调度 :

贪心法


code>> #include 
    
      #include 
     
       #include 
      
        using namespace std; class JOB { public : JOB() { cin >> n >> m; jt.push_back(0); mt.push_back(0); for (int i = 1; i <= n; i++) { int in1; cin >> in1; jt.push_back(in1); } for (int i = 1; i <= m; i++) { mt.push_back(0); } }; public : int n, m; vector 
       
         jt; vector 
        
          mt; }; struct greater { bool operator()(int x , int y) const { return (x > y); } }; JOB J; void greedyJOB() { sort(J.jt.begin() + 1, J.jt.end() , greater()); int i; vector 
         
           ::iterator iter; for (i = 1; i <= J.n; i++) { if (i <= J.m) { J.mt[i] += J.jt[i]; } else { iter = min_element(J.mt.begin() + 1, J.mt.end()); *iter += J.jt[i]; } } iter = max_element(J.mt.begin() + 1, J.mt.end()); cout << *iter << endl; } int main() { greedyJOB(); return 0; } 
            
          
         
        
       
      
    
 

6、  Kruskal算法:

贪心法
 
code>> #include"UnionSet.h" #include 
     
       #include 
      
        #include 
       
         #include 
        
          using namespace std; class Edge { public : Edge(int i = -1, int j = -1, int weight = 1000) { this->i = i; this->j = j; this->weight = weight; } friend bool operator<(Edge E1 , Edge E2) { return (E1.weight >= E2.weight); } public: int i, j; int weight; }; class Graph { public : Graph() { cin >> vn >> en; edges.push_back(Edge()); for (int i = 1; i <= en; i++) { int in1, in2, in3; cin >> in1 >> in2 >> in3; edges.push_back(Edge(in1, in2, in3)); } } public : vector 
         
           edges;//边集 int vn;//顶点数 int en;//边数 }; Graph G; vector 
          
            minspt;//存储最小生成树中各边 //克鲁斯卡尔算法 void Kruskal() { priority_queue 
           
             > Q(G.edges.begin()+1 , G.edges.end()); /*Q.push(Edge()); for (int i = 1; i <= G.en; i++) { Q.push(G.edges[i]); } */ //初始化并查集 vector 
            
              S; S.push_back(PNode()); for (int i = 1; i <= G.vn; i++) { S.push_back(PNode(i, i)); } UnionSet U = UnionSet(S , G.vn); //边长递增序依次考察每条边 Edge s1; vector 
             
               ::iterator a ,b; for (int i = 1; i <= G.en; i++) { s1 = Q.top(); Q.pop(); a = U.Find(s1.i);//s1.i所在集合的头 b = U.Find(s1.j);//s2.j所在集合的头 if (a->data != b->data) { minspt.push_back(s1); U.Union(a->data, b->data); } } } int main() { Kruskal(); cout << "minimum_spanning_Tree : " << endl; for (int i = 0; i < minspt.size(); i++) { cout<<"( " << minspt[i].i <<" , " < 
              
                >上面用到的并查集: #pragma once #include 
               
                 #include 
                
                  #include 
                 
                   using namespace std; class PNode { public: PNode(int d = -1, int p = -1) { data = d; parent = p; }; bool operator==(int val) { return (data == val); } public: int data; int parent;//存在父子关系的就在同一个连通分支,parent是自己的结点,他就是该集合的代表; }; class UnionSet { public: UnionSet()//初始化集合 { cin >> n; s.push_back(PNode(0, 0)); for (int i = 1; i <= n; i++) { int in1; int in2; cin >> in1 >> in2; s.push_back(PNode(in1, in2)); } }; UnionSet(vector 
                  
                    s, int n) { this->s = s; this->n = n; }; void Union(int s1, int s2) { //合并成员s1, s2所在的两个连通分支 /*vector 
                   
                     ::iterator iter1, iter2; iter1 = Find(s1); iter2 = Find(s2); if(iter1->data != iter2->data) { iter2->parent = iter1->data; }*/ //合并代表s1 , s2所在的连通分支 vector 
                    
                      ::iterator iter1, iter2; iter1 = find(s.begin() + 1, s.end(), s1); iter2 = find(s.begin() + 1, s.end(), s2); iter2->parent = iter1->data; }; vector 
                     
                       ::iterator Find(int m)//查找成员m所在集合的代表,返回它的位置 { vector 
                      
                        ::iterator iter , p , q , r; iter = find(s.begin() + 1, s.end(), m); //路径压缩 p = iter; while (p->parent != p->data) { p = find(s.begin() + 1, s.end(), p->parent);//返回代表的位置 } r = iter;//指向当前 q = find(s.begin() + 1, s.end(), r->parent);//指向上级 while (q != p) { r->parent = p->parent; r = q;//上位 q = find(s.begin() + 1, s.end(), q->parent);//上位 } return p;//返回树根,即代表 } public : vector 
                       
                         s; int n; }; 
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
     

7、  Prim算法:

贪心法

code>>感觉写复杂了。。。。。。 #include 
     
       #include 
      
        #include 
       
         using namespace std; class EdgeNode { public : EdgeNode(int i = 0 , int j = 0 , int w = 10000) { this->i = i; this->j = j; this->weight = w; } friend bool operator==(EdgeNode E1 , EdgeNode E2) { return ((E1.i == E2.i && E1.j == E2.j) || (E1.i == E2.j && E1.j == E2.i)); } public : int i, j; int weight; }; class Graph { public : Graph() { cin >> vn >> en; edges.push_back(EdgeNode()); for (int i = 1; i <= en; i++) { int in1, in2, in3; cin >> in1 >> in2 >> in3; edges.push_back(EdgeNode(in1, in2, in3)); } minspt.push_back(EdgeNode()); } EdgeNode Find(int i, int j) { EdgeNode e = EdgeNode(i, j, 0); vector 
        
          ::iterator iter; iter = find(edges.begin() + 1, edges.end(), e); if (iter != edges.end()) { return EdgeNode(i, j, iter->weight); } else { return EdgeNode(i, j, 10000); } } public : int vn, en; vector 
         
           edges; vector 
          
            minspt; }; Graph G; vector 
           
             closest;//closest[i] : 从V-S中的顶点i到S中最近的j顶点的相应的边 vector 
            
              s;//已选择的顶点标记为true; bool comp(EdgeNode E1 ,EdgeNode E2 )//E1 类似扫描器p, E2类似min { if (!s[E1.i]) { return (E1.weight < E2.weight); } else { return false; } } void prim() { EdgeNode e1, e2; vector 
             
               ::iterator iter; closest.push_back(EdgeNode()); //初始化closest , s; for (int i = 0; i <= G.vn; i++) { s.push_back(false); } s[0] = s[1] = true; for (int i = 1; i <= G.vn; i++)//到1的最近边 { if (!s[i]) { e1 = G.Find(i, 1); closest.push_back(EdgeNode(i, 1, e1.weight)); } else { closest.push_back(EdgeNode()); } } for (int j = 1; j < G.vn; j++) { int k = 0; iter = min_element(closest.begin() + 1, closest.end(), comp); k = iter->i; if (k) { s[k] = true;//顶点k加入S中 G.minspt.push_back(*iter); //修改closet for (int i = 1; i <= G.vn; i++) { if (!s[i]) { e1 = G.Find(i, closest[i].j); e2 = G.Find(i, k); if (e1.weight > e2.weight)//i到S中的新加的顶点k更近,更新closest { closest[i] = e2; } } } } } } int main() { prim(); cout << "minimum_spanning_Tree : " << endl; for (int i = 1; i <= G.minspt.size()-1; i++) { cout << "( " << G.minspt[i].j << " , " << G.minspt[i].i << " , " << G.minspt[i].weight << " )" << endl; } return 0; } 
              
             
            
           
          
         
        
       
     



















版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/204222.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午8:43
下一篇 2026年3月19日 下午8:43


相关推荐

  • ios safari 模拟器_web测试-ios设备模拟器(iOS Simulator)

    ios safari 模拟器_web测试-ios设备模拟器(iOS Simulator)前言虽然 ChromeDevToo 可以模拟手机的环境 但与真实环境差别比较大 所以一般会用真机调试 或者就是用模拟器了 这篇文章主要就是介绍下在 mac 上如何使用模拟器来调试页面 安装 iossimulator 捆绑于 xcode 直接上 appStore 搜索 Xcode 进行安装如何使用 1 打开 xcode 需要新建一个项目 通过 Xcode OpenDevelope Simulato

    2026年3月18日
    2
  • 理解 sudo 和 sudoers[通俗易懂]

    理解 sudo 和 sudoers[通俗易懂]在Linux上,只有root用户可以执行任何命令,其他用户必须使用sudo才可执行特殊的命令.sudo是通过sudoers进行配置的.默认配置/etc/sudoers:##ThisfileMUSTbeeditedwiththe’visudo’commandasroot.##Pleaseconsideraddinglocalcontentin/etc/sudoers.d/insteadof#directlymodifying

    2022年6月20日
    33
  • 使用InetAddress

    使用InetAddress17.2Java的基本网络支持  Java为网络支持提供了java.net包,该包下的URL和URLConnection等类提供了以编程方式访问Web服务的功能,而URLDecoder和URLEncoder则提供普通字符串和application/x-www-form-urlencodedMIME字符串相互转换的静态方法。  17.2.1使用InetAddress

    2022年6月23日
    24
  • Java基础篇:final关键字

    Java基础篇:final关键字

    2021年10月4日
    51
  • laravel 安装完成后安装 vendor 目录

    laravel 安装完成后安装 vendor 目录

    2021年10月20日
    58
  • clientHeight、scrollHeight、offsetHeight和scrollTop之间区别[通俗易懂]

    clientHeight、scrollHeight、offsetHeight和scrollTop之间区别[通俗易懂]屏幕可见区域高(内容的可视高度,不包括边框,边距或滚动条):document.body.clientHeight正文内容高(整个元素的高度,包括带滚动条的隐蔽的地方):document.body.scrollHeight内容高+padding+边框:document.body.offsetHeight滚动条已经滚动的高度:document.body.scrollTop屏幕分辨率高:

    2022年7月23日
    13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号