C++队列和优先权队列的使用---应用:带时限作业排序

原创 2016年06月02日 09:18:55

C++队列和优先权队列的使用—应用:带时限作业排序


C++队列的使用

首先包含头文件

include

队列可以用线性表(list)或双向队列(deque)来实现(注意vector container 不能用来实现queue,因为vector 没有成员函数pop_front!):
queue<list<int>> q1;
queue<deque<int>> q2;
其成员函数有“判空(empty)” 、“尺寸(Size)” 、“首元(front)” 、“尾元(backt)” 、“加入队列(push)” 、“弹出队列(pop)”等操作。

1.back() 返回一个引用,指向最后一个元素
2.empty() 如果队列空则返回真
3.front() 返回第一个元素
4.pop() 删除第一个元素
5.push() 在末尾加入一个元素
6.size() 返回队列中元素的个数

例如,队列在带时限作业排序中的应用

#include<iostream>
`#include<queue>`
using namespace std;
struct Node         //状态空间树结点结构
{
    Node(Node *par, int k, int num)
    {
        parent = par; j = k; NodeNum = num;
    }
    Node *parent;    //指向该结点的双亲结点
    int j;           //该结点代表的解分量x[i]=j
    int NodeNum;     //该结点的编号,增加的变量,可以不要
};

template<class T>
struct qNode       //活结点表中的活结点结构
{
    qNode(){}
    qNode(T p, T los, int sd, int k, Node *pt)
    {
        prof = p; loss = los; d = sd; ptr = pt; j = k;
    }
    T prof, loss;   //当前结点X的下界函数c(X)=loss,上界函数u(X)=24-prof
    int j, d;        //当前活结点所代表的分量x[j]=j, d是迄今为止的时间
    Node *ptr;      //指向状态空间树中相应的结点
};

template<class T>
class JS
{
public:
    JS(T *prof, int *de, int *time, int size);
    T JSFIFOBB();                              //构造状态空间树,求最优解值
    void GenerateAns(int *x, int &k);          //一维数组x为最优解向量,k中返回x的分量解
private:
    T *p, total;                                //p为收益数组,total初始为n个作业收益之和
    int *t, *d, n;                             //t为作业处理时间数组,d为按非减次序排列的作业时间数组
    Node *ans, *root;                           //root指向状态空间树的根,ans指向最优解答案结点
};

template<class T>
JS<T>::JS(T *prof, int *de, int *time, int size)
{
    n = size;
    p = new T[n];  d = new int[n];   t = new int[n];
    total = 0;
    for (int i = 0; i<n; i++)
    {
        p[i] = prof[i];   total += p[i];
        d[i] = de[i];     t[i] = time[i];
    }
}

`#define mSize 20`

template<class T>
T JS<T>::JSFIFOBB()
{
    Node *E, *child;

    queue< qNode<T> > q; //生成一个FIFO队列实例q

    int num = 1;                     //结点编号num
    E = root = new Node(NULL, -1, num);  //构造状态空间树的根结点root
    cout << " root->NodeNum=" << root->NodeNum << "  root->parent=" << root->j << endl;
    qNode<T> ep(0, 0, 0, -1, root);    //ep为扩展结点
    qNode<T> ec;                   //ec为活结点(入队的结点)
    T U = total;                     //上界变量U赋初值,total为作业收益和
    while (1)
    {
        T loss = ep.loss, prof = ep.prof;  E = ep.ptr;  //loss为已造成的损失,prof为已获收益
        for (int j = ep.j + 1; j<n; j++)     //考察所有孩子
        {
            num++;
            if (ep.d + t[j] <= d[j] && loss<U)
            {
                child = new Node(E, j, num); //构造E的孩子结点
                cout << " child->NodeNum=" << child->NodeNum << "  child->parent=" << E->NodeNum << endl;
                ec.prof = prof + p[j];     ec.d = ep.d + t[j];
                ec.ptr = child;          ec.loss = loss;        ec.j = j;
                q.push(ec);            //活结点进队列
                /*
                cout<<"ec.prof="<<ec.prof;
                cout<<"  ec.d="<<ec.d;
                cout<<"  ec.loss="<<ec.loss;
                cout<<"  ec.j="<<ec.j;
                cout<<endl;
                */
                T cost = total - ec.prof;    //计算上界函数值
                if (cost<U)
                {
                    U = cost;  ans = child;   //修改上界变量U,置child为当前的答案结点,
                }                        //当函数返回时,ans指向答案结点
            }
            loss = loss + p[j];
        }
        //cout<<endl;
        do
        {
            if (q.empty())
                return total = U;           //若队列为空,则返回最小损失值,隐含着返回ans结点
            ep=q.front();                 //选择下一个扩展结点
            q.pop();
        } while (ep.loss >= U);
    }
}

template<class T>
void JS<T>::GenerateAns(int *x, int &k)
{
    Node *ans1 = ans;
    k = 0;
    while (ans1->j>0)
    {
        k++;
        ans1 = ans1->parent;
    }
    ans1 = ans;
    for (int i = k - 1; i >= 0; i--)
    {
        x[i] = ans1->j;
        ans1 = ans1->parent;
    }
}

