\n\u30af\u30e9\u30b9\u3092\u7d99\u627f\u3057\u3066\u554f\u984c\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\nfrom simanneal import Annealer\nclass TravellingSalesmanProblem(Annealer):\n"""Test annealer with a travelling salesman problem."""<\/code><\/pre>\n<\/li>\n\n\u4f5c\u7528\u95a2\u6570\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\ndef move(self):\n """Swaps two cities in the route."""\n a = random.randint(0, len(self.state) - 1)\n b = random.randint(0, len(self.state) - 1)\n self.state[a], self.state[b] = self.state[b], self.state[a]<\/code><\/pre>\n<\/li>\n\n\u76ee\u7684\u95a2\u6570\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\ndef energy(self):\n """Calculates the length of the route."""\n e = 0\n for i in range(len(self.state)):\n e += self.distance(cities[self.state[i - 1]],\n cities[self.state[i]])\n return e<\/code><\/pre>\n<\/li>\n\n\u5b9f\u884c\u3059\u308b<\/p>\ninitial_state = ['New York', 'Los Angeles', 'Boston', 'Houston']\ntsp = TravellingSalesmanProblem(initial_state)\ntsp.steps = 10**6 # \u8a66\u884c\u56de\u6570\nitinerary, miles = tsp.anneal()\n# ...\ntsp.state # \u3053\u308c\u304c\u6700\u9069\u5316\u3055\u308c\u305f\u72b6\u614b<\/code><\/pre>\n<\/li>\n<\/ol>\n\u3084\u3063\u3066\u307f\u308b<\/h2>\n
\u554f\u984c\u3092\u518d\u63b2\u3057\u307e\u3059\u3002<\/p>\n
\n- \u540c\u3058\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4eba\u3068\u306e\u7d44\u307f\u5408\u308f\u305b\u306f\u3001\u6975\u529b\u907f\u3051\u308b<\/li>\n
- \u524d\u65e5\u4ee5\u524d\u306b\u540c\u3058\u7d44\u307f\u5408\u308f\u305b\u3060\u3063\u305f\u4eba\u3068\u306e\u7d44\u307f\u5408\u308f\u305b\u306f\u3001\u6975\u529b\u907f\u3051\u308b<\/li>\n<\/ol>\n
\u5404\u30e1\u30f3\u30d0\u30fc\u3068\u30d7\u305d\u306e\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u30ea\u30b9\u30c8\u5316\u3059\u308b<\/p>\n
members = [\n ["\u5c71\u7530", "p1"],\n ["\u7530\u4e2d", "p2"],\n ["\u4f0a\u85e4", "p3"],\n ["\u6751\u7530", "p2"],\n \/\/ ...\n]<\/code><\/pre>\n\u72b6\u614b\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\n
# \u4eee\u306724\u4eba\u30923\u4eba\u3054\u3068\uff088\u30c1\u30fc\u30e0\uff09\u306b\u5206\u3051\u308b\u3053\u3068\u3092\u60f3\u5b9a\nnum_members = len(members)\nnum_team = 8\nmember_team = [i % num_team for i in range(num_members)]\nteam_to_member = [[] for _ in range(num_team)]\nproject_count_by_team = [defaultdict(int) for _ in range(num_team)]\n\nfor i in range(num_members):\n team_to_member[member_team[i]].append(i)\n project_count_by_team[member_team[i]][members[i][1]] += 1\n\ninit_state = [member_team, team_to_member, project_count_by_team]<\/code><\/pre>\n\u521d\u671f\u72b6\u614b<\/p>\n
[\n # \u521d\u671f\u5024\u3068\u3057\u3066\u9806\u756a\u306b\u30c1\u30fc\u30e0\u3092\u5272\u308a\u5f53\u3066\n [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7],\n # \u5404\u30c1\u30fc\u30e0\u306e\u30e1\u30f3\u30d0\u30fc\n [[0, 8, 16],\n [1, 9, 17],\n [2, 10, 18],\n [3, 11, 19],\n [4, 12, 20],\n [5, 13, 21],\n [6, 14, 22],\n [7, 15, 23]],\n # \u5404\u30c1\u30fc\u30e0\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u6570\n [defaultdict(<class 'int'>, {'p1': 1, 'p2': 2}),\n defaultdict(<class 'int'>, {'p2': 1, 'p4': 2}),\n defaultdict(<class 'int'>, {'p3': 1, 'p4': 1, 'p2': 1}),\n defaultdict(<class 'int'>, {'p1': 1, 'p3': 1, 'p4': 1}),\n defaultdict(<class 'int'>, {'p2': 1, 'p3': 2}),\n defaultdict(<class 'int'>, {'p3': 2, 'p4': 1}),\n defaultdict(<class 'int'>, {'p4': 2, 'p1': 1}),\n defaultdict(<class 'int'>, {'p1': 1, 'p3': 2})]\n ]<\/code><\/pre>\n\u540c\u3058\u306b\u30c1\u30fc\u30e0\u306b\u306a\u3063\u305f\u56de\u6570\u3092\u8a18\u9332\u3059\u308b\u95a2\u6570\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\n
# \u30e1\u30f3\u30d0\u30fc\u306e\u4e8c\u6b21\u5143\u30ea\u30b9\u30c8\u3092\uff10\u57cb\u3081\u3059\u308b\uff08\u521d\u671f\u5024\uff09\nnum_same_team = [[0] * num_members for _ in range(num_members)]\n\ndef record_num_same_team(num_same_team, team_to_member):\n num_same_team_next = deepcopy(num_same_team)\n\n # \u540c\u3058\u30c1\u30fc\u30e0\u306b\u306a\u3063\u305f\u3089\u30a4\u30f3\u30af\u30ea\u30e1\u30f3\u30c8\u3059\u308b\n for m in team_to_member:\n for i in range(len(m)):\n m1 = m[i]\n for j in range(i+1, len(m)):\n m2 = m[j]\n num_same_team_next[m1][m2] += 1\n num_same_team_next[m2][m1] += 1\n\n return num_same_team_next<\/code><\/pre>\n\u30c1\u30fc\u30e0t\u306b\u304a\u3051\u308b\u91cd\u8907\u5ea6\u3092\u8a08\u7b97\u3059\u308b\u95a2\u6570\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\n
def calc_team_cost(t, team_to_members, project_count_by_team, num_same_team):\n # \u904e\u53bb\u306b\u540c\u3058\u30c1\u30fc\u30e0\u306b\u306a\u3063\u305f\u56de\u6570\n g = 0\n team = team_to_members[t]\n for i in range(len(team)):\n m1 = team[i]\n for j in range(i+1, len(team)):\n m2 = team[j]\n g += num_same_team[m1][m2] ** 2\n\n # \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u91cd\u8907\u6570\n d = 0\n for v in project_count_by_team[t].values():\n d += max(0, v-1)**2\n\n return g + d<\/code><\/pre>\n\u4f5c\u7528\u95a2\u6570\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\n
def move(self):\n # \u30e9\u30f3\u30c0\u30e0\u306b\u30e1\u30f3\u30d0\u30fc\u3092\u9078\u629e\n a = choice(range(num_members))\n b = choice(range(num_members))\n\n # \u30e1\u30f3\u30d0\u30fcor\u30e1\u30f3\u30d0\u30fc\u306e\u30c1\u30fc\u30e0\u304c\u540c\u3058\u306a\u3089\u3070\u30b9\u30ad\u30c3\u30d7\n if a == b:\n return 0\n\n a_team = self.state[0][a]\n b_team = self.state[0][b]\n\n if a_team == b_team:\n return 0\n\n # \u5909\u66f4\u524d\u306e\u91cd\u8907\u5ea6\u3092\u8a08\u7b97\n cost_a_before = calc_team_cost(a_team, self.state[1], self.state[2], self.num_same_team)\n cost_b_before = calc_team_cost(b_team, self.state[1], self.state[2], self.num_same_team)\n\n # \u30e1\u30f3\u30d0\u30fc\u3092\u4ea4\u63db\n self.state[2][a_team][members[a][1]] -= 1\n self.state[2][b_team][members[b][1]] -= 1\n\n self.state[1][a_team].remove(a)\n self.state[1][b_team].remove(b)\n\n self.state[0][a], self.state[0][b] = self.state[0][b], self.state[0][a]\n\n self.state[2][b_team][members[a][1]] += 1\n self.state[2][a_team][members[b][1]] += 1\n\n self.state[1][b_team].append(a)\n self.state[1][a_team].append(b)\n\n # \u5909\u66f4\u5f8c\u306e\u91cd\u8907\u5ea6\u3092\u8a08\u7b97\n cost_a_after = calc_team_cost(a_team, self.state[1], self.state[2], self.num_same_team)\n cost_b_after = calc_team_cost(b_team, self.state[1], self.state[2], self.num_same_team)\n\n # \u5dee\u5206\u3092\u8fd4\u3059\n return cost_a_after - cost_a_before + cost_b_after - cost_b_before<\/code><\/pre>\n\u76ee\u7684\u95a2\u6570\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\n
def energy(self):\n # \u5404\u30c1\u30fc\u30e0\u306e\u91cd\u8907\u5ea6\u306e\u7dcf\u548c\uff08\u3053\u306e\u5024\u3092\u6700\u5c0f\u5316\u3059\u308b\uff09\n return sum(calc_team_cost(i, self.state[1], self.state[2], self.num_same_team) for i in range(num_team))<\/code><\/pre>\n\u554f\u984c\u3092\u5b9a\u7fa9\u3059\u308b<\/p>\n
class GroupingProblem(Annealer):\n def __init__(self, init_state, num_same_team):\n super(GroupingProblem, self).__init__(init_state)\n self.num_same_team = num_same_team\n\n def move(self):\n # ...\n\n def energy(self):\n # ...<\/code><\/pre>\n\u5b9f\u884c\u3059\u308b<\/p>\n
if __name__ == "__main__":\n num_same_team = [[0] * num_members for _ in range(num_members)]\n\n # \uff11\u9031\u9593\u5206\u3092\u60f3\u5b9a\u3057\u30665\u56de\u5206\u306e\u91cd\u8907\u3092\u307f\u308b\n for i in range(5):\n problem = GroupingProblem(init_state, num_same_team)\n problem.steps = 10**5\n problem.copy_strategy = "deepcopy"\n state, e = problem.anneal()\n num_same_team = record_num_same_team(num_same_team, problem.state[1])<\/code><\/pre>\n