lru调度算法例题_嵌入式必会!C语言最常用的贪心算法就这么被攻略了

01

基本概念

贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性(即某个状态以后的过程不会影响以前的状态,只与当前状态有关。)

所以,对所采用的贪心策略一定要仔细分析其是否满足无后效性。

02

贪心算法的基本思路

解题的一般步骤是:

1.建立数学模型来描述问题;
2.把求解的问题分成若干个子问题;
3.对每一子问题求解,得到子问题的局部最优解;
4.把子问题的局部最优解合成原来问题的一个解。

03

该算法存在的问题

  • 不能保证求得的最后解是最佳的

  • 不能用来求最大值或最小值的问题

  • 只能求满足某些约束条件的可行解的范围

04

贪心算法适用的问题


贪心策略适用的前提是:局部最优策略能导致产生全局最优解。


实际上,贪心算法适用的情况很少。一般对一个问题分析是否适用于贪心算法,可以先选择该问题下的几个实际数据进行分析,就可以做出判断。

05

贪心选择性质

所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。


当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。

06

贪心算法的实现框架


从问题的某一初始解出发:

while (朝给定总目标前进一步){利用可行的决策,求出可行解的一个解元素。}


由所有解元素组合成问题的一个可行解;

07

例题分析

如果大家比较了解动态规划,就会发现它们之间的相似之处。最优解问题大部分都可以拆分成一个个的子问题,把解空间的遍历视作对子问题树的遍历,则以某种形式对树整个的遍历一遍就可以求出最优解,大部分情况下这是不可行的。贪心算法和动态规划本质上是对子问题树的一种修剪,两种算法要求问题都具有的一个性质就是子问题最优性(组成最优解的每一个子问题的解,对于这个子问题本身肯定也是最优的)。动态规划方法代表了这一类问题的一般解法,我们自底向上构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,并且以其中的最优值作为自身的值,其它的值舍弃。而贪心算法是动态规划方法的一个特例,可以证明每一个子树的根的值不取决于下面叶子的值,而只取决于当前问题的状况。换句话说,不需要知道一个节点所有子树的情况,就可以求出这个节点的值。由于贪心算法的这个特性,它对解空间树的遍历不需要自底向上,而只需要自根开始,选择最优的路,一直走到底就可以了。
话不多说,我们来看几个具体的例子慢慢理解它:1.活动选择问题
这是《算法导论》上的例子,也是一个非常经典的问题。有n个需要在同一天使用同一个教室的活动a1,a2,…,an,教室同一时刻只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi 。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai和aj两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。例如下图所示的活动集合S,其中各项活动按照结束时间单调递增排序。953d7cb95d55587b28581703fde7dff9.png
考虑使用贪心算法的解法。为了方便,我们用不同颜色的线条代表每个活动,线条的长度就是活动所占据的时间段,蓝色的线条表示我们已经选择的活动;红色的线条表示我们没有选择的活动。
如果我们每次都选择开始时间最早的活动,不能得到最优解:94c6d3149de34cab07934bc3e6d319ed.png
如果我们每次都选择持续时间最短的活动,不能得到最优解:26bf886c3291684ab00598578ae5410c.png
可以用数学归纳法证明,我们的贪心策略应该是每次选取结束时间最早的活动。直观上也很好理解,按这种方法选择相容活动为未安排活动留下尽可能多的时间。这也是把各项活动按照结束时间单调递增排序的原因。
    #include    #include    #include    using namespace std;        int N;    struct Act    {        int start;        int end;    }act[100010];         bool cmp(Act a,Act b)  {          return a.end    }         int greedy_activity_selector()  {          int num=1,i=1;           for(int j=2;j<=N;j++)          {              if(act[j].start>=act[i].end)              {                  i=j;                  num++;              }          }          return num;    }         int main()  {          int t;        scanf("%d",&t);        while(t--)        {            scanf("%d",&N);            for(int i=1;i<=N;i++)            {                scanf("%lld %lld",&act[i].start,&act[i].end);            }            act[0].start=-1;            act[0].end=-1;             sort(act+1,act+N+1,cmp);            int res=greedy_activity_selector();            cout<endl;          }    }  
