How to try all possible paths? - python

I need to try all possible paths, branching every time I hit a certain point. There are <128 possible paths for this problem, so no need to worry about exponential scaling.
I have a player that can take steps through a field. The player
takes a step, and on a step there could be an encounter.
There are two options when an encounter is found: i) Input 'B' or ii) Input 'G'.
I would like to try both and continue repeating this until the end of the field is reached. The end goal is to have tried all possibilities.
Here is the template, in Python, for what I am talking about (Step object returns the next step using next()):
from row_maker_inlined import Step
def main():
initial_stats = {'n':1,'step':250,'o':13,'i':113,'dng':0,'inp':'Empty'}
player = Step(initial_stats)
end_of_field = 128
# Walk until reaching an encounter:
while player.step['n'] < end_of_field:
player.next()
if player.step['enc']:
print 'An encounter has been reached.'
# Perform an input on an encounter step:
player.input = 'B'
# Make a branch of player?
# perform this on the branch:
# player.input = 'G'
# Keep doing this, and branching on each encounter, until the end is reached.
As you can see, the problem is rather simple. Just I have no idea, as a beginner programmer, how to solve such a problem.
I believe I may need to use recursion in order to keep branching. But I really just do not understand how one 'makes a branch' using recursion, or anything else.
What kind of solution should I be looking at?

You should be looking at search algorithms like breath first search (BFS) and depth first search (DFS).
Wikipedia has this as the pseudo-code implementation of BFS:
procedure BFS(G, v) is
let Q be a queue
Q.enqueue(v)
label v as discovered
while Q is not empty
v← Q.dequeue()
for all edges from v to w in G.adjacentEdges(v) do
if w is not labeled as discovered
Q.enqueue(w)
label w as discovered
Essentially, when you reach an "encounter" you want to add this point to your queue at the end. Then you pick your FIRST element off of the queue and explore it, putting all its children into the queue, and so on. It's a non-recursive solution that is simple enough to do what you want.
DFS is similar but instead of picking the FIRST element form the queue, you pick the last. This makes it so that you explore a single path all the way to a dead end before coming back to explore another.
Good luck!

Related

Is there a way to use a programmatic debugger in python?

I'm trying to animate every step of some code programmatically like in this video(code here). Basically, I want to visualize every step of the algorithm for a given input.
Doing the animations is trivial, but if you look at the code, the author does everything by hand. I'm trying to do this programmatically, so at every step, I need the current line, some variables, call hierarchy etc. so I can make the animations work.
For example, let's say bfs.py contains the following:
def bfs(G, v):
def visit(v):
pass #print(v)
visited = [False] * len(G)
queue = [v]
while len(queue) > 0:
v = queue.pop(0)
if not visited[v]:
visit(v)
visited[v] = True
for w in G[v]:
if not visited[w]:
queue.append(w)
And I want to do something similar to the video without modifying this code: I run this from inside a different file in a way that enables stepping and peeking in the way I want.
I tried Pdb but it forces interactivity, and I couldn't find a way to use it how I want to. I also tried nopdb, but it seems very complicated to use it for my purposes, so before further work, I'd like to explore other options.

How do I stop my backtracking algorithm once I find and answer?

I have wrote this code for solving a problem given to me in class, the task was to solve the "toads and frogs problem" using backtracking. My code solves this problem but does not stop once it reaches the solution (it keeps printing "states" showing other paths that are not a solution to the problem), is there a way to do this?. This is the code:
def solution_recursive(frogs):
#Prints the state of the problem (example: "L L L L _ R R R R" in the starting case
#when all the "left" frogs are on the left side and all the "right" frogs are on
#the right side)
show_frogs(frogs)
#If the solution is found, return the list of frogs that contains the right order
if frogs == ["R","R","R","R","E","L","L","L","L"]:
return(frogs)
#If the solution isn't the actual state, then start (or continue) recursion
else:
#S_prime contains possible solutions to the problem a.k.a. "moves"
S_prime = possible_movements(frogs)
#while S_prime contains solutions, do the following
while len(S_prime) > 0:
s = S_prime[0]
S_prime.pop(0)
#Start again with solution s
solution_recursive(s)
Thanks in advancement!
How do I stop my backtracking algorithm once I find an answer?
You could use Python exception facilities for such a purpose.
You could also adopt the convention that your solution_recursive returns a boolean telling to stop the backtrack.
It is also a matter of taste or of opinion.
I'd like to expand a bit on your recursive code.
One of your problems is that your program displays paths that are not the solutions. This is because each call to solution_recursive starts with
show_frogs(frogs)
regardless of whether frogs is the solution or not.
Then, you say that the program is continuing even after the solution has been found. There are two reasons for this, the first being that your while loop doesn't care about whether the solution has been found or not, it will go through all the possible moves:
while len(S_prime) > 0:
And the other reason is that you are reinitializing S_prime every time this function is called. I'm actually quite amazed that it didn't enter an infinite loop just checking the first move over and over again.
Since this is a problem in class, I won't give you an exact solution but these problems need to be resolved and I'm sure that your teaching material can guide you.

