Sunday, August 20th
Sort items based on dependencies and groups
Given n items, where any item may belong to 1 or none of m groups, and where any item may depend on another item, sort the items based on the dependencies while keeping all grouped elements together
The idea is to create 2 graphs, one with dependencies between items, and another with dependencies between groups. Perform topological sort on both graphs. Then generate the final answer by ordering all elements within a group depending on the item-dependency graph, while preserving the ordering of the group-dependencies.
First we define the topological sort. It takes in an adjacency list and list of in-degree counts as input, and writes the output order to an input vector
Topological sort begins with an empty queue. Then we iterate over the indegree vector, and push all nodes with an indegree of 0 onto the queue.
Then we iterate through the queue, popping one element at the time and pushing it to the order vector. All the indegrees of nodes adjacent to the newly-ordered node are decremented by 1. If this results in a node with an in-degree of 0, it's pushed to the queue. This continues until the queue is empty.
If after the queue is empty, the order vector is not the same size as the indegree vector, then not all elements were sorted and the ordering failed (there was likely a cycle in the graph), so return false. Else, if the ordering was a success, return true. The order vector is kept as an input parameter passed by reference.
The full topological sort is below:
With topological sort defined, we turn attention to the main sorting function
First, create a group number for any node not in a group
Create the 4 structures needed to run topological sort on 2 graphs, namely the item adjacency list, the item in-degrees, the group adjacency list, and the group in-degrees
Next is to create the dependency graphs for items and groups. Each graph will be represented as an adjacency list. For each item in the beforeItems[], increment the vertex's indegree by 1 and add the node to the adjacency list.
Then, check if the two nodes u and v are in different groups. If so, then we can add to the group adjacency list and group indegree
With the adjacency lists and in-degree counts, we are almost ready to perform the topological sorts. We only need to define the vectors that will store the orders. If the sort returns false, there are cyclic dependencies and we can't solve the problem
With the sorted orders of items and groups, begin formulating the solution by creating a map and adding elements to their group in order according to the item sort
With nodes in their group in proper order, then iterate through groups in sorted order and add the nodes to the solution array, and return the answer
Basically creating a couple graphs, running 2 topological sorts, then translating the result into a final ordering
Thanks to CHIIKUU for a slick and sensible implementation - learned a new technique for creating adjacency lists
Comments
Post a Comment