2.钱币找零问题
这个问题在我们的日常生活中就更加普遍了。假设1元、2元、5元、10元、20元、50元、100元的纸币分别有c0, c1, c2, c3, c4, c5, c6张。现在要用这些钱来支付K元,至少要用多少张纸币?用贪心算法的思想,很显然,每一步尽可能用面值大的纸币即可。在日常生活中我们自然而然也是这么做的。在程序中已经事先将Value按照从小到大的顺序排好。
    #include    #include    using namespace std;    const int N=7;    int Count[N]={3,0,2,1,0,3,5};    int Value[N]={1,2,5,10,20,50,100};          int solve(int money){        int num=0;        for(int i=N-1;i>=0;i--)        {            int c=min(money/Value[i],Count[i]);            money=money-c*Value[i];            num+=c;        }        if(money>0) num=-1;        return num;    }         int main(){        int money;        cin>>money;        int res=solve(money);        if(res!=-1) cout<endl;        else cout<<"NO"<<endl;    }

3.再论背包问题

在从零开始学动态规划中我们已经谈过三种最基本的背包问题:零一背包,部分背包,完全背包。很容易证明,背包问题不能使用贪心算法。然而我们考虑这样一种背包问题:在选择物品i装入背包时,可以选择物品的一部分,而不一定要全部装入背包。这时便可以使用贪心算法求解了。计算每种物品的单位重量价值作为贪心选择的依据指标,选择单位重量价值最高的物品,将尽可能多的该物品装入背包,依此策略一直地进行下去,直到背包装满为止。在零一背包问题中贪心选择之所以不能得到最优解原因是贪心选择无法保证最终能将背包装满,部分闲置的背包空间使每公斤背包空间的价值降低了。在程序中已经事先将单位重量价值按照从大到小的顺序排好。
    #include       using namespace std;       const int N=4;      void knapsack(float M,float v[],float w[],float x[]);            int main()  {          float M=50;        //背包所能容纳的重量           float w[]={0,10,30,20,5};        //每种物品的重量          float v[]={0,200,400,100,10};            //每种物品的价值        float x[N+1]={0};          //记录结果的数组        knapsack(M,v,w,x);          cout<<"选择装下的物品比例:"<<endl;          for(int i=1;i<=N;i++) cout<<"["<"]:"<    }            void knapsack(float M,float v[],float w[],float x[])  {          int i;          //物品整件被装下          for(i=1;i<=N;i++)        {              if(w[i]>M) break;               x[i]=1;              M-=w[i];          }           //物品部分被装下          if(i<=N) x[i]=M/w[i];       }

4.多机调度问题

n个作业组成的作业集,可由m台相同机器加工处理。要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。作业不能拆分成更小的子作业;每个作业均可在任何一台机器上加工处理。这个问题是NP完全问题,还没有有效的解法(求最优解),但是可以用贪心选择策略设计出较好的近似算法(求次优解)。当n<=m时,只要将作业时间区间分配给作业即可;当n>m时,首先将n个作业从大到小排序,然后依此顺序将作业分配给空闲的处理机。也就是说从剩下的作业中,选择需要处理时间最长的,然后依次选择处理时间次长的,直到所有的作业全部处理完毕,或者机器不能再处理其他作业为止。如果我们每次是将需要处理时间最短的作业分配给空闲的机器,那么可能就会出现其它所有作业都处理完了只剩所需时间最长的作业在处理的情况,这样势必效率较低。在下面的代码中没有讨论n和m的大小关系,把这两种情况合二为一了。
    #include    #include    using namespace std;      int speed[10010];      int mintime[110];           bool cmp( const int &x,const int &y)  {          return x>y;      }           int main()  {          int n,m;                 memset(speed,0,sizeof(speed));           memset(mintime,0,sizeof(mintime));            cin>>n>>m;             for(int i=0;icin>>speed[i];          sort(speed,speed+n,cmp);          for(int i=0;i        {            *min_element(mintime,mintime+m)+=speed[i];              }           cout<endl;    }

