(LBFSP)中间存储有限流水车间的有向图模型(c++实现)

基本概念: 

引自 《混合差分进化与调度算法》-王凌 ,图中应该漏标了两个关键路径节点(实心点),但不影响理解。LBFSP可以转化为有向无环图模型,在工件数n、机器数m、缓冲区容量Bj,j+1都确定的情况下,工件的排序不同,图中顶点的权值和倾斜边的权值也不同(水平边和垂直边权值均为0),但图的结构并不会发生变化。

LBFSP有向图c++实现如下。

#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

//边
struct Edge {
    vector<int> from;  //边的起点
    vector<int> to;  //边指向的顶点
    double weight;  //边的权重,LBFSP中水平边和垂直边权重为0,倾斜边(缓冲区约束)权重为边的起点对应的加工时间的相反数
    Edge() {}
    Edge(vector<int> from, vector<int> to, double weight = 0.0): from(from), to(to), weight(weight) {}
};

//顶点
struct Node {
    vector<int> op;  //顶点的编号,即工序号,从(1, 1)到(n, m),共n*m个
    vector<Edge> edges; //顶点的出边
    double weight;  //顶点的权重,LBFSP中顶点权重为对应工序的加工时间
    int in_degree = 0;  //顶点的入度(用于拓扑排序)
};

int main()
{
    int n = 5, m = 5;  //n为工件数,m为机器数
    vector<vector<Node*>> DAG(n, vector<Node*>(m, nullptr));  //邻接表
    vector<int> b(m - 1, 0);  //机器j与j + 1间的缓冲区容量
    vector<vector<double>> T(n, vector<double>(m, 0));  //加工时间
    vector<int> solution(n, 0);
    iota(solution.begin(), solution.end(), 1); //工件的排序(序号从1到n) {1,2,3,4,5}
    T[0] = { 1, 1, 1, 1, 1 };
    T[1] = { 1, 2, 2, 1, 1 };
    T[2] = { 3, 1, 1, 2, 1 };
    T[3] = { 1, 1, 2, 3, 1 };
    T[4] = { 1, 2, 3, 1, 4 };

    /* 有向图建立 */
    //初始化顶点
    for (auto& nodes : DAG) {
        for (auto& node : nodes) node = new Node();
    }

    //顶点编号和顶点权重
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            DAG[i][j]->op = vector<int>{ i + 1, j + 1 };
            DAG[i][j]->weight = T[solution[i] - 1][j];
        }
    }

    //边和边的权重
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            //工件顺序约束
            if (i - 1 >= 0) {
                DAG[i - 1][j]->edges.push_back(Edge({ i - 1, j }, { i, j }, 0.0));
                DAG[i][j]->in_degree++;
            }

            //机器顺序约束
            if (j - 1 >= 0) {
                DAG[i][j - 1]->edges.push_back(Edge({ i, j - 1 }, { i, j }, 0.0));
                DAG[i][j]->in_degree++;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            //缓冲区约束
            if (j + 1 < m && i - b[j] - 1 >= 0) {
                DAG[i - b[j] - 1][j + 1]->edges.push_back(Edge({ i - b[j] - 1, j + 1 }, { i, j }, -T[solution[i - b[j] - 1] - 1][j + 1]));
                DAG[i][j]->in_degree++;
            }
        }
    }
    /* 有向图建立完毕 */

    //打印输出
    int i = 1;
    for (auto& nodes : DAG) {     
        int j = 1;
        for (auto& node : nodes) {
            cout << "******** " << i << ", " << j << "********" << endl;
            cout << "顶点编号:" << node->op[0] << "  " << node->op[1] << endl;
            cout << "顶点出边数:" << node->edges.size() << endl;
            cout << "顶点入度:" << node->in_degree << endl;
            cout << "顶点权值:" << node->weight << endl;
            cout << "******** " << i << ", " << j++ << "********" << endl;
        }
        cout << endl;
        i++;
    }

    cout << "****** 特定点的出边详细信息 ******" << endl;
    cout << "**(1, 1):" << endl;
    for (auto& edge : DAG[0][0]->edges) {
        cout << "------------" << endl;
        cout << "(" << edge.from[0] << ", " << edge.from[1] << ") -> ";
        cout << "(" << edge.to[0] << ", " << edge.to[1] << ")" << endl;
        cout << edge.weight << endl;
        cout << "------------" << endl;
    }
    cout << endl << "**(3, 3):" << endl;
    for (auto& edge : DAG[2][2]->edges) {
        cout << "------------" << endl;
        cout << "(" << edge.from[0] << ", " << edge.from[1] << ") -> ";
        cout << "(" << edge.to[0] << ", " << edge.to[1] << ")" << endl;
        cout << edge.weight << endl;
        cout << "------------" << endl;
    }
    cout << endl << "**(5, 5):" << endl;
    for (auto& edge : DAG[4][4]->edges) {
        cout << "------------" << endl;
        cout << "(" << edge.from[0] << ", " << edge.from[1] << ") -> ";
        cout << "(" << edge.to[0] << ", " << edge.to[1] << ")" << endl;
        cout << edge.weight << endl;
        cout << "------------" << endl;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值