Python list of lists specific path combinations or permutations

2024/7/8 6:51:27

I have a list of lists and am looking for something similar to combinations or permutations, but there are conditions that may result in good "Path" or "Dead_End". If "Dead_End", it should index to the next choice in the list. Example:

AList = [[1, 2, 3],[2, 0, 3],[3, 1, 0],[1, 0, 2]]N = 0
Index = 0
#AList[N][Index]=1,  AList[2][2]=0

I would like to start with the value AList[N][Index], which at the start is [0][0] and therefore equals 1 and assign that to N. After N is assigned 1, we can never go back to that List and the Path = [1].

Then I would have AList[N][Index], which is AList[1][0] and that equals 2. Assign that to N. Path.append(N) and I would have Path = [1, 2].

AList[N][Index] would next equal 3, N = 3, and Path would become [1, 2, 3]

Now AList[N][Index] would equal 1. This would be a Dead_Path and not a good solution because 1 is already in Path and we can't go back to it. So I want to index over to the next choice in the list. Index = Index + 1. That would result in AList[N][Index] = 0. Path = [1, 2, 3, 0]

That is a good Path and there are many good Paths and many Dead_Ends. For example, another good Path would be Path = [1, 0, 2, 3].

Is this a multi-nested IF, For, While loop scenario or is there an itertools function to test out all of the Paths and Dead_Ends? And the List of list could be more complicated and not uniform to create even more Dead_Ends, like:

BList = [[1, 4, 3],[2, 0, 3, 4],[3, 4, 0],[1, 2],[3, 2, 1, 0]]

Edited: I couldn't deal with all of the Dead_Ends. All of the loops and indexing got me confused, so I think the best solution is that I use itertools and list all path combinations and allow revisiting back to previous node. Then I would use set() function to eliminate the lists that revisited a node. In the end, I'm left with Perfect_Paths hitting each node once. I don't know if this is the fastest / cleanest, but it worked. Code below:

Perfect_Path = list()
i = 0 All_Paths = list(itertools.product(*Alist))for i in range(len(All_Paths)):if len(set(All_Paths[i])) == len(Alist):  #filter out paths that revisited a node, which means it would have same number repeated in listPerfect_Path.append(All_Paths[i])print ("The perfect paths are ", Perfect_Path)

Edit: Well my code above works for a small Alist, but to itertools all combinations for a slightly larger list, say 10 data nodes all of a sudden becomes millions of paths. And then I have to set() them to eliminate choices. Back to the drawing board for me.

Answer

Reading through the text of the question again and again I detected two variants of rules for finding the right answer and will provide here both of them without asking which one is the one OP had in mind asking the question.

Let's start with the easy one. The path through the elements of the matrix can jump from one element to any other element and the only restriction for the path is that there are no same values in the path allowed. This makes it very easy to find all paths through the values of the matrix and it goes as follows:

Step1: make out of all of the matrix values a flat set with unique values

Step2: create all possible permutations of this set

Let's demonstrate with code that this variant works even on a quite large matrix:

theMatrix = [[1, 1, 3, 2, 1, 3, 3, 3, 2, 1, 1, 3],[1, 2, 1],[2, 3, 3, 1, 3, 3, 2, 1, 1, 1, 3, 3, 1, 3, 3],[3, 1, 3, 1, 2],[2, 3, 3, 1, 3, 3, 2, 1, 1, 1, 3],[1, 2],[1, 2, 1],[2, 3, 3, 1, 3, 3, 1, 1, 3, 3, 1, 3, 3],[3, 1, 3, 1, 2],[2, 3, 3, 1, 3, 3, 2, 1, 1, 1, 3],[1, 2],[2, 3, 3, 1, 3, 3, 1, 1, 3, 3, 1, 3, 3],[3, 1, 3, 1, 2],[2, 3, 3, 1, 3, 3, 2, 1, 1, 1, 3],[3, 2, 1, 3, 1]]
setOnlyDifferentMatrixValues = set()
for row in range(len(theMatrix)):for column in range(len(theMatrix[row])):setOnlyDifferentMatrixValues.add(theMatrix[row][column])
from itertools import permutations
allPossiblePaths = permutations(setOnlyDifferentMatrixValues)
print(list(allPossiblePaths))

The code above outputs:

