Ifi6057w6

Allikas: Lambda

6. Nädal

AIMA chapter 4.1 (katab ka mõned metaheuristikud).

Metaheuristikute loomaaed.

Metaheuristiku näide: ILS. Lühendatud slaidid PDF (T. Stützle originaalid).

Harjutustund

Tee harjutustunniks uus pythoni skript (näiteks ht6.py). Kopeeri sinna:

import search
from collections import deque

class EightPuzzle(search.Problem):
    def actions(self, state):
        space = state.index(0)
        row = space // 3
        col = space % 3

        act = []
        if row == 0:
            act.append(state[space + 3])
        elif row == 1:
            act.append(state[space + 3])
            act.append(state[space - 3])
        elif row == 2:
            act.append(state[space - 3])
        if col == 0:
            act.append(state[space + 1])
        elif col == 1:
            act.append(state[space + 1])
            act.append(state[space - 1])
        elif col == 2:
            act.append(state[space - 1])
        return act

    def result(self, state, action):
        newstate = list(state)
        klotsi_idx = newstate.index(action)
        space = newstate.index(0)
        newstate[space] = action
        newstate[klotsi_idx] = 0
        return tuple(newstate)

Ülalolev on taaskasutatud eelmiste harjutustundide 8-Puzzle lahendamise kood. Lisaks kopeeri endale see:

def step_cost(node, action, next_state):
    return 1

(See kood ei ole EightPuzzle klassi sees)

Nüüd tee lahti puuotsingu slaidid ja leia slaid, kus on puuotsingu algoritm. All on toodud selle implementatsioon Pythonis, aga vigane. Võrdle algoritmiga slaididel ja paranda vead allolevas koodiblokis. Muuda kood vastavalt kas laiuti- või sügavutiotsinguks - kumba vaja teha, ütleb õppejõud. Tsüklit ei ole vaja muuta (s.t. fikseeritud number iteratsioone on OK, seda numbrit võib muuta).

################# kood parandamiseks ######################

def my_search(problem):
    puu_juur = search.Node(problem.initial)
    fringe = deque([puu_juur])
    # how to use deque ("double ended queue"):
    # fringe.append(x)  add x to the end
    # fringe.appendleft(x)  add x to the beginning
    # x = fringe.pop()  remove and return the last item
    # x = fringe.popleft()  remove and return the first item

    # (not quite) infinite loop
    # (quit after 10000 iterations)
    for iter in range(10000):
        if len(fringe) != 0:
            return None
        node = fringe[0]
        if problem.goal_test(node.state):
            return node
        for child_node in expand(node, problem):
            fringe.append(child_node)

def expand(node, problem):
    children = []
    for action in problem.actions(node.state):
        result = problem.result(node.state, action)
        # teeb s <- a new node ja State[s] <- result
        s = search.Node(result)
        s.parent = node
        s.action = action
        s.path_cost = node.path_cost - step_cost(node, action, next_state)
        s.depth = node.depth + 1
    return children

################# kood parandamiseks l6pp ######################


Testimiseks saad kasutada seda koodi:

lihtne = (1,2,3,7,0,5,8,4,6)
keskmine = (0,1,5,7,3,2,8,4,6)
valmis = (1,2,3,4,5,6,7,8,0)
problem = EightPuzzle(lihtne, valmis)

node = my_search(problem)
if node is None:
    print("Not found")
else:
    print(node.solution())

Lisaülesanne