How does Python stops itself a recurence?

Imagine I calculate the Fibonacci sequence following the (obviously inefficient) recursive algorithm :
def Fibo(n):
if n <= 1:
return(n)
else:
return(Fibo(n-2) + Fibo(n-1))
then my question is : how does Python known it has to stop the recurrence at n=0 ?
After all, if I call Fibo(-12), Python obviously answers -12, so why does it stop the recursion at n=0 while calling Fibo(12) for instance ?
Edit after a few comments :
This question has nothing to do with the mathematical concept of recurrence. I know recurrence stops at the initialized point. I would like to understand how recurrence are implemented in computer. For me ti is absolutely not clear while a computer should stop while there is no explicit stop command. What prevents here Fibo(0)=Fibo(-1)+Fibo(-2) to continue endlessly ? Because after all I precised that Fibo(-1)=-1, Fibo(-2)=-2, ... and I might want to summ all negative numbers as well ...
I confess in the last case I would prefer do a while loop.
It's functional, so it doesn't run, so it also doesn't stop. You are (still) thinking in terms of iterative programming and assume some kind of loop here which needs to stop at some time. This is not the case.
Instead in this paradigm you just state that the return value is the sum of the prior two numbers. At this point you don't care how the prior numbers are produced, here you just assume that they already exist.
Of course they don't and you will have to compute them as well but still this is not a loop which needs a stop. Instead it is a recursion which has an anchor. With each recursion step the values will become smaller and smaller and once they reach a value below 2 you just return 0 or 1 without any further recursion. This is your anchor.
Feel free to think of it as a "stopping point" but be aware that there is no loop happening which you need to break out of or similar.

How can I avoid recursion between move generation and check validation in python chess implementation?

I'm currently working on a simple python 3 implementation of a chess game where legal moves can be calculated and things like check, checkmate, and stalemate can be determined. I've encountered a logic error which results in recursion and I'm not sure how I change my current approach to avoid this.
I've got some pseudo-code here (my actual code several hundred lines long and it would be impractical to paste it all for a logic problem).
Where am I going wrong with my thought process behind this code?
class ChessBoard:
def get_position():
# returns fen of position
def set_position(position_code):
# sets the board's position and values using the fen code given
# assume its white's turn right now
def calculate_moves():
# uses vectors to calculate moves for all pieces
for each_move in candidate_moves:
if passes_all_general_conditions:
# now I need to check if the potential
# legal move will leave the user in check
# obviously if the white king can be taken in the next turn
# by the other color then the move cannot be considered legal
temp_board = ChessBoard()
temp_board.set_position(self.get_position())
temp_board.make_move(the_selected_move_that_needs_checking)
if not temp_board.incheck():
# add move to list of legal moves
def incheck():
# player is in check if a piece can take it on the next turn
# don't I need to know what moves can be made before I can know if its check??
# let k equal the current turn (or half-turn as chess players call it)
# in order to calculate the moves for position at turn k
# the moves for position k + 1 must be known
# obviously this just enters infinite recursion
It looks like incheck() is not implemented. The default return value of a python method is the None type.
>>> not None == True
True
So the deepest-nested conditional in your loop always evaluates to True.
I appreciate that you didn't copy paste you whole code, but it would have been useful to at least show SOME part of it, in order to fix your issue.
Since I cannot debug your code without seeing it, I will just make a guess:
I think you use calculate_moves() in incheck(), and incheck to verify wether calculated_moves are legal ones.
If you do that, you have got two options:
-Split calculate_moves into two functions: one generates pseudo legals, and the other then controls these pseudolegals on legality. You will just ave to replace calculate_moves() in incheck() by calculate_pseudolegals(). This approach is a little bit inefficient though.
-The more efficient solution is to fully delete your incheck() routine and write a new, efficient one. There you would replace the king you wish to test on check by every figure of its own color onece, and then test if it could hit a figure of the same type of the opponent. If it can, your king is in check. Be aware that you will still need a calculate_pseudolegals() function for this to work.

