diff --git a/dynamic_programming/travelling_salesman.py b/dynamic_programming/travelling_salesman.py new file mode 100644 index 000000000000..33c09433de9e --- /dev/null +++ b/dynamic_programming/travelling_salesman.py @@ -0,0 +1,76 @@ +def tsp_dp(distances: list[list[float]]) -> tuple[float, list[int]]: + """ + Solves Traveling Salesman Problem using dynamic programming. + + >>> distances = [[0, 10, 15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]] + >>> cost, path = tsp_dp(distances) + >>> float(cost) + 80.0 + >>> path[0] + 0 + + >>> distances = [[0, 5], [5, 0]] + >>> cost, path = tsp_dp(distances) + >>> float(cost) + 10.0 + >>> path + [0, 1] + """ + if not distances: + raise ValueError("Empty distance matrix") + + n = len(distances) + all_points = (1 << n) - 1 + dp = {} + parent = {} + + def solve(mask: int, pos: int) -> float: + """ + Recursive helper function for solving the TSP using dynamic programming. + + :param mask: Bitmask representing visited nodes. + :param pos: Current position in the tour. + :return: Minimum cost to complete the tour. + """ + if mask == all_points: + return distances[pos][0] + + state = (mask, pos) + if state in dp: + return dp[state] + + minimum = float("inf") + min_next = -1 + + for next_city in range(n): + if mask & (1 << next_city) == 0: + new_mask = mask | (1 << next_city) + new_dist = distances[pos][next_city] + solve(new_mask, next_city) + + if new_dist < minimum: + minimum = new_dist + min_next = next_city + + dp[state] = minimum + parent[state] = min_next + return minimum + + optimal_cost = solve(1, 0) + + path = [0] + mask = 1 + pos = 0 + + for _ in range(n - 1): + next_pos = parent[(mask, pos)] + path.append(next_pos) + mask |= 1 << next_pos + pos = next_pos + + return optimal_cost, path + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/graphics/butterfly_pattern.py b/graphics/butterfly_pattern.py new file mode 100644 index 000000000000..6fd15b38b148 --- /dev/null +++ b/graphics/butterfly_pattern.py @@ -0,0 +1,16 @@ +def butterfly_pattern(n): + # Upper part + for i in range(1, n + 1): + print("*" * i, end="") + print(" " * (2 * (n - i)), end="") + print("*" * i) + + # Lower part + for i in range(n - 1, 0, -1): + print("*" * i, end="") + print(" " * (2 * (n - i)), end="") + print("*" * i) + + +n = int(input("Enter the size: ")) +butterfly_pattern(n)