5.小船过河问题

POJ1700是一道经典的贪心算法例题。题目大意是只有一艘船,能乘2人,船的运行速度为2人中较慢一人的速度,过去后还需一个人把船划回来,问把n个人运到对岸,最少需要多久。先将所有人过河所需的时间按照升序排序,我们考虑把单独过河所需要时间最多的两个旅行者送到对岸去,有两种方式:
1.最快的和次快的过河,然后最快的将船划回来;次慢的和最慢的过河,然后次快的将船划回来,所需时间为:t[0]+2*t[1]+t[n-1];
2.最快的和最慢的过河,然后最快的将船划回来,最快的和次慢的过河,然后最快的将船划回来,所需时间为:2*t[0]+t[n-2]+t[n-1]。
算一下就知道,除此之外的其它情况用的时间一定更多。每次都运送耗时最长的两人而不影响其它人,问题具有贪心子结构的性质。
AC代码:
    #include    #include    using namespace std;         int main(){        int a[1000],t,n,sum;        scanf("%d",&t);        while(t--)        {            scanf("%d",&n);            sum=0;            for(int i=0;iscanf(            while(n>3)            {                sum=min(sum+a[1]+a[0]+a[n-1]+a[1],sum+a[n-1]+a[0]+a[n-2]+a[0]);                n-=2;            }            if(n==3) sum+=a[0]+a[1]+a[2];            else if(n==2) sum+=a[1];            else sum+=a[0];            printf("%d\n",sum);        }    }

6.区间覆盖问题

POJ1328是一道经典的贪心算法例题。题目大意是假设海岸线是一条无限延伸的直线。陆地在海岸线的一侧,而海洋在另一侧。每一个小的岛屿是海洋上的一个点。雷达坐落于海岸线上,只能覆盖d距离,所以如果小岛能够被覆盖到的话,它们之间的距离最多为d。题目要求计算出能够覆盖给出的所有岛屿的最少雷达数目。对于每个小岛,我们可以计算出一个雷达所在位置的区间。aae033e288701f546a5019f56d2353df.png
问题转化为如何用尽可能少的点覆盖这些区间。先将所有区间按照左端点大小排序,初始时需要一个点。如果两个区间相交而不重合,我们什么都不需要做;如果一个区间完全包含于另外一个区间,我们需要更新区间的右端点;如果两个区间不相交,我们需要增加点并更新右端点。
AC代码:
    #include    #include    #include    using namespace std;    struct Point    {        double x;        double y;    }point[1000];         int cmp(const void *a, const void *b){        return (*(Point *)a).x>(*(Point *)b).x?1:-1;    }         int main(){        int n,d;        int num=1;        while(cin>>n>>d)        {            int counting=1;            if(n==0&&d==0) break;            for(int i=0;i            {                int x,y;                cin>>x>>y;                if(y>d)                {                    counting=-1;                }                double t=sqrt(d*d-y*y);                //转化为最少区间的问题                point[i].x=x-t;                //区间左端点                point[i].y=x+t;                //区间右端点            }            if(counting!=-1)            {                qsort(point,n,sizeof(point[0]),cmp);                //按区间左端点排序                double s=point[0].y;                //区间右端点                for(int i=1;i                {                    if(point[i].x>s)                    //如果两个区间没有重合,增加雷达数目并更新右端点                    {                        counting++;                        s=point[i].y;                    }                    else if(point[i].y                    //如果第二个区间被完全包含于第一个区间,更新右端点                    {                        s=point[i].y;                    }                }            }            cout<<"Case "<':'<<            num++;        }    }

