Как закодировать «Если существует только одна переменная» в поисковом «алгоритме»?

#python #arrays #numpy

#python #массивы #numpy

Вопрос:

Я использую «алгоритм» поиска по сетке «своими руками», который начинается в левом верхнем углу и заканчивается в правом нижнем углу. Мой «алгоритм» может перемещаться только ВПРАВО и ВНИЗ, он смотрит на своих соседей и видит, какой из них наименьший, и переходит к наименьшему. Если оба соседа равны, его приоритеты снижаются. Ниже приведен мой код:

 import numpy as np
import random

# Create grid with random integers from 0 to 9
width, height = 10, 10
np.random.seed(0)
grid = np.random.randint(0, 10, size=(width, height))

# Agent actions
goal = grid[-1][-1] # Row, Column

# Check mechanism
print(grid)
print(goal)
 
 def rightdown():
    x, y = 0, 0
    current_pos = grid[x][y]
    steps = [grid[0][0]]
    print("Initial pos: ", current_pos)
    
    
    for i in range(16): 
        if grid[x   1][y] < grid[x][y   1]: # Go Right
            current_pos = grid[x   1][y]
            
            x  = 1
            
        elif grid[x   1][y] > grid[x][y   1]: # Go Down
            current_pos =  grid[x][y   1]
            
            y  = 1
            
        elif grid[x   1][y] == grid[x][y   1]: # Go Down if same
            current_pos = grid[x][y   1]
    
            x  = 1
           
        elif grid[0][9] or grid[1][9] or grid[2][9] or grid[3][9] or grid [4][9] or grid [5][9] or grid [6][9] or grid [7][9] or grid [8][9] or grid [9][9]:
            print('right hit')
            
        elif grid[9][0] or grid[9][1] or grid[9][2] or grid[9][3] or grid [9][4] or grid [9][5] or grid [9][6] or grid [9][7] or grid [9][8] or grid [9][9]:
            print('bott hit')
        
        print('Current position: ', current_pos)
        print('This is x, y: ', x, ',', y, 'n')    
        
        steps.append(current_pos)

    
    print('Total steps taken: ', sum(steps))
        
        
rightdown()
 

Мой вопрос: я хочу сделать так, чтобы, как только он достигнет конца массива (например. Правильно), он будет только снижаться. Однако как мне это закодировать? На английском языке это означало бы, что если существует только правильный массив, переместитесь вниз, а не если существуют оба right и down.

EDIT_1: я отредактировал код, чтобы увидеть, достигает ли позиция счетчика либо нижней строки, либо крайнего правого столбца, однако следующий код теперь выдает ошибку:

индекс 10 выходит за пределы оси 0 с размером 10

Чтобы обойти это, измените диапазон от 16 до 15 или меньше. 16 использовался, потому что он повторяется до следующего числа.

для i в диапазоне (15):

Почему следующий код не выводит «правый удар», когда он находится в следующей позиции [6] [9]?

Комментарии:

1. Сравните x и y с width и height , может быть?

2. Извините @TigerhawkT3, я не понимаю, что вы имеете в виду под этим?

3. x и y являются текущими значениями, представляющими ваше местоположение при переходе по сетке. width и height являются максимальными значениями, представляющими размеры сетки. Если текущие значения достигают максимального значения, значит, вы попали в конец сетки в этом направлении.

4. Я изучил возможность добавления нового оператора elif: ‘elif grid [x] [-y]:’, однако он никогда не достигает этого условия, и я понятия не имею, почему. Итак, я отредактировал его для определенных значений, но все равно не выполняет условие. Есть идеи, почему? Мой приведенный выше код отражает то, что я сделал.

5. ширина = 10, индексы равны 0 … 9 . вы можете пойти правильно, только если x 1 будет еще меньше ширины — если x 1 == 10, вы получаете ошибку индекса при следующих проверках.

Ответ №1:

В вашем коде есть несколько особенностей:

  • вам нужно контролировать свои индексы, чтобы они не пытались получить доступ за пределы вашего заданного массива
  • вам нужно проверить, можете ли вы продвигать индексы или выходить за пределы при перемещении
  • единственный раз, когда сравниваются значения по индексу, — это когда решается, куда двигаться дальше: elif grid[0][9] or grid[1][9] .... or grid [9][9]: print('right hit') обращается к значениям и проверяет, не соответствует ли какое-либо из них действительности — он не проверяет indexpositions
  • sum of steps() будут суммироваться все посещенные значения, а не количество шагов (может быть преднамеренным)

Вы могли бы исправить это следующим образом:

 def rightdown(g):
    row, column, (max_row, max_column) = 0, 0, g.shape

    print(g)
    last_pos = -1,-1
    current_pos = row,column
    current_value = g[row][column]
    steps = [current_value]

    def p(): #  printer function called twice later: dry - don't repeat yourself
        msg = "hit bottom" if row 1 == max_row else (
            "hit right" if column 1 == max_column else "")
        print("Pos:", current_pos, "  Value:", g[row][column], msg)
      
    while current_pos != (max_row - 1, max_column - 1):
        p()
        if row 1 < max_row and column 1 < max_column:
            vd = g[row   1][column]
            vr = g[row][column   1]

            if vd <= vr:
                row  = 1
            else:
                column  = 1
        elif row 1 == max_row:
            column  = 1
        elif column 1 == max_column:
            row  = 1

        steps.append(g[row][column])
        last_pos, current_pos = current_pos, (row, column)

    p()
    print('Steps', steps, 'taken: ', len(steps), "sum:", sum(steps))
 

Вызовите его с помощью:

 import numpy as np
import random

# Create grid with random integers from 0 to 9
width, height = 10, 10
np.random.seed(0)
grid = np.random.randint(0, 10, size=(width, height))
print(grid)

rightdown(grid)
 

Вывод:

 [[5 0 3 3 7 9 3 5 2 4]
 [7 6 8 8 1 6 7 7 8 1]
 [5 9 8 9 4 3 0 3 5 0]
 [2 3 8 1 3 3 3 7 0 1]
 [9 9 0 4 7 3 2 7 2 0]
 [0 4 5 5 6 8 4 1 4 9]
 [8 1 1 7 9 9 3 6 7 2]
 [0 3 5 9 4 4 6 4 4 3]
 [4 4 8 4 3 7 5 5 0 1]
 [5 9 3 0 5 0 1 2 4 2]]
Pos: (0, 0)   Value: 5
Pos: (0, 1)   Value: 0
Pos: (0, 2)   Value: 3
Pos: (0, 3)   Value: 3
Pos: (0, 4)   Value: 7
Pos: (1, 4)   Value: 1
Pos: (2, 4)   Value: 4
Pos: (3, 4)   Value: 3
Pos: (3, 5)   Value: 3
Pos: (4, 5)   Value: 3
Pos: (4, 6)   Value: 2
Pos: (5, 6)   Value: 4
Pos: (5, 7)   Value: 1
Pos: (5, 8)   Value: 4
Pos: (6, 8)   Value: 7
Pos: (6, 9)   Value: 2 hit right
Pos: (7, 9)   Value: 3 hit right
Pos: (8, 9)   Value: 1 hit right
Pos: (9, 9)   Value: 2 hit bottom
Steps [5, 0, 3, 3, 7, 1, 4, 3, 3, 3, 2, 4, 1, 4, 7, 2, 3, 1, 2] taken: 19 sum: 58