'#define SIZE 5    //4'

void main()
{
    float prof[SIZE] = { 3, 8, 6, 4, 5 };   //{5,3,6,10};
    int de[SIZE] = { 1, 2, 3, 4, 4 };       //{1,1,2,3};
    int time[SIZE] = { 1, 1, 2, 2, 1 };     //{1,1,1,2};
    float total = 0, U;
    int x[10];
    int k;

    JS<float> work(prof, de, time, SIZE);
    U = work.JSFIFOBB();      cout << endl;
    for (int i = 0; i<SIZE; i++) total += prof[i];

    cout << endl;
    cout << "total=" << total << endl;

    cout << endl;
    cout << "U=" << U << endl;

    cout << endl;
    cout << "最优解的值=" << total - U << endl;

    cout << "最优解X[]:";
    work.GenerateAns(x, k);
    for (int i = 0; i<k; i++) cout << " " << x[i];
    cout << endl;

    for (int i = 0; i<k; i++)
        cout << "作业" << x[i] << ":(" << prof[x[i]] << "," << de[x[i]] << "," << time[x[i]] << ")" << endl;
}

C++优先权队列的使用

首先引入头文件

#include<queue>

包含的方法

C++优先队列类似队列,但是在这个数据结构中的元素按照一定的断言排列有序。
1.empty() 如果优先队列为空,则返回真
2.pop() 删除第一个元素
3.push() 加入一个元素
4.size() 返回优先队列中拥有的元素的个数
5.top() 返回优先队列中有最高优先级的元素

实例为带时限的作业排序LCBB算法,例如:

#include<iostream>
#include <queue>
using namespace std;
struct Node         //状态空间树结点结构
{
    Node(Node *par, int k, int num)
    {
        parent = par; j = k; NodeNum = num;
    }
    Node *parent;    //指向该结点的双亲结点
    int j;           //该结点代表的解分量x[i]=j
    int NodeNum;     //该结点的编号,增加的变量,可以不要
};

template<class T>
struct qNode       //活结点表中的活结点结构
{
    operator T()const{ return loss; }
    qNode(){}
    qNode(T p, T los, int sd, int k, Node *pt)
    {
        prof = p; loss = los; d = sd; ptr = pt; j = k;
    }
    T prof, loss;   //当前结点X的下界函数c(X)=loss,上界函数u(X)=24-prof
    int j, d;        //当前活结点所代表的分量x[j]=j, d是迄今为止的时间
    Node *ptr;      //指向状态空间树中相应的结点
};

template<class T>
class JS
{
public:
    JS(T *prof, int *de, int *time, int size);
    T JSLCBB();                                //构造状态空间树,求最优解值
    void GenerateAns(int *x, int &k);          //一维数组x为最优解向量,k中返回x的分量解
private:
    T *p, total;                                //p为收益数组,total初始为n个作业收益之和
    int *t, *d, n;                             //t为作业处理时间数组,d为按非减次序排列的作业时间数组
    Node *ans, *root;                           //root指向状态空间树的根,ans指向最优解答案结点
};

template<class T>
JS<T>::JS(T *prof, int *de, int *time, int size)
{
    n = size;
    p = new T[n];  d = new int[n];   t = new int[n];
    total = 0;
    for (int i = 0; i<n; i++)
    {
        p[i] = prof[i];   total += p[i];
        d[i] = de[i];     t[i] = time[i];
    }
}

#define mSize 20

template<class T>
T JS<T>::JSLCBB()
{
    Node *E, *child;
    priority_queue< qNode<T> > q; //生成一个优先权队列实例q
    int num = 1;                      //结点编号num
    E = root = new Node(NULL, -1, num);   //构造状态空间树的根结点root
    cout << " root->NodeNum=" << root->NodeNum << "  root->parent=" << root->j << endl;
    qNode<T> ep(0, 0, 0, -1, root);     //ep为扩展结点
    qNode<T> ec;                    //ec为活结点(入队的结点)
    T U = total;                      //上界变量U赋初值,total为作业收益和
    while (1)
    {
        T loss = ep.loss, prof = ep.prof;  E = ep.ptr;  //loss为已造成的损失,prof为已获收益
        for (int j = ep.j + 1; j<n; j++)     //考察所有孩子
        {
            num++;
            if (ep.d + t[j] <= d[j] && loss<U)
            {
                child = new Node(E, j, num); //构造E的孩子结点
                cout << " child->NodeNum=" << child->NodeNum << "  child->parent=" << E->NodeNum << endl;
                ec.prof = prof + p[j];     ec.d = ep.d + t[j];
                ec.ptr = child;          ec.loss = loss;        ec.j = j;
                q.push(ec);            //活结点进队列
                /*
                cout<<"ec.prof="<<ec.prof;
                cout<<"  ec.d="<<ec.d;
                cout<<"  ec.loss="<<ec.loss;
                cout<<"  ec.j="<<ec.j;
                cout<<endl;
                */
                T cost = total - ec.prof;    //计算上界函数值
                if (cost<U)
                {
                    U = cost;  ans = child;   //修改上界变量U,置child为当前的答案结点,
                }                        //当函数返回时,ans指向答案结点
            }
            loss = loss + p[j];
        }
        //cout<<endl;
        if (!q.empty())
        {
            ep=q.top();                  //选择下一个扩展结点 
            q.pop();
            if (ep.loss >= U)
                return total = U;
        }
        else return total = U;                 //若队列为空,则返回最小损失值,隐含着返回ans结点
    }
}