7.销售比赛

在学校OJ上做的一道比较好的题,这里码一下。假设有偶数天,要求每天必须买一件物品或者卖一件物品,只能选择一种操作并且不能不选,开始手上没有这种物品。现在给你每天的物品价格表,要求计算最大收益。首先要明白,第一天必须买,最后一天必须卖,并且最后手上没有物品。那么除了第一天和最后一天之外我们每次取两天,小的买大的卖,并且把卖的价格放进一个最小堆。如果买的价格比堆顶还大,就交换。这样我们保证了卖的价格总是大于买的价格,一定能取得最大收益。
    #include    #include    #include    #include    #include    #include    #include    using namespace std;    long long int price[100010],t,n,res;               int main(){        ios::sync_with_stdio(false);        cin>>t;        while(t--)        {            cin>>n;            priority_queue<long long int, vector<long long int>, greater<long long int> > q;            res=0;            for(int i=1;i<=n;i++)            {                cin>>price[i];            }            res-=price[1];            res+=price[n];            for(int i=2;i<=n-1;i=i+2)            {                long long int buy=min(price[i],price[i+1]);                long long int sell=max(price[i],price[i+1]);                if(!q.empty())                {                    if(buy>q.top())                    {                        res=res-2*q.top()+buy+sell;                        q.pop();                        q.push(buy);                        q.push(sell);                    }                    else                    {                        res=res-buy+sell;                        q.push(sell);                    }                }                else                {                    res=res-buy+sell;                    q.push(sell);                }            }                 cout<endl;        }    }

下面我们结合数据结构中的知识讲解几个例子。8.Huffman编码
这同样是《算法导论》上的例子。Huffman编码是广泛用于数据文件压缩的十分有效的编码方法。我们可以有多种方式表示文件中的信息,如果用01串表示字符,采用定长编码表示,则需要3位表示一个字符,整个文件编码需要300000位;采用变长编码表示,给频率高的字符较短的编码,频率低的字符较长的编码,达到整体编码减少的目的,则整个文件编码需要(45×1+13×3+12×3+16×3+9×4+5×4)×1000=224000位,由此可见,变长码比定长码方案好,总码长减小约25%。

a29b951242f1eb638f283ded58c25aca.png


对每一个字符规定一个01串作为其代码,并要求任一字符的代码都不是其他字符代码的前缀,这种编码称为前缀码。可能无前缀码是一个更好的名字,但是前缀码是一致认可的标准术语。编码的前缀性质可以使译码非常简单:例如001011101可以唯一的分解为0,0,101,1101,因而其译码为aabe。译码过程需要方便的取出编码的前缀,为此可以用二叉树作为前缀码的数据结构:树叶表示给定字符;从树根到树叶的路径当作该字符的前缀码;代码中每一位的0或1分别作为指示某节点到左儿子或右儿子的路标。

4061c7cb8c686140d1c8d3a086a7764d.png


从上图可以看出,最优前缀编码码的二叉树总是一棵完全二叉树,而定长编码的二叉树不是一棵完全二叉树。给定编码字符集C及频率分布f,C的一个前缀码编码方案对应于一棵二叉树T。字符c在树T中的深度记为dT(c),dT(c)也是字符c的前缀码长。则平均码长定义为:

83edbdebe16228279db442e60b54805b.png


使平均码长达到最小的前缀码编码方案称为C的最优前缀码。     
Huffman编码的构造方法:先合并最小频率的2个字符对应的子树,计算合并后的子树的频率;重新排序各个子树;对上述排序后的子树序列进行合并;重复上述过程,将全部结点合并成1棵完整的二叉树;对二叉树中的边赋予0、1,得到各字符的变长编码。

4e996057e1276e3f07cd7265c2e4f0b9.png