Solving a programming-contest using Python [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I found this problem, which I thought would be interesting to solve but couldn't really come up with a correct solution-
Inside a room, there is a monster with
N heads, and a human (with 1 head).
The human has two laser guns. The
first gun, A destroys C1 heads when
fired and the second gun,B destroys C2
heads when fired [The guns may destroy
both the monster's as well as human
heads, but the guns prioritize monster
heads over human ones].
Also, if after the firing of the gun
the monster has a positive non-zero
number of heads left, the monster will
grow additional heads. The monster
grows G1 heads when gun A is used and
it grows G2 heads when gun B is used.
The problem is to input N, C1, C2, G1
and G2, then find out what would be
the shortest combination of
gun-choice(A or B) the human must use
to kill the monster(the monster dies
when No. of heads=0).
[Note- this problem is from a programming contest that has already ended]
I tried approaching this problem using recursion but found myself clueless about how to actually come up with the solution. So, if you could give some hints how to approach the problem, that'd be great.
First of all: Dijkstra's is not the optimal solution :)
Given this sentence: "The guns may destroy both the monster's as well as human heads"
I take it if you can shoot 10 heads and the monster only has 5 heads, you can't kill it because that would kill you too. Is that correct?
In any case, any solution would be of the form:
ABABAABBABBB... (some string of A's and B's)
On the final hit you kill C1 or C2 heads. On every other hit you kill C1 - G1 or C2 - G2 heads.
If the final hit is from A, you have to destroy N-A heads with shots doing (C1-G1) or (C2-G2) damage.
If the final hit is from B, you have to destroy N-B heads with shots doing (C1-G1) or (C2-G2) damage.
Any K can be represented in the form:
X*i + Y*j = K
Of course, X and Y have to be coprime, etc.
K heads can be destroyed by i shots of damage X and j shots of damage Y.
You can find out the values of i and j with the extended greatest common divisor algorithm.
Solve for X = (C1-G1), Y = (C2-G2) and K = (N-A)
Also solve for X = (C1-G1), Y = (C2-G2) and K = (N-B)
The smallest answer is the correct one :)
That's it :)
Ah, I see you have found a solution in C++ already using Dijkstra's algorithm: http://hashsamrat.blogspot.com/2010/10/surviving-monster-programming-problem.html
However, you seem to be thinking about 'recursion' and other methods.
The solution is separate than the implementation. Thus what you really want to do would be to use the same algorithm (Dijkstra's, which is just breadth-first search carefully done so you visit the shortest paths first), but in python rather than C++.
You could just copy the C++ line-by-line, using python idioms to make the code cleaner and more elegant. But you'll still be using the same algorithm. (Alternatively, you could Google for the hundreds of ways people have implemented Dijkstra's in python. Or you could write it yourself; all you need is a priority queue (see wikipedia), and if time isn't an issue, you can write a poorly-performing priority queue in the form of a dictionary-of-lists.)
edit: Thinking about it, if by "shortest set of choices" you just mean "fewest gunshots", you don't really need Dijkstra's at all; it's just breadth-first-search (which is equivalent to Dijkstra's when all edges have weight 1).
In particular, the logic to generate a new node is as follows:
def howManyHeadsLeft(currentHeads, damage, regen):
newHeads = heads - damage
if {this results in blowing off our own head} and newHeads>0: #modify depending on assumptions
# we killed ourselves without taking monster down with us
return {} # the empty set of possible search nodes
else:
newHeads += regen
# we could just say return {newHeads} here,
# but that would be terribly slow to keep on searching the same
# state over and over again, so we use a cache to avoid doing that
# this is called dynamic programming
if {we have never seen newHeads before}:
return {newHeads}
else
return {}
def newSearchNodes(currentHeads):
return howManyHeadsLeft(currentHeads, atypeDamage, atypeRegen) | howManyHeadsLeft(currentHeads, btypeDamage, btypeRegen)
The 'goal' condition for the search is having just enough damage to kill the hydra without killing yourself (modify as appropriate depending on assumptions):
heads==1+atypeDamage or heads==1+btypeDamage
Of course it is also possible that no solution exists (regen > damage for both types of guns), in which case this algorithm might run forever, but could probably be modified to terminate.

Categories