template<class T>
void JS<T>::GenerateAns(int *x, int &k)
{
    Node *ans1 = ans;
    k = 0;
    while (ans1->j>0)
    {
        k++;
        ans1 = ans1->parent;
    }
    ans1 = ans;
    for (int i = k - 1; i >= 0; i--)
    {
        x[i] = ans1->j;
        ans1 = ans1->parent;
    }
}

#define SIZE 5

void main()
{
    float prof[SIZE] = { 3, 8, 6, 4, 5 };   //{5,3,6,10};
    int de[SIZE] = { 1, 2, 3, 4, 4 };       //{1,1,2,3};
    int time[SIZE] = { 1, 1, 2, 2, 1 };     //{1,1,1,2};
    float total = 0, U;
    int x[10];
    int k;

    JS<float> work(prof, de, time, SIZE);
    U = work.JSLCBB();      cout << endl;
    for (int i = 0; i<SIZE; i++) total += prof[i];

    cout << endl;
    cout << "total=" << total << endl;

    cout << endl;
    cout << "U=" << U << endl;

    cout << endl;
    cout << "最优解的值=" << total - U << endl;

    cout << "最优解X[]:" << endl;
    work.GenerateAns(x, k);
    for (int i = 0; i<k; i++) cout << " " << x[i];
    cout << endl;

    for (int i = 0; i<k; i++)
        cout << "(" << prof[x[i]] << "," << de[x[i]] << "," << time[x[i]] << ")" << endl;
}

【C++】优先队列priority_queue

优先队列是队列的一种,允许用户对队列中存储的元素设置优先级。按照数据的优先级来对队列中的数据进行动态的排序。每次的push和pop操作,队列都会动态的调整。 所以我们无论按照什么顺序...
  • qq_27991659
  • qq_27991659
  • 2016年01月21日 15:11
  • 3250

c++STL中优先队列的使用

说到队列,我们首先想到就是先进先出,后进后出;那么何为优先队列呢,在优先队列中,元素被赋予优先级,当访问元素时,具有最高级优先级的元素先被访问。即优先队列具有最高级先出的行为特征。 优先队列在头文件...
  • AC_Gibson
  • AC_Gibson
  • 2015年03月11日 16:15
  • 13060

【C++优先队列】

优先队列:顾名思义,首先它是一个队列,但是它强调了“优先”二字,所以,已经不能算是一般意义上的队列了,它的“优先”意指取队首元素时,有一定的选择性,即根据元素的属性选择某一项值最优的出队~ 百度百科上...
  • qq_24653023
  • qq_24653023
  • 2016年07月16日 21:18
  • 2079

C++优先队列(priority queue)及重载运算符

定义: 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in,...
  • riba2534
  • riba2534
  • 2016年12月04日 01:08
  • 1709

C++之队列和优先队列

转载自:http://www.cppblog.com/wanghaiguang/archive/2012/06/05/177644.html http://www.cnblogs.com/heqin...
  • liuweiyuxiang
  • liuweiyuxiang
  • 2016年08月01日 19:18
  • 2056

【STL学习】优先级队列Priority Queue详解与C++编程实现

优先级队列Priority Queue介绍 优先级队列是一个拥有权值观念的queue。它允许在底端添加元素、在顶端去除元素、删除元素。 优先级队列内部的元素并不是按照添加的顺序排列,而是自...
  • xiajun07061225
  • xiajun07061225
  • 2013年01月30日 16:43
  • 14131

基于最大堆的最大优先队列的C++类模板实现

  • 2013年12月19日 22:50
  • 2KB
  • 下载

C++ - 库函数优先级队列(priority_queue)输出最小值 代码

库函数优先级队列(priority_queue)输出最小值 代码本文地址: http://blog.csdn.net/caroline_wendy库函数优先级队列(priority_queue)的实现...
  • u012515223
  • u012515223
  • 2014年07月21日 09:23
  • 4551

C++ STL优先队列常用用法

STL优先队列
  • CerberuX
  • CerberuX
  • 2016年06月26日 13:08
  • 1170

priority_queue<int,vector<int>,greater<int>>优先队列 按照由小到大顺序

C++优先队列的基本使用方法  #include #include #include using namespace std; struct node {     friend bo...
  • lethic
  • lethic
  • 2012年07月23日 01:24
  • 15068
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++队列和优先权队列的使用---应用:带时限作业排序
举报原因:
原因补充:

(最多只允许输入30个字)