POJ3253一道就是利用这一思想的典型例题。题目大意是有把一块无限长的木板锯成几块给定长度的小木板,每次锯都需要一定费用,费用就是当前锯的木板的长度。给定各个要求的小木板的长度以及小木板的个数,求最小的费用。以要求3块长度分别为5,8,5的木板为例:先从无限长的木板上锯下长度为21的木板,花费21;再从长度为21的木板上锯下长度为5的木板,花费5;再从长度为16的木板上锯下长度为8的木板,花费8;总花费=21+5+8=34。利用Huffman思想,要使总费用最小,那么每次只选取最小长度的两块木板相加,再把这些和累加到总费用中即可。为了提高效率,使用优先队列优化,并且还要注意使用long long int保存结果。
AC代码:
    #include    #include    #include    using namespace std;         int main(){        long long int sum;        int i,n,t,a,b;        while(~scanf("%d",&n))        {            priority_queue<int,vector<int>,greater<int> >q;            for(i=0;i            {                scanf("%d",&t);                q.push(t);            }            sum=0;            if(q.size()==1)            {                a=q.top();                sum+=a;                q.pop();            }            while(q.size()>1)            {                a=q.top();                q.pop();                b=q.top();                q.pop();                t=a+b;                sum+=t;                q.push(t);            }            printf("%lld\n",sum);        }    }

9.Dijkstra算法

Dijkstra算法是由E.W.Dijkstra于1959年提出,是目前公认的最好的求解最短路径的方法,使用的条件是图中不能存在负边。算法解决的是单个源点到其他顶点的最短路径问题,其主要特点是每次迭代时选择的下一个顶点是标记点之外距离源点最近的顶点,简单的说就是bfs+贪心算法的思想。
    #include    #include    #define INF 1000    #define MAX_V 100    using namespace std;           int main(){        int V,E;        int i,j,m,n;        int cost[MAX_V][MAX_V];        int d[MAX_V];        bool used[MAX_V];        cin>>V>>E;        fill(d,d+V+1,INF);        fill(used,used+V,false);        for(i=0;i        {            for(j=0;j            {                if(i==j) cost[i][j]=0;                else cost[i][j]=INF;            }        }        for(m=0;m        {            cin>>i>>j>>cost[i][j];            cost[j][i]=cost[i][j];        }        cin>>n;        d[n]=0;        //源点        while(true)        {            int v=V;            for(m=0;m            {                    if((!used[m])&&(d[m]            }                if(v==V) break;            used[v]=true;            for(m=0;m            {                d[m]=min(d[m],d[v]+cost[v][m]);            }        }        for(i=0;i        {            cout<<"the shortest distance between "<" and "<        }    }

10.最小生成树算法

设一个网络表示为无向连通带权图G =(V, E) , E中每条边(v,w)的权为c[v][w]。如果G的子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。生成树的代价是指生成树上各边权的总和,在G的所有生成树中,耗费最小的生成树称为G的最小生成树。例如在设计通信网络时,用图的顶点表示城市,用边(v,w)的权c[v][w]表示建立城市v和城市w之间的通信线路所需的费用,最小生成树给出建立通信网络的最经济方案。

4922cb31fab767b4563281944e5c61bd.png


