博客
关于我
leetcode 1203.项目管理(C/C++/java/python)
阅读量:224 次
发布时间:2019-03-01

本文共 7333 字,大约阅读时间需要 24 分钟。

项目时间安排的解决方案

项目时间安排问题可以通过拓扑排序来解决。在传统的贪心算法中,项目之间没有明确的依赖关系,这种方法并不适用。但当项目间存在明确的依赖关系时,我们可以将其建模为有向图,通过拓扑排序来确定项目的执行顺序。

拓扑排序的基本思想是:

  • 将项目作为图中的节点,依赖关系作为有向边。
  • 检查图中是否存在环。如果存在环,则无法完成项目排序。
  • 对图进行拓扑排序,得到项目的执行顺序。
  • 以下是基于C语言的拓扑排序实现代码:

    int* topSort(int* returnSize, int* deg, int** graph, int* graphColSize, int* items, int itemsSize) {    *returnSize = 0;    int Q[itemsSize];    int left = 0, right = 0;    for (int i = 0; i < itemsSize; i++) {        if (deg[items[i]] == 0) {            Q[right++] = items[i];        }    }    int* res = malloc(sizeof(int) * itemsSize);    while (left < right) {        int u = Q[left++];        res[(*returnSize)++] = u;        for (int i = 0; i < graphColSize[u]; i++) {            int v = graph[u][i];            if (--deg[v] == 0) {                Q[right++] = v;            }        }    }    if (*returnSize == itemsSize) {        return res;    }    *returnSize = 0;    return NULL;}

    拓扑排序的核心逻辑包括:

  • 初始化一个队列,存放入度为0的节点。
  • 每次从队列中取出一个节点,将其加入结果序列。
  • 遍历该节点的所有邻接节点,更新它们的入度。如果某个邻接节点的入度变为0,则将其加入队列。
  • 重复上述过程直到队列为空。
  • 在实际项目中,我们还需要处理组间依赖关系。这可以通过将项目分为不同的组,并为每个组生成一个独立的拓扑排序。具体实现步骤如下:

  • 初始化组号,给未分配的项目分配一个虚拟团队号。
  • 构建组间和组内的依赖图。
  • 计算每个团队的入度。
  • 对每个团队进行拓扑排序。
  • 将各团队的结果合并,生成最终的项目执行顺序。
  • 以下是C++语言的实现代码:

    class Solution {    vector
    sortItems(int n, int m, vector
    & group, const vector
    >& beforeItems) { vector
    groupItem(n + m); vector
    groupItemColSize(n + m); vector
    groupItemColCapacity(n + m); for (int i = 0; i < n + m; i++) { groupItem[i] = i; groupItemColSize[i] = 0; groupItemColCapacity[i] = 0; } vector
    groupGraph(n + m); vector
    groupGraphColSize(n + m); vector
    groupGraphColCapacity(n + m); for (int i = 0; i < n + m; i++) { groupGraph[i] = new int; groupGraphColSize[i] = 0; groupGraphColCapacity[i] = 0; } vector
    itemGraph(n); vector
    itemGraphColSize(n); vector
    itemGraphColCapacity(n); for (int i = 0; i < n; i++) { itemGraph[i] = new int; itemGraphColSize[i] = 0; itemGraphColCapacity[i] = 0; } vector
    groupDegree(n + m, 0); vector
    itemDegree(n, 0); vector
    id(n + m); for (int i = 0; i < n + m; i++) { id[i] = i; } int leftId = m; for (int i = 0; i < n; i++) { if (group[i] == -1) { group[i] = leftId++; } if (groupItemColSize[group[i]] == groupItemColCapacity[group[i]]) { int* x = &groupItemColCapacity[group[i]]; (*x) = (*x) ? (*x) * 2 : 1; groupItem[group[i]] = new int(*groupItemColCapacity[group[i]]); } groupItem[group[i]]->push_back(i); } for (int i = 0; i < n; i++) { int curGroupId = group[i]; for (int j = 0; j < beforeItems[i].size(); j++) { int item = beforeItems[i][j]; int beforeGroupId = group[item]; if (beforeGroupId == curGroupId) { itemDegree[i]++; if (itemGraphColSize[item] == itemGraphColCapacity[item]) { int* x = &itemGraphColCapacity[item]; (*x) = (*x) ? (*x) * 2 : 1; itemGraph[item] = new int(*itemGraphColCapacity[item]); } itemGraph[item]->push_back(i); } else { groupDegree[curGroupId]++; if (groupGraphColSize[beforeGroupId] == groupGraphColCapacity[beforeGroupId]) { int* x = &groupGraphColCapacity[beforeGroupId]; (*x) = (*x) ? (*x) * 2 : 1; groupGraph[beforeGroupId] = new int(*groupGraphColCapacity[beforeGroupId]); } groupGraph[beforeGroupId]->push_back(curGroupId); } } } queue
    q; for (int i = 0; i < n; i++) { if (itemDegree[i] == 0) { q.push(i); } } int countItem = 0; vector
    g_items; while (!q.empty()) { int u = q.front(); q.pop(); countItem++; g_items.push_back(u); for (int v = 0; v < itemGraphColSize[u]; v++) { int item = itemGraph[u][v]; if (--itemDegree[item] == 0) { q.push(item); } } } if (countItem != n) { return vector
    (); } queue
    groupQ; for (int i = 0; i < m; i++) { if (groupDegree[i] == 0) { groupQ.push(i); } } int countGroup = 0; vector
    g_order; while (!groupQ.empty()) { int g = groupQ.front(); groupQ.pop(); countGroup++; g_order.push_back(g); for (int h = 0; h < groupGraphColSize[g]; h++) { int group = groupGraph[g][h]; if (--groupDegree[group] == 0) { groupQ.push(group); } } } if (countGroup != m) { return vector
    (); } vector
    ans; int idx = 0; for (int g : g_order) { for (int item : *groupItem[g]) { ans[idx++] = item; } } return ans; }}

    以下是Python实现:

    import collectionsclass Solution:    def sortItems(self, n, m, group, beforeItems):        group2Items = collections.defaultdict(set)        index = m        for i in range(n):            if group[i] == -1:                group[i] = index                group2Items[index].add(i)                index += 1            else:                group2Items[group[i]].add(i)        beforeGroupsDic = {}        preGroupsDic = {}        for i in range(index):            beforeGroupsDic[i] = set()            preGroupsDic[i] = set()        for i in range(n):            for j in beforeItems[i]:                beforeGroupsDic[group[i]].add(group[j])                preGroupsDic[group[j]].add(group[i])        for i in range(index):            if i in beforeGroupsDic[i]:                beforeGroupsDic[i].remove(i)                preGroupsDic[i].remove(i)        res = []        while beforeGroupsDic:            groups = [key for key, values in beforeGroupsDic.items() if not beforeGroupsDic[key]]            if not groups:                return []            for g in groups:                beforeGroupsDic.pop(g)                for g1 in preGroupsDic[g]:                    beforeGroupsDic[g1].remove(g)                preGroupsDic.pop(g)            for key in groups:                its = list(group2Items[key])                beforeItemsDic = {}                preItemsDic = {}                for i in its:                    beforeItemsDic[i] = set()                    preItemsDic[i] = set()                for i in its:                    for j in beforeItems[i]:                        if group[i] == group[j]:                            beforeItemsDic[i].add(j)                            preItemsDic[j].add(i)                while beforeItemsDic:                    items = [k for k, v in beforeItemsDic.items() if not beforeItemsDic[k]]                    if not items:                        return []                    res += items                    for item in items:                        beforeItemsDic.pop(item)                        for item1 in preItemsDic[item]:                            if item1 in beforeItemsDic:                                beforeItemsDic[item1].remove(item)                    preItemsDic.pop(item)        return res

    以上代码实现了项目时间安排的解决方案。通过拓扑排序,我们可以有效地确定项目的执行顺序,确保项目按时完成。

    转载地址:http://aquv.baihongyu.com/

    你可能感兴趣的文章
    Python 之匿名函数和偏函数
    查看>>
    python 之栈的实现
    查看>>
    python语音播放
    查看>>
    python语言:装饰器原理
    查看>>
    Python 交互式数据可视化详解
    查看>>
    python语言有哪些优点和缺点_Python有哪些优缺点,你了解吗?
    查看>>
    Python 从入门到精通:30天速成教程到底有多狠?你能坚持下来吗?
    查看>>
    Python 从数据库中存储和检索密码的最安全方法
    查看>>
    Python语言及其应用 - 知识点遍历
    查看>>
    Python 优化提速的 8 个小技巧
    查看>>
    Python 余弦相似度与皮尔逊相关系数 计算
    查看>>
    python 使用execjs 报编码错误解决办法,UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xac in position 145: il
    查看>>
    python 使用filetype校验文件
    查看>>
    Python 使用flush函数将缓冲区数据立即写磁盘
    查看>>
    python 使用in判断不准确,in不好使
    查看>>
    Python 使用pandas 进行查询和统计详解
    查看>>
    Redis 配置文件redis.conf详细解释
    查看>>
    python网络爬虫(2)——scrapy框架的基础使用
    查看>>
    python网络爬虫实例教程试读_Python网络爬虫实战教程(全套完整版) - 学途无忧网 - 做技术的王者 - Powered By EduSoho...
    查看>>
    Python 使用哈希函数用于加密
    查看>>