MIT 6.0002 Introduction to Computational Thinking and Data Science, Fall 2016 · Problem set 1, Problem A.3: Brute Force Cow Transport — brute_force_cow_transport · Prof. Eric Grimson, Prof. John Guttag and Dr. Ana Bell · CC BY-NC-SA 4.0 · MIT publishes no solution for this set; the worked solution is ours
Implement a brute force algorithm to find the minimum number of trips needed to take all the cows across the universe in brute_force_cow_transport. The result should be a list of lists, where each inner list represents a trip and contains the names of cows taken on that trip.
Another way to transport the cows is to look at every possible combination of trips and pick the best one. This is an example of a brute force algorithm. The brute force algorithm should follow this method:
get_partitions function to help you!Notes:
get_partitions that generates all the set partitions for a set of cows (it is in the starter code, above your function).Assumptions:
[[1,2],[3,4]] and [[3,4],[1,2]] are considered equivalent lists of trips, and [[1,2],[3,4]] and [[2,1],[3,4]] are considered the same partitions of [1,2,3,4].10).Helper function get_partitions: to generate all the possibilities for the brute force method, you will want to work with set partitions (https://en.wikipedia.org/wiki/Partition_of_a_set). For instance, all the possible 2-partitions of the list [1,2,3,4] are [[1,2],[3,4]], [[1,3],[2,4]], [[2,3],[1,4]], [[1],[2,3,4]], [[2],[1,3,4]], [[3],[1,2,4]], [[4],[1,2,3]].
get_partitions(list) takes as input a list and returns a generator that contains all the possible partitions of this list, from 0-partitions to n-partitions, where n is the length of this list. To use generators, you must iterate over the generator to retrieve the elements; you cannot index into a generator! For instance, the recommended way to call get_partitions on a list [1,2,3] is the following:
for partition in get_partitions([1,2,3]): print(partition)
Try out this snippet of code to see what is printed!
Example: suppose the spaceship has a cargo weight limit of 10 tons and the set of cows to transport is {"Jesse": 6, "Maybel": 3, "Callie": 2, "Maggie": 5}.
The brute force algorithm will first try to fit them on only one trip, ["Jesse", "Maybel", "Callie", "Maggie"]. Since this trip contains 16 tons of cows, it is over the weight limit and does not work.
Then the algorithm will try fitting them on all combinations of two trips. Suppose it first tries [["Jesse", "Maggie"], ["Maybel", "Callie"]]. This solution will be rejected because Jesse and Maggie together are over the weight limit and cannot be on the same trip. The algorithm will continue trying two trip partitions until it finds one that works, such as [["Jesse", "Callie"], ["Maybel", "Maggie"]].
The final result is then [["Jesse", "Callie"], ["Maybel", "Maggie"]]. Note that depending on which cow it tries first, the algorithm may find a different, optimal solution. Another optimal result could be [['Jesse', 'Maybel'], ['Callie', 'Maggie']]. (So the tests check that every cow travels exactly once, that no trip is over the limit, and that the number of trips is the minimum — not which optimal allocation you return.)
print(len(brute_force_cow_transport({"Jesse": 6, "Maybel": 3, "Callie": 2, "Maggie": 5}, 10))) # 2 print(len(brute_force_cow_transport(load_cows('ps1_cow_data_2.txt')))) # 5
Adapted for the browser: MIT's get_partitions from ps1_partition.py and the load_cows you wrote in Problem A.1 are given at the top of the editor instead of imported, and ps1_cow_data_2.txt is written into the working directory before your code runs. The tests use herds of at most 8 cows so that the brute force finishes quickly.