构造最小生成树的Kruskal算法和Prim算法都利用了MST(最小生成树)性质:设顶点集U是V的真子集(可以任意选取),如果(u,v)∈E为横跨点集U和V—U的边,即u∈U,v∈V- U,并且在所有这样的边中,(u,v)的权c[u][v]最小,则一定存在G的一棵最小生成树,它以(u,v)为其中一条边。04b007f8793a47eb8fd0a07a0cb7d4d1.pnge2a9cf1b2068054fe9df7ade6bebaa2b.png
使用反证法可以很简单的证明此性质。假设对G的任意一个最小生成树T,针对点集U和V—U,(u,v)∈E为横跨这2个点集的最小权边,T不包含该最小权边,但T包括节点u和v。将添加到树T中,树T将变为含回路的子图,并且该回路上有一条不同于的边,u’∈U,v’∈V-U。将删去,得到另一个树T’,即树T’是通过将T中的边替换为得到的。由于这2条边的耗费满足c[u][v]≤c[u’][v’],故即T’耗费≤T的耗费,这与T是任意最小生成树的假设相矛盾,从而得证。12b19b30100b98d35efe114e7e5ff5f7.png
Prim算法每一步都选择连接U和V-U的权值最小的边加入生成树。ca9003a790fd87a931718f8ba8fecd34.png
    #include    #include    #define MAX_V 100    #define INF 1000    using namespace std;           int main(){        int V,E;        int i,j,m,n;        int cost[MAX_V][MAX_V];        int mincost[MAX_V];        bool used[MAX_V];        cin>>V>>E;        fill(mincost,mincost+V+1,INF);        fill(used,used+V,false);        for(i=0;i        {            for(j=0;j            {                if(i==j) cost[i][j]=0;                else cost[i][j]=INF;            }        }        for(m=0;m        {            cin>>i>>j>>cost[i][j];            cost[j][i]=cost[i][j];        }        mincost[0]=0;        int res=0;        while(true)        {            int v=V;            for(m=0;m            {                    if((!used[m])&&(mincost[m]                    v=m;            }                if(v==V) break;            used[v]=true;            res+=mincost[v];            for(m=0;m            {                mincost[m]=min(mincost[m],cost[v][m]);            }        }        cout<endl;    }

Kruskal算法每一步直接将权值最小的不成环的边加入生成树,我们借助并查集这一数据结构可以完美实现它。6e1c42e1b1e7eff60cd2f8efd766e407.png
    #include    #include    #define MAX_E 100    using namespace std;      struct edge    {        int u,v,cost;        };    int pre[MAX_E];    edge es[MAX_E];    int find(int x);    void initvalue(int x);    bool same(int x,int y);    void unite(int x,int y);    bool comp(const edge& e1,const edge& e2);         int main(){        int V,E;        int i,j,m,n;        cin>>V>>E;        initvalue(V);        for(i=0;icin>>es[i].u>>es[i].v>>es[i].cost;                sort(es,es+E,comp);        int res=0;        for(i=0;i        {            edge e=es[i];            if(!same(e.u,e.v))            {                unite(e.u,e.v);                res+=e.cost;            }        }        cout<endl;        }         bool comp(const edge& e1,const edge& e2){        return e1.cost    }         void initvalue(int x){        for(int i=0;i    }         int find(int x){        int r=x;        while(pre[r]!=r) r=pre[r];        int i=x,j;        while(pre[i]!=r)        {            j=pre[i];            pre[i]=r;            i=j;        }        return r;    }         bool same(int x,int y){        if(find(x)==find(y)) return true;        else return false;        }         void unite(int x,int y){        int fx=find(x);        int fy=find(y);        if(fx!=fy) pre[fx]=fy;        }

关于贪心算法的基础知识就简要介绍到这里,希望能作为大家继续深入学习的基础。

-END-

来源:付斌整理

推荐阅读

【1】安谋中国“星辰”处理器商用:灵动微、全志科技、华大北斗布局合作

【2】Soitec:今明两年,FD-SOI应用或迎来腾飞拐点

【3】终于整理齐了,电子工程师“设计锦囊”,你值得拥有!

【4】半导体行业的人都在关注这几个公众号

6128a2d3698ddf9ff8070b736a21c9d7.gif你和大牛工程师之间到底差了啥?加入技术交流群,与高手面对面 添加管理员微信1fc8a55a528f21bac1b2eb4a246cf589.png加入“中国电子网微信群”交流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/547931.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【虚拟化实战】存储设计之一存储类型

