im looking to see how i can navigate through a non-recombinant binomial tree.
I have set up my tree as following:
enter image description here
def arbolno(t,S0,u,d):
S=[S0]
for i in range(1,2**(t+1)-1):
if i%2==0:
S.append(np.round(S[int(i/2-1)]*u,3))
elif i%2!=0:
S.append(np.round(S[int((i-1)/2)]*d,3))
return S
Now, I want to calculate a return from a holding period, lets say, n moments.
How can I index correctly, given my format of listing my nodes? For instance, if I define a return period of 2 moments in time, then, for instance, node number 14 would be compared with node 2.
I want to know a general formula if there is, in order to index through my list of nodes correctly.
Thanks!
Related
I am working on my senior thesis in economics, and one of the major problems is that an agent is trying to choose the strategy on a binary tree that maximizes utility (we use probability weighting, so ignore that the expected value of each bet is 0). The binary tree has 2^T - 1 nodes, where if an agent takes a bet, they have a 1/2 chance of getting 10 units and a 1/2 chance of losing 10 units. Then a strategy is essentially all of the bets they would be willing to take and the resulting probability/payoff end states.
Thus far, I've let strategies be a list of strategies (or probabilistic outcomes of the strategies). As such, the first strategy is
strategy[0] = [[-10,1/2],[10,1/2]],
where the first element of strategy[0] is the payout and then probability of an outcome. Here, the agent only takes the first bet and doesn't continue regardless of the outcome.
Then, the second strategy would split the first element of strategy[0] into two outcomes with half of the probability of the parent [-20,1/4],[0,1/4] and then adds the elements of strategy[0] that aren't being split, so
strategy[1] = [[-20,1/4],[0,1/4],[10,1/2]].
Here, the agent takes the first bet regardless and then only takes the second if they lose the first. Then, our goal is that to create an algorithm that generates every possible strategy for at most T bets.
Currently, I have a function that splits the i-th list element into two, signifying that the agent takes the bet at the given node, attached below
def split(strategy,i):
newstrat = []
node = strategy[i]
newnode1 = [node[0] - 10,node[1]/2]
newnode2 = [node[0] + 10,node[1]/2]
for j in range(len(strategy)):
if j != i:
newstrat += [prospects[j]]
else:
newstrat += [newnode1] + [newnode2]
return newstrat
So in as in our earlier example, we would have
strategy[1] = split(strategy[0],0),
strategy[2] = split(strategy[0],1),
strategy[3] = split(strategy[2],0], #the agent is willing to take bets at either node
and so on.
However, at the column where t = 3 < T, there are 4 nodes, and therefore 15 different combinations of choices whether or not to bet at one or more of the nodes. My question might be really elementary, but I am having trouble adding each strategy to the set of strategies in a way that allows me to continue building onto it for t = 4 and onward.
sorry for the complicated / confusing title.
Basically I'm trying to implement a system that helps with the sorting of documents with no known date of writing.
It consists of two inputs:
Input 1: A tuple, where the first element is the number of documents, N. The second element is the number of pairs of documents with a known writing order, L. (First document was written before the second document).
Input 2: A list of L tuples. Each tuple contains two elements (documents). The first document was written before the second document. Eg: (1 2), (3 4) means that document1 was written before document2 and document3 was written before document4.
Next, the software must determine if there is a way of sorting all documents chronologically, there can be three outputs:
Inconclusive - Means that the temporal organization of the documents is inconsistent and there is no way of sorting them.
Incomplete - Means that information is lacking and the system can't find a way of sorting.
In case the information is enough, the system should output the order in which the documents have been written.
So far, I have managed to take both inputs, but I do not know where to start in terms of sorting the documents. Any suggestions?
Here's my code so far (Python3):
LN = tuple(int(x.strip()) for x in input("Number of docs. / Number of known pairs").split(' '))
print(LN)
if (LN[1]) > (LN[0]**2):
print("Invalid number of pairs")
else:
A = ['none'] * LN[0]
for i in range(LN[0]):
t = tuple(int(x.strip()) for x in input("Pair:").split(' '))
A[i] = t
print(A)
I appreciate all suggestions :)
Build a directed graph. The inputs are the edges. Check for cycles which would indicate inconsistent input. Find the "leftmost" node, that is the node that doesn't have any edge to it, meaning nothing to its left. Multiple that are leftmost? Incomplete. Then, for each node in the graph, assign the index that equals the length of the longest path from the leftmost node. As there are no (directed) cycles, you could probably just do BFS starting at the leftmost node and at each step assign to the node the maximum of its current value and its value given from its parent. Then iterate through all nodes, and put the numbers in their corresponding indices. Two nodes have the same index assigned? Incomplete.
Objective: Given a coordinate X, find "n" nearest line-polygon for coordinate X, not just "n" nearest points. Example: https://i.imgur.com/qyxV2MF.png
I have a group of spatial line-polygons which can have more than 2 coordinates. Their coordinates are stored in a (scipy)KDtree to enable NN search.
First, I will query "i" number of nearest coordinates then look up the corresponding line-polygons-> "i" coordinates may not necessarily produce "i" lines.
In order to achieve "n" nearest lines, I will need to increase "i". My problem is that "i" can be unpredictable because the number of coords varies between every line-polygon. Example, a line-polygon can be represented by 2 coordinates, but another can be represented using 10 coordinates. Most of the time, I only need 2 nearest neighboring line-polygons from point X.
In the example image, I need line A and B as my result. Even with "i" = 3, only line A will be found because A1, A2, A3 are the nearest neighbors to X.
Question: Is there a way to group coordinates of a shape together and then carry out NN search to get "n" unique shapes? (besides brute forcing "i" to ensure "n" unique shapes)
Current workaround pseudocode:
found = []
while True:
if first_loop:
result = look up N nearest coords
else:
result = look up Nth nearest coord
look up shapes using result and append to found
perform de-duplication of found
if len(found) >= required:
return found
else:
N = N+1 # to check the Nth neighbor next iteration
If i understood your question correctly, it's a problem of having the right data-structures.
Let's have the following data-structures,
1. A dictionary from the line-polygons to points
2. Another dictionary from points to line-polygons (or equivalently a single bidirectional map from bidict instead of couple of dictionaries)
3. a boolean array visited with size equal to the number of points
Now the following algorithm should solve your problem (can be implemented efficiently with the above data structures):
For all the points initialize the visited array to be False.
Find the nearest point to the query point first from the kd-tree, mark the matched point and all the points from the the corresponding polygon the matched point belongs to as visited and return that particular polygon (id) as the nearest polygon (if there are multiple such polygons, return all of them).
Repeat step 2 until n such (distinct) polygons are returned. Consider a new point returned from the kd-tree as matched with the query point iff it's not yet visited (if a matched point returned by kd-tree is already visited, discard it and query the next nearest point matched). Once a point is visited, mark the point and all the points from the corresponding polygon(s) as visited and return the polygon(s).
I see two ways of doing this efficiently:
Index the complete "line-polygons": For this you could bound each line-polygon by a minimum bounding rectangle. Then index all the rectangles with an appropriate index structure like an R-Tree. Instead of points, you will have line-polygons on the lowest level, so you will have to adapt the distance for this case.
Use Distance Browsing: The idea here is to attach to each point the id of its line-polygon and index the points in an index structure (e.g., KD-Tree). Then you successively retrieve the next nearest point to your query using distance browsing. You proceed this until you have found points of n different line-polygons.
# stack_depth is initialised to 0
def find_in_tree(node, find_condition, stack_depth):
assert (stack_depth < max_stack_depth), 'Deeper than max depth'
stack_depth += 1
result = []
if find_condition(node):
result += [node]
for child_node in node.children:
result.extend(find_in_tree(child_node, find_condition, stack_depth))
return result
I need help understanding this piece of code. The question i want to answer is
The Python function above searches the contents of a balanced binary tree.
If an upper limit of 1,000,000 nodes is assumed what should the max_stack_depth constant be set to?
From what I understand, this is a trick question. If you think about it, stack_depth is incremented every time the find_in_tree() function is called in the recursion. And we are trying to find a particular node in the tree.So the worst case would be when we have to search through all the nodes in the tree before we find it. Hence, max_stack_depth should 1,000,000?
If you look at when stack_depth increments then it looks like we will increment every time we access a node. And in our case we are accessing every single node every time. Because there is no return condition when stops the algorithm when the correct node is found.
Can someone please try to explain me their thought process.
Instead of multiplying the number of nodes on each layer, you have to add them. For example, the number of nodes in the first four layers is 1+2+4+8=15, not 1*2*4*8=64.
# 1
# # + 2
# # # # + 4
# # # # # # # # + 8 = 15
In general, the number of nodes in the first n layers is 2**(n+1)-1. You can use logarithms to get the correct power and get the floor of that number. If you want fewer that that number, you would also have to subtract one from the power.
>>> math.floor(math.log(1000000, 2))
19
>>> sum(2**i for i in range(1, 20))
1048574
Concerning your edit: Yes, stack_depth is incremented with each node, but you are incrementing a local variable. The increment will carry to the child nodes (passed as a parameter) but not to the siblings, i.e. all the nodes at level n will be called with stack_depth == n-1 (assuming it started as 0 on the first level). Thus, max_stack_depth should be 19 (or 20 if it starts with 1) to visit the ~1,000,000 nodes in the first 19 levels of the tree.
Straightforward question: I would like to retrieve all the nodes connected to a given node within a NetworkX graph in order to create a subgraph. In the example shown below, I just want to extract all the nodes inside the circle, given the name of one of any one of them.
I've tried the following recursive function, but hit Python's recursion limit, even though there are only 91 nodes in this network.
Regardless of whether or not the below code is buggy, what is the best way to do what I'm trying to achieve? I will be running this code on graphs of various sizes, and will not know beforehand what the maximum recursion depth will be.
def fetch_connected_nodes(node, neighbors_list):
for neighbor in assembly.neighbors(node):
print(neighbor)
if len(assembly.neighbors(neighbor)) == 1:
neighbors_list.append(neighbor)
return neighbors_list
else:
neighbors_list.append(neighbor)
fetch_connected_nodes(neighbor, neighbors_list)
neighbors = []
starting_node = 'NODE_1_length_6578_cov_450.665_ID_16281'
connected_nodes = fetch_connected_nodes(starting_node, neighbors)
Assuming the graph is undirected, there is a built-in networkx command for this:
node_connected_component(G, n)
The documentation is here. It returns all nodes in the connected component of G containing n.
It's not recursive, but I don't think you actually need or even want that.
comments on your code: You've got a bug that will often result an infinite recursion. If u and v are neighbors both with degree at least 2, then it will start with u, put v in the list and when processing v put u in the list and keep repeating. It needs to change to only process neighbors that are not in neighbors_list. It's expensive to check that, so instead use a set. There's also a small problem if the starting node has degree 1. Your test for degree 1 doesn't do what you're after. If the initial node has degree 1, but its neighbor has higher degree it won't find the neighbor's neighbors.
Here's a modification of your code:
def fetch_connected_nodes(G, node, seen = None):
if seen == None:
seen = set([node])
for neighbor in G.neighbors(node):
print(neighbor)
if neighbor not in seen:
seen.add(neighbor)
fetch_connected_nodes(G, neighbor, seen)
return seen
You call this like fetch_connected_nodes(assembly, starting_node).
You can simply use a Breadth-first search starting from your given node or any node.
In Networkx you can have the tree-graph from your starting node using the function:
bfs_tree(G, source, reverse=False)
Here is a link to the doc: Network bfs_tree.
Here is a recursive algorithm to get all nodes connected to an input node.
def create_subgraph(G,sub_G,start_node):
sub_G.add_node(start_node)
for n in G.neighbors_iter(start_node):
if n not in sub_G.neighbors(start_node):
sub_G.add_path([start_node,n])
create_subgraph(G,sub_G,n)
I believe the key thing here to prevent infinite recursive calls is the condition to check that node which is neighbor in the original graph is not already connected in the sub_G that is being created. Otherwise, you will always be going back and forth and edges between nodes that already have edges.
I tested it as follows:
G = nx.erdos_renyi_graph(20,0.08)
nx.draw(G,with_labels = True)
plt.show()
sub_G = nx.Graph()
create_subgraph(G,sub_G,17)
nx.draw(sub_G,with_labels = True)
plt.show()
You will find in the attached image, the full graph and the sub_graph that contains node 17.