[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

Now the more complex variant with more lines of code. The code is necessary, because there are more restrictions there and the path can go only through matrix elements which are neighbors (horizontal, vertical and diagonal). In this case not all paths have the same length and the same elements in them:

def getAllValidPathsFrom(myMatrix): 
# def getDictRepresentationOf(myMatrix):dctOfMatrix = {}for row in range(len(myMatrix)):for column in range(len(myMatrix[row])):currPoint = (column, row)dctOfMatrix[currPoint] = myMatrix[row][column]lstIndicesOfAllMatrixPoints = list(dctOfMatrix.keys())setAllPossiblePaths = set()from itertools import permutationspermutationsIndicesOfAllMatrixPoints = permutations(lstIndicesOfAllMatrixPoints)cutBranchAt = ()sizeOfCutBranch = 0for pathCandidate in permutationsIndicesOfAllMatrixPoints: # print(pathCandidate, type(pathCandidate))if sizeOfCutBranch > 0:# print( "sizeOfCutBranch > 0", cutBranchAt )cutBranchAt = tuple(cutBranchAt)while cutBranchAt == pathCandidate[0:sizeOfCutBranch]:try:pathCandidate = next(permutationsIndicesOfAllMatrixPoints)except:breaklstPossiblePath = []prevIndexTuple = pathCandidate[0]lstPossiblePath.append(prevIndexTuple)for currIndexTuple in pathCandidate[1:]:if (abs(currIndexTuple[0]-prevIndexTuple[0]) > 1) or (abs(currIndexTuple[1]-prevIndexTuple[1]) > 1) :sizeOfCutBranch = len(lstPossiblePath)+1cutBranchAt = tuple(lstPossiblePath+[currIndexTuple])break # current path indices not allowed in path (no jumps)else:if dctOfMatrix[currIndexTuple] in [ dctOfMatrix[index] for index in lstPossiblePath ] : sizeOfCutBranch = len(lstPossiblePath)+1cutBranchAt = tuple(lstPossiblePath+[currIndexTuple])break # only values different from all previous are allowed else:sizeOfCutBranch = 0cutBranchAt = ()lstPossiblePath.append(currIndexTuple)prevIndexTuple = currIndexTupleif len(lstPossiblePath) > 1 and tuple(lstPossiblePath) not in setAllPossiblePaths: setAllPossiblePaths.add(tuple(lstPossiblePath))return setAllPossiblePaths, dctOfMatrix
#:def getAllValidSkiingPathsFromtheMatrix = [[3, 1, 3],[1, 1],[1, 2, 1, 3]]lstAllPossiblePaths, dctOfMatrix = getAllValidPathsFrom(theMatrix)
setDifferentPossiblePaths = set(lstAllPossiblePaths)
setTpl = set()
for item in setDifferentPossiblePaths:lstTpl = []for element in item:lstTpl.append(dctOfMatrix[element])setTpl.add(tuple(lstTpl))
print(setTpl)

The code above runs over a small matrix as the large one would kill it computationally. Because of special arrangement of values in the small matrix it is possible to demonstrate here that not all permutations are generated because of the more restrictive rules for building the path. Let's compare the outputs for the variant one and the variant two of the answer:

[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]{(1, 2), (1, 3), (2, 1, 3), (3, 1), (2, 1), (3, 1, 2)}

Because in the second variant the path has to go through adjacent matrix elements not all permutations of the longest path are there and there are also shorter paths included.

https://en.xdnf.cn/q/120361.html

Related Q&A

Python packages.import sys vs from sys import argv

Im trying to use argv into my python script. For this im using following code:from sys import argv script, file_name = argv print(file_name)python3 e.py e.txt This code works fine.But when I use:import…

How to reorganize a list of tuples?

Say I had a list of tuples:[(98, studentA), (97, studentB), (98, studentC), (95,studentD)]And I wanted to organize it so that the students are grouped together by the first number in the tuple, what wo…

How to loop through json data with multiple objects

My json file data.json looks like this [ {"host" : "192.168.0.25", "username":"server2", "path":"/home/server/.ssh/01_id"}, {"host"…

python django only the first statement statement can be accessed

i can acccess only the first statement in my name appjavascript:<script type="text/javascript">function searched(){{% for names in name %}nameSearched = document.getElementById(name).va…

syntax error return outside function in python

I am trying to count the word fizz using python. However it is giving me an error.def fizz_count(x):count =0 for item in x :if item== "fizz":count=count+1 return countitem= ["fizz",…

How to replace values in multidimensional array?

I am trying to get a multidimensional array working, where the user string is filled in the cell. I have been searching for ways to update user values in the multidimensional array def createMultiArr…

How to deploy a python docker image to AWS Lambda?

I am trying to figure out how to deploy a flask application that I have received with a Dockerfile to AWS Lambda.In local, all I have to do to start the app is to enter docker-compose up. Thats work gr…

How to isolate titles from these image URLs?

I have a list of image urls contained in images. I am trying to isolate the title from these image urls so that I can display, on the html, the image (using the whole url) and the corresponding title. …

Columns and rows concatenation with a commun value in another column

In the below mentioned table, I want to concatenate the columns Tri_gram_sents and Value together and then all rows which has the same number in column sentence.Tri_gram_sents Value …

Python Indentation Error [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.This question was caused by a typo or a problem that can no longer be reproduced. While similar q…