Problem Statement存储设计是虚拟化设计的重要部分之一&#xff0c;确定合适的存储类型是展开存储设计的关键一步。FC/FCoE, iSCSI, NFS 甚至 Local Storage, 你会选择哪一种呢&#xff1f;参见下图。Requirements客户需要移植物理服务器到VMware虚拟化平台&#xff0c;很多物…

ztree 指定节点清空_节点操作

一.节点操作​ 1.DOM节点操作​ ①创建节点​ 语法&#xff1a;document.createElement("标签名")&#xff1b;​ 注&#xff1a;只单纯的创建出来了一个元素节点对象&#xff0c;不包含内容、属性和样式。​ ②插入节点​ 在父元素内部末尾追加​ 语法&#xff1a;父…

GC 基础

如何定位垃圾 1. 引用计数法 为对象添加一个引用计数器&#xff0c;当对象增加一个引用时计数器加 1&#xff0c;引用失效时计数器减 1。引用计数为 0 的对象可被回收。 在两个对象出现循环引用的情况下&#xff0c;此时引用计数器永远不为 0&#xff0c;导致无法对它们进行…

离线部署 CDH 6.2 及使用 CDH 部署 Hadoop3 大数据平台集群服务

Cloudera Manager Cloudera Manager 分为两个部分&#xff1a;CDH和CM。 CDH是Cloudera Distribution Hadoop的简称&#xff0c;顾名思义&#xff0c;就是cloudera公司发布的Hadoop版本&#xff0c;封装了Apache Hadoop&#xff0c;提供Hadoop所有的服务&#xff0c;包括HDFS…

玛酷机器人课程视频_建阳玛酷机器人丨2019WRO机器人比赛凯旋而归!

2019年7月福州WRO青少年机器人交流RA 7月27-28日&#xff0c;经过角逐&#xff0c; WRO华南赛区(福州站)在福州中加学校顺利落幕。 本次大赛设置了山火营救、无人速递、城市救援、RA常规赛、足球世界杯、WEDO常规项目、WEDO小手拼出大世界等七个单项比赛。 …

kindeditor图片批量上传失败问题

2019独角兽企业重金招聘Python工程师标准>>> 问题&#xff1a;在演示版中批量上传没有问题&#xff0c;放到我们后台系统中&#xff0c;就上传不成功。 排查&#xff1a;逐步验证发现根本没有http到upload上传文件中&#xff0c;往上找。。。终于碰到是后台管理员验…

presto集群安装

presto集群安装 整合hive 张映 发表于 2019-11-07 分类目录&#xff1a; hadoop/spark/scala 标签&#xff1a;hive, presto Presto是一个运行在多台服务器上的分布式系统。 完整安装包括一个coordinator&#xff08;调度节点&#xff09;和多个worker。 由客户端提交查询&…

wps 复制流程图_简单三步,用WPS轻松完成一个又大气又好看的流程图!

流程图是工作中经常需要用到的图形&#xff0c;使用 WPS 可以方便地创建流程图。创建的流程图保存在云文档后&#xff0c;可以随时插入 WPS 的其他组件。新建流程图文件流程图可以从 WPS 的其他组件中创建&#xff0c;如 WPS 文字、WPS 表格等&#xff0c;也可以单独创建。流程…

Tez 0.9安装部署+hive on tez配置 + Tez-UI

Tez说明 将xyz替换为您正在使用的tez发行版号。例如0.5.0。对于Tez版本0.8.3和更高版本&#xff0c;Tez需要Apache Hadoop版本为2.6.0或更高版本。对于Tez版本0.9.0及更高版本&#xff0c;Tez需要Apache Hadoop版本为2.7.0或更高版本。 关于版本 1.Hadoop 2.7.0&#xff08;我…

启动成功浏览器显示不了_移动端利用chrome浏览器在PC端进行调试方法

