博客
关于我
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/

    你可能感兴趣的文章
    Objective-C实现大位数乘法(附完整源码)
    查看>>
    Objective-C实现大根堆(附完整源码)
    查看>>
    Objective-C实现奇偶检验码(附完整源码)
    查看>>
    Objective-C实现奇偶转置排序算法(附完整源码)
    查看>>
    Objective-C实现奇异值分解SVD(附完整源码)
    查看>>
    Objective-C实现子集总和算法(附完整源码)
    查看>>
    Objective-C实现字符串boyer moore search博耶摩尔搜索算法(附完整源码)
    查看>>
    Objective-C实现字符串IP地址转DWORD地址(附完整源码)
    查看>>
    Objective-C实现字符串jaro winkler算法(附完整源码)
    查看>>
    Objective-C实现字符串manacher马拉车算法(附完整源码)
    查看>>
    Objective-C实现字符串wildcard pattern matching通配符模式匹配算法(附完整源码)
    查看>>
    Objective-C实现字符串word patterns单词模式算法(附完整源码)
    查看>>
    Objective-C实现字符串Z 函数或 Z 算法(附完整源码)
    查看>>
    Objective-C实现字符串加解密(附完整源码)
    查看>>
    Objective-C实现字符串复制功能(附完整源码)
    查看>>
    Objective-C实现字符串是否回文Palindrome算法 (附完整源码)
    查看>>
    Objective-C实现完整的ComplexNumber复数类(附完整源码)
    查看>>
    Objective-C实现实现rabin karp算法(附完整源码)
    查看>>
    Objective-C实现对图像进行色调处理算法(附完整源码)
    查看>>
    Objective-C实现对称矩阵压缩存储(附完整源码)
    查看>>