Untitled

mail@pastecode.io avatar
unknown
plain_text
11 days ago
7.9 kB
3
Indexable
Never
#define MAX_LINE 503
#define MAX_EQUIP 503
#define MAX_PRODUCT 30005
#include<unordered_map>
#include<queue>
#include<set>
using namespace std;

// Cấu trúc lưu thông tin của mỗi sản phẩm
struct Product{
    int pID;            // ID của sản phẩm
    int line;           // Dây chuyền sản xuất mà sản phẩm này sẽ sử dụng
    int end;            // Thời gian sản phẩm này hoàn thành sản xuất
    int work;           // Thời gian sản xuất cần thiết để hoàn thành sản phẩm
    int idEquipInMap;   // ID thiết bị ánh xạ với sản phẩm này
    int statusPro;      // Trạng thái của sản phẩm (1: chờ, 2: đang sản xuất, 3: đã hoàn thành)
};
Product products[MAX_PRODUCT]; // Mảng chứa thông tin tất cả các sản phẩm
int cntP, cntE;                // `cntP`: đếm số lượng sản phẩm, `cntE`: đếm số lượng thiết bị

// Hàm so sánh để sắp xếp các sản phẩm trong quá trình sản xuất
struct cmp{
    bool operator()(int a, int b){
        // Sắp xếp theo thời gian kết thúc, nếu bằng thì sắp xếp theo ID sản phẩm
        if(products[a].end < products[b].end || (products[a].end == products[b].end && products[a].pID < products[b].pID)){
            return true;
        }
        return false;
    }
};

// Khai báo các hàng đợi để quản lý sản phẩm trên các dây chuyền sản xuất
queue<int> listLine[MAX_LINE]; // Mỗi hàng đợi quản lý các sản phẩm đang chờ xử lý trên một dây chuyền
unordered_map<int,int> mapProduct; // Ánh xạ ID sản phẩm (pID) tới chỉ số của sản phẩm trong mảng `products[]`
unordered_map<int,int> mapEquip;   // Ánh xạ ID thiết bị tới chỉ số của thiết bị trong hệ thống
set<int,cmp> listProducing;        // Tập hợp các sản phẩm đang được sản xuất, sắp xếp theo hàm `cmp`
int equip[MAX_EQUIP];              // Trạng thái của các thiết bị (0: rảnh, 1: đang bận)
int lineBusy[MAX_LINE];            // Trạng thái của các dây chuyền sản xuất (-1: rảnh, ID sản phẩm: đang xử lý)

int numLine;     // Số lượng dây chuyền
int numEquip;    // Số lượng thiết bị
int timeLine;    // Thời gian hiện tại của hệ thống

// Hàm khởi tạo hệ thống sản xuất với L dây chuyền và M thiết bị
void init(int L, int M) {
    numLine = L;      // Gán số dây chuyền sản xuất
    numEquip = M;     // Gán số thiết bị
    cntP = 0;         // Đặt số lượng sản phẩm về 0
    cntE = 0;         // Đặt số lượng thiết bị ánh xạ về 0
    timeLine = 0;     // Đặt thời gian hệ thống về 0
    mapProduct.clear();   // Xóa tất cả ánh xạ sản phẩm
    mapEquip.clear();     // Xóa tất cả ánh xạ thiết bị
    listProducing.clear(); // Xóa danh sách sản phẩm đang sản xuất
    for(int i = 0; i < MAX_LINE; i++){
        listLine[i] = queue<int>();  // Khởi tạo hàng đợi cho các dây chuyền sản xuất
        lineBusy[i] = -1;            // Đặt trạng thái dây chuyền về rảnh (-1)
    }
    for(int i = 0; i < MAX_EQUIP; i++){
        equip[i] = 0;                // Đặt trạng thái tất cả thiết bị về rảnh (0)
    }
    return;
}