由于最近工作中遇到需要在电脑上调试手机端的功能和样式&#xff0c;之前也没有遇到过&#xff0c;所以就各种百度和试验。最后终于功夫不负有心人&#xff0c;成功了。(那一刻心情真滴很鸡冻啊~~~~~~~~~)。所以暂时记录下来。以免鸡冻过度再给忘记了。好&#xff0c;接下来就是…

在maven本地仓库导入jar包

# Dfile jar包所在位置 DgroupId 指定groupId DartifactId 指定artifactId Dversion 指定版本 mvn install:install-file -DfileC:\Users\zlf\Desktop\mybatis-main\target\mybatis.jar -DgroupId"cn.bugstack.middleware" -DartifactIdmybatis -Dversion"1.0.…

Flink完全分布式集群安装

Flink支持完全分布式模式&#xff0c;这时它由一个master节点和多个worker节点构成。在本节&#xff0c;我们将搭建一个如下的三个节点的Flink集群。 一、Flink集群安装、配置和运行 Flink完全分布式集群搭建步骤如下&#xff1a; 1、配置从master到worker节点的SSH无密登录&…

一个4体低位交叉的存储器_前交叉韧带术后关节粘连的康复策略

ACL术后粘连的康复现状在国外&#xff0c;前交叉韧带ACL重建术后关节粘连的发生率为1%。在国内&#xff0c;由于多数医院在行前交叉韧带重建术后&#xff0c;对患者缺少及时、系统、科学的康复治疗&#xff0c;大部分患者由此易发生关节粘连&#xff0c;而往往关节粘连造成的功…

Maven多模块打包

在类似如下的场景中进行打包 lottery-rpc 将出现报错&#xff0c;原因是没办法将 lottery-common 一起打包进去。 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://…

hadoop 2.6.5 + hive 集群搭建

Hadoop 搭建&#xff1a;https://blog.csdn.net/sinat_28371057/article/details/109135056 hive 搭建 1. 系统环境 centos 7.3 Hadoop 2.7.3 jdk 1.8 MySQL安装在master机器上&#xff0c;hive服务器也安装在master上 hive版本: https://mirrors.cnnic.cn/apache/hive/hive…

光耦和开关频率

为什么80%的码农都做不了架构师&#xff1f;>>> TLP250&#xff0c;HCPL3120都可以 直接驱动小型IGBT&#xff0c;不需要加推挽管 6N137&#xff0c;没有推挽&#xff0c;OC上拉&#xff0c;到最后可能驱动速度还上不去 我们6N137&#xff0c;是用来驱动IPM的 电压…

配置babel_Babel 7 下配置 TypeScript 支持

本文将展示&#xff0c;如何使用 babel/preset-typescript 和 babel/preset-env 配置一个最小但完整的编译环境&#xff0c;打包工具使用 webpack4.41.2插件集 preset-typescriptpreset-typescript 是 Babel 提供的预设插件集之一&#xff0c;Babel 官方对其有一篇简短的介绍&a…

jQuery 计时器(jquery timers)简单应用

jquery timers 代码&#xff08;版本1.2&#xff09;&#xff1a; jquery timers /** * jQuery.timers - Timer abstractions for jQuery * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com) * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/). …

服务器改用ssh文件登录

首先在服务器生成密钥 ssh-keygen -t rsa -b 4096 将 id_rsa.pub的内容导入到 authorized_keys文件中&#xff0c;这样远程登录时用id_rsa文件登录会与authorized_keys中的文件进行验证。 cat id_rsa.pub >> authorized_keys 关闭ssh密码登录 在 /etc/ssh 下的sshd_conf…

Spark集群完全分布式安装部署

Spark集群完全分布式安装部署下载安装配置Spark 1spark-envsh配置2slaves配置3profile配置复制到其他节点测试总结 Spark集群完全分布式安装部署 本文中所提到的Spark集群所用的系统环境是Centos6.5&#xff0c;共4个节点&#xff0c;前提是Hadoop、JDK都已经安装配置好了&…