Simple Execution Planner
An execution planner is a crucial component in database systems and task schedulers. It analyzes a set of operations and determines the most efficient order to execute them, minimizing resource usage and execution time. This challenge asks you to build a simplified execution planner that optimizes the order of operations based on a cost model.
Problem Description
You are tasked with creating a basic execution planner in Python. The planner will receive a list of operations, each with an associated cost. The goal is to find the permutation of these operations that results in the lowest total cost. The planner should implement a brute-force approach to explore all possible permutations and select the one with the minimum cost.
Key Requirements:
- Input: A list of tuples, where each tuple represents an operation and contains the operation's name (string) and its cost (integer).
- Output: A tuple containing:
- A list representing the optimal order of operations (list of operation names).
- The minimum total cost achieved by that order (integer).
- Cost Model: The total cost is simply the sum of the costs of the operations in the chosen order.
- Brute-Force Approach: Due to the simplicity of the problem, a brute-force approach (generating all permutations) is acceptable. Do not implement more sophisticated optimization algorithms like dynamic programming or heuristics.
Expected Behavior:
The planner should correctly identify the optimal order of operations and its corresponding cost for various input scenarios. It should handle cases with duplicate operation costs and empty input lists gracefully.
Edge Cases to Consider:
- Empty Input List: If the input list is empty, the planner should return an empty list for the optimal order and a cost of 0.
- Single Operation: If the input list contains only one operation, the planner should return a list containing that operation and its cost.
- Duplicate Costs: The planner should handle cases where multiple operations have the same cost. Any permutation resulting in the minimum cost is acceptable.
Examples
Example 1:
Input: [("A", 10), ("B", 5), ("C", 8)]
Output: ['B', 'C', 'A']
Explanation: The permutations and their costs are:
- ['A', 'B', 'C']: 10 + 5 + 8 = 23
- ['A', 'C', 'B']: 10 + 8 + 5 = 23
- ['B', 'A', 'C']: 5 + 10 + 8 = 23
- ['B', 'C', 'A']: 5 + 8 + 10 = 23
- ['C', 'A', 'B']: 8 + 10 + 5 = 23
- ['C', 'B', 'A']: 8 + 5 + 10 = 23
All permutations have the same cost. Any of them is a valid output.
Example 2:
Input: [("X", 2), ("Y", 7), ("Z", 1)]
Output: ['Z', 'X', 'Y']
Explanation: The permutation ['Z', 'X', 'Y'] has the lowest cost: 1 + 2 + 7 = 10.
Example 3: (Edge Case)
Input: []
Output: ([], 0)
Explanation: An empty input list should return an empty list and a cost of 0.
Constraints
- The number of operations in the input list will be between 0 and 10 (inclusive). This limits the computational complexity of the brute-force approach.
- Operation names will be strings consisting of uppercase letters (A-Z).
- Operation costs will be non-negative integers.
- The code should be reasonably efficient for the given constraints. While brute-force is acceptable, avoid unnecessary overhead.
Notes
- You can use the
itertools.permutationsfunction from the Python standard library to generate permutations. - Focus on clarity and correctness. The code should be easy to understand and produce the correct output.
- Consider how to handle ties in cost – any optimal permutation is acceptable.
- The function should return a tuple as specified in the "Output" section.