// Hàm duyệt sản phẩm đang sản xuất và cập nhật hệ thống tại thời điểm `timeSt`
void duyetSP(int timeSt, bool newr){
    bool completed = false; // Biến kiểm tra xem có sản phẩm nào hoàn thành hay không
    while(!listProducing.empty()){ // Duyệt qua danh sách các sản phẩm đang được sản xuất
        auto it = listProducing.begin(); // Lấy sản phẩm có thời gian kết thúc sớm nhất
        if(products[*it].end > timeSt){  // Nếu thời gian kết thúc của sản phẩm lớn hơn `timeSt`, ngừng duyệt
            break;
        }
        products[*it].statusPro = 3;       // Đánh dấu sản phẩm đã hoàn thành (statusPro = 3)
        equip[products[*it].idEquipInMap] = 0; // Đặt thiết bị của sản phẩm về rảnh
        lineBusy[products[*it].line] = -1;     // Đặt dây chuyền sản xuất về rảnh
        listProducing.erase(*it);              // Xóa sản phẩm khỏi danh sách đang sản xuất
        completed = true;                      // Đánh dấu đã có sản phẩm hoàn thành
    }
    // Nếu có sản phẩm mới hoặc sản phẩm đã hoàn thành, duyệt qua tất cả dây chuyền
    if(newr == true || completed == true){
        for(int i = 0; i < numLine; i++){
            if(!listLine[i].empty()){         // Nếu dây chuyền có sản phẩm chờ xử lý
                int idxPro = listLine[i].front(); // Lấy sản phẩm đầu tiên của dây chuyền
                if(lineBusy[products[idxPro].line] == -1 && equip[products[idxPro].idEquipInMap] == 0){
                    // Nếu dây chuyền và thiết bị rảnh
                    listLine[i].pop();              // Loại bỏ sản phẩm khỏi hàng đợi
                    products[idxPro].statusPro = 2; // Đặt sản phẩm vào trạng thái đang sản xuất
                    products[idxPro].end = timeSt + products[idxPro].work; // Cập nhật thời gian kết thúc
                    equip[products[idxPro].idEquipInMap] = 1;   // Đánh dấu thiết bị đang bận
                    lineBusy[products[idxPro].line] = products[idxPro].pID; // Đánh dấu dây chuyền đang bận
                    listProducing.insert(idxPro);   // Thêm sản phẩm vào danh sách đang sản xuất
                }
            }
        }
        timeLine = timeSt; // Cập nhật thời gian của hệ thống
    }
}

// Hàm yêu cầu sản xuất một sản phẩm mới
int request(int tStamp, int pId, int mLine, int eId, int mTime) {
    for(int i = timeLine; i < tStamp; i++){  // Cập nhật hệ thống cho đến thời gian `tStamp`
        duyetSP(i, false);
    }
    cntP++; // Tăng số lượng sản phẩm
    products[cntP].pID = pId;    // Gán ID sản phẩm
    products[cntP].work = mTime; // Gán thời gian sản xuất
    products[cntP].line = mLine; // Gán dây chuyền sản xuất
    products[cntP].statusPro = 1; // Đặt trạng thái sản phẩm thành chờ xử lý
    products[cntP].end = tStamp;  // Đặt thời gian bắt đầu sản xuất
    mapProduct[pId] = cntP; // Ánh xạ ID sản phẩm với chỉ số trong mảng `products`
    if(mapEquip[eId] == 0){ // Nếu thiết bị chưa được ánh xạ
        cntE++;              // Tăng số lượng thiết bị
        mapEquip[eId] = cntE; // Ánh xạ thiết bị vào hệ thống
    }
    products[cntP].idEquipInMap = mapEquip[eId]; // Gán thiết bị cho sản phẩm
    listLine[mLine].push(cntP); // Thêm sản phẩm vào hàng đợi của dây chuyền
    duyetSP(tStamp, true); // Duyệt hệ thống để xử lý sản phẩm ngay nếu có thể
    return lineBusy[mLine]; // Trả về trạng thái dây chuyền
}

// Hàm kiểm tra trạng thái của sản phẩm tại thời điểm `tStamp`
int status(int tStamp, int pId) {
    for(int i = timeLine; i <= tStamp; i++){ // Cập nhật hệ thống cho đến thời gian `tStamp`
        duyetSP(i, false);
    }
    if(mapProduct[pId] == 0){ // Nếu sản phẩm không tồn tại
        return 0;             // Trả về 0 (sản phẩm không tồn tại)
    }
    return products[mapProduct[pId]].statusPro; // Trả về trạng thái của sản phẩm
}
Leave a Comment