diff --git a/kesarev/ANT.py b/kesarev/ANT.py index 0da732e..9b1e0a3 100755 --- a/kesarev/ANT.py +++ b/kesarev/ANT.py @@ -4,6 +4,9 @@ def sign(x): return 1 if(x >= 0) else -1 +def absolute_value(x): + return x if(x >= 0) else -x + class ANT: def __init__(self, size, g = None): if g is None: @@ -25,7 +28,7 @@ def returnAppleNumber(self): return self.applesWasEat def makeMoves(self, maxStep, mapSize, appleNumber, mapSource): - map = [[mapSource[i][j] for j in range(0, len(mapSource[i]))] for i in range(0, len(mapSource))] + torMap = [[mapSource[i][j] for j in range(0, len(mapSource[i]))] for i in range(0, len(mapSource))] self.applesWasEat = 0 self.moveToEatAllApples = 0 self.livingTime += 1 @@ -37,49 +40,38 @@ def makeMoves(self, maxStep, mapSize, appleNumber, mapSource): apples = appleNumber while not apples == 0 and moves < 1.5 * maxStep: - if x >= mapSize or x < 0: - x -= mapSize * sign(x) - if y >= mapSize or y < 0: - y -= mapSize * sign(y) - nextX = x nextY = y - if rotation == 0: - nextX += 1 - elif rotation == 1: - nextY += 1 - elif rotation == 2: - nextX -= 1 - elif rotation == 3: - nextY -= 1 + if absolute_value(rotation) == 1: + nextY += sign(rotation) + else: + nextX += sign(rotation) if nextX >= mapSize or nextX < 0: nextX -= mapSize * sign(nextX) if nextY >= mapSize or nextY < 0: nextY -= mapSize * sign(nextY) - action = st.getAction(map[nextY][nextX]) - outState = st.getOutState(map[nextY][nextX]) + action = st.getAction(torMap[nextY][nextX]) + outState = st.getOutState(torMap[nextY][nextX]) st = self.genome.getState(outState) if action == 0: x = nextX y = nextY - if map[nextY][nextX] == 1: + if torMap[y][x] == 1: apples -= 1 - map[nextY][nextX] = 0 + torMap[y][x] = 0 if moves < maxStep: self.applesWasEat += 1 elif action == 2: rotation -= 1 - if rotation < 0: - rotation = 3 + if rotation < -2: + rotation = 1 elif action == 1: rotation += 1 - if rotation > 3: - rotation = 0 - elif action == 3: - pass + if rotation > 1: + rotation = -2 moves += 1 self.moveToEatAllApples = moves self.prior = self.applesWasEat + (maxStep - self.moveToEatAllApples) / (float(maxStep)) \ No newline at end of file diff --git a/kesarev/GENOME.py b/kesarev/GENOME.py index 89849f3..2743964 100755 --- a/kesarev/GENOME.py +++ b/kesarev/GENOME.py @@ -14,8 +14,8 @@ def __init__(self, size): action1 = random.randint(0, 3) self.states.append(STATE.STATE(out0, out1, action0, action1)) - def getState(self, id): - return self.states[id] + def getState(self, i): + return self.states[i] def getStartState(self): return self.states[self.startState] diff --git a/kesarev/README.md b/kesarev/README.md index 26bfb78..321944e 100644 --- a/kesarev/README.md +++ b/kesarev/README.md @@ -1,2 +1,32 @@ -smart_ant -========= \ No newline at end of file +SMART ANT +========= + +Задача Умный муравей. + +Постановка задачи +------- +Задано тороидальное поле(Уходя за край поля, муравей появляется с другого его края) n x n клеток, на нем заданным образом расположены k яблок. Необходимо построить конечный управляющий автомат Мили из +l состояний, описывающий муравья, который за m ходов съедает все яблоки. Изначально муравей находится в верхней левой клетке тора и смотрит вправо. Муравей может видеть, есть ли яблоко в клетке перед ним, и на каждом шаге должен выполнять одно из трех действий: +1. повернуться на 90 градусов налево +2. повернуться на 90 градусов направо +3. переместиться на клетку вперед и съесть яблоко, если оно есть в клетке + + +Формат входной файла +----- +В первой строке входного файла содержатся числа n l m, описание которых выше. Далее записаны n строк по n символов в каждой, которые описывают тор. Символ '*' соответствует наличию яблока, '.' - отсутствию. Должно быть гарантировано, что в левой верхней клетке тора нет яблока! +Примеры входного файла можно посмотреть в папке './tests/'. + +Формат выхода +----- +В первой строке выводится имя файла, поданного на вход. +Во второй строке выводится номер стартового состояния. В следующих l строках описываются состояния автомата в формате t0 t1 a0 a1, где t0 и a0 - номер состояния, в которое нужно перейти, если яблока перед муравьем нет, и действие, которое совершает муравей на данном переходе, а t1 и a1 - номер состояния, в которое нужно перейти, если перед муравьем есть яблоко, и действие, которое совершает муравей на данном переходе. + +Usage: +----- + python ./main.py + +Использованая литература +----- +http://is.ifmo.ru/download/ant_ga_min_number_of_state.pdf +http://rudocs.exdat.com/docs/index-229491.html \ No newline at end of file diff --git a/kesarev/SMART_ANT.py b/kesarev/SMART_ANT.py index 13e10d2..976db78 100755 --- a/kesarev/SMART_ANT.py +++ b/kesarev/SMART_ANT.py @@ -4,7 +4,7 @@ import STATE class SMART_ANT: - def __init__(self, generationSize, survived, genomeSize, maxStep, mapSize, apples, map): + def __init__(self, generationSize, survived, genomeSize, maxStep, mapSize, apples, tMap): random.seed(None) self.generationSize = generationSize self.genomeSize = genomeSize @@ -13,7 +13,7 @@ def __init__(self, generationSize, survived, genomeSize, maxStep, mapSize, apple self.maxStepToAnt = maxStep self.sizeOfMap = mapSize self.appleNumber = apples - self.torMap = map + self.torMap = tMap self.survivedAnts = survived self.generationNumber = 0 @@ -46,15 +46,12 @@ def makeMachine(self): def makeLittleShake(self): gs = int(len(self.generation) / 10) for i in range(gs, len(self.generation)): - self.generation[i] = ANT.ANT(self.genomeSize) + self.generation[i] = ANT.ANT(self.genomeSize) print("Little Shake!\n") def makeBigShake(self): for i in range(0, len(self.generation)): - #if random.randint(0, 1) == 0: - # self.makeMutation(i) - #else: - self.generation[i] = ANT.ANT(self.genomeSize) + self.generation[i] = ANT.ANT(self.genomeSize) print("BIG SHAKE!\n") def makeMutation(self, a): diff --git a/kesarev/STATE.py b/kesarev/STATE.py index 710487f..e1a8514 100755 --- a/kesarev/STATE.py +++ b/kesarev/STATE.py @@ -7,8 +7,8 @@ def __init__(self, out0 = 0, out1 = 0, action0 = 3, action1 = 3): self.actionToMove0 = action0 self.actionToMove1 = action1 - def getOutState(self, id): - return self.outState0 if (id == 0) else self.outState1 + def getOutState(self, i): + return self.outState0 if (i == 0) else self.outState1 - def getAction(self, id): - return self.actionToMove0 if (id == 0) else self.actionToMove1 + def getAction(self, i): + return self.actionToMove0 if (i == 0) else self.actionToMove1 diff --git a/kesarev/main.py b/kesarev/main.py index be54233..0a3cd50 100755 --- a/kesarev/main.py +++ b/kesarev/main.py @@ -1,27 +1,28 @@ __author__ = 'derketzer' import SMART_ANT +import sys def main(): - file_name = "tests/t1.txt" - file = open(file_name, 'r') + file_name = sys.argv[1] + input_file = open(file_name, 'r') generationSize = 1000 survivedSize = 100 apples = 0 - s = file.readline() + s = input_file.readline() s = s.split(' ') mapSize = int(s[0]) genomeSize = int(s[1]) maxStep = int(s[2]) - map = [[0 for j in range(0, mapSize)] for i in range(0, mapSize)] + torMap = [[0 for j in range(0, mapSize)] for i in range(0, mapSize)] for i in range(0, mapSize): - s = file.readline() + s = input_file.readline() for j in range(0, mapSize): c = s[j] - map[i][j] = 1 if (c == '*') else 0 - apples += map[i][j] - - smart_ant = SMART_ANT.SMART_ANT(generationSize, survivedSize, genomeSize, maxStep, mapSize, apples, map) + torMap[i][j] = 1 if (c == '*') else 0 + apples += torMap[i][j] + input_file.close() + smart_ant = SMART_ANT.SMART_ANT(generationSize, survivedSize, genomeSize, maxStep, mapSize, apples, torMap) st = smart_ant.makeMachine() print(file_name) print(st.genome.startState) diff --git a/kesarev/tests/.DS_Store b/kesarev/tests/.DS_Store index e7a40b7..73b1764 100644 Binary files a/kesarev/tests/.DS_Store and b/kesarev/tests/.DS_Store differ