Itertools.permutations create n random solutions to the TSP - python

I'm working on a script which creates random solutions to the traveling salesman problem. I have a set of cities, as well as a set of distances (which I not yet need since I'm creating random solutions).
I am attempting to use Itertools.permutations on the list of cities in order to create unique routes. My questions are:
Is there any way in which I can make Itertools.permutations generate random solutions? Right now, it starts with cities[0]->cities[1]->cities[2] and so on. Can I randomize this?
Can I make itertools generate only n permutations before returning? I have a list of 29 cities, and as you might have guessed that's a whole lot of permutations!
Thanks in advance!

This Python code will generate the permutations based on a random starting point and will stop after 6 permutations:
from itertools import permutations
from random import shuffle
A=range(26)
shuffle(A)
for i,perm in enumerate(permutations(A)):
print perm
if i>=5:
break
Note that the permutations still have a lot of structure so the second permutation will be a lot like the first.
You may do better simply using shuffle(A) each time to try a different permutation. (It may regenerate a permutation but with very low probability for 29 cities.) For example,
for i in range(10):
shuffle(A)
print A

Related

Iterate through all list orders

So I have a set of 11 variables that I want to assign the numbers 1 to 11 using python. I want to then iterate through all combinations of these assignments and check they complete a series of tests. The 6 tests are such that 6 different combinations of the variables (including a separate 12th variable that retains a constant value (12)) are tested to see if they add to 26. For a permutation to be successful, all combinations must add to 26.
To simplify, say it was just 3 variables assigned the numbers 1-3 I want the program to output a=1,b=2,c=3 then to check this against the criteria before changing the order to a=1,b=3,c=2. Check then change: a=2,b=1,c=3 check and change etc until all combinations have been checked.
I first considered using a list to store the numbers 1 to 11 then just randomising the list order using the shuffle function. I’m not sure how else to iterate through the combinations. The random nature of shuffle would eventually do the job but it would be very slow and certainly not an elegant solution.
Thanks for any help in advance :)
I have since realised after looking through the answers and links provided that what I actually need here is the itertools.permutation function. Since this particular problem requires all permutations of the list of numbers 1-11 and not just combinations of these numbers in a list of a smaller size and the ordering matters.The following link was useful in realising the solution.
https://www.tutorialspoint.com/generate-all-permutation-of-a-set-in-python
import itertools
numbers = list(range(1,12))
permutations=list(itertools.permutations(numbers,11))
The result of this code provides all possible orders of the numbers 1-11 as a list of tuples which I can then iterate through to check if they pass the tests.
The itertools package includes a combinations function that may be helpful for you. For example:
import itertools
numbers = range(1, 12)
for (a,b,c) in itertools.combinations(numbers, 3):
# do something

Optimization of Unique, non-reversible permutations in Python

I'm currently trying to solve the 'dance recital' kattis challenge in Python 3. See here
After taking input on how many performances there are in the dance recital, you must arrange performances in such a way that sequential performances by a dancer are minimized.
I've seen this challenge completed in C++, but my code kept running out of time and I wanted to optimize it.
Question: As of right now, I generate all possible permutations of performances and run comparisons off of that. A faster way to would be to not generate all permutations, as some of them are simply reversed and would result in the exact same output.
import itertools
print(list(itertools.permutations(range(2)))) --> [(0,1),(1,0)] #They're the same, backwards and forwards
print(magic_algorithm(range(2))) --> [(0,1)] #This is what I want
How might I generate such a list of permutations?
I've tried:
-Generating all permutation, running over them again to reversed() duplicates and saving them. This takes too long and the result cannot be hard coded into the solution as the file becomes too big.
-Only generating permutations up to the half-way mark, then stopping, assuming that after that, no unique permutations are generated (not true, as I found out)
-I've checked out questions here, but no one seems to have the same question as me, ditto on the web
Here's my current code:
from itertools import permutations
number_of_routines = int(input()) #first line is number of routines
dance_routine_list = [0]*10
permutation_list = list(permutations(range(number_of_routines))) #generate permutations
for q in range(number_of_routines):
s = input()
for c in s:
v = ord(c) - 65
dance_routine_list[q] |= (1 << v) #each routine ex.'ABC' is A-Z where each char represents a performer in the routine
def calculate():
least_changes_possible = 1e9 #this will become smaller, as optimizations are found
for j in permutation_list:
tmp = 0
for i in range(1,number_of_routines):
tmp += (bin(dance_routine_list[j[i]] & dance_routine_list[j[i - 1]]).count('1')) #each 1 represents a performer who must complete sequential routines
least_changes_possible = min(least_changes_possible, tmp)
return least_changes_possible
print(calculate())
Edit: Took a shower and decided adding a 2-element-comparison look-up table would speed it up, as many of the operations are repeated. Still doesn't fix iterating over the whole permutations, but it should help.
Edit: Found another thread that answered this pretty well. How to generate permutations of a list without "reverse duplicates" in Python using generators
Thank you all!
There are at most 10 possible dance routines, so at most 3.6M permutations, and even bad algorithms like generate 'em all and test will be done very quickly.
If you wanted a fast solution for up to 24 or so routines, then I would do it like this...
Given the the R dance routines, at any point in the recital, in order to decide which routine you can perform next, you need to know:
Which routines you've already performed, because there you can't do those ones next. There are 2R possible sets of already-performed routines; and
Which routine was performed last, because that helps determine the cost of the next one. There are at most R-1 possible values for that.
So there are at less than (R-2)*2R possible recital states...
Imagine a directed graph that connects each possible state to all the possible following states, by an edge for the routine that you would perform to get to that state. Label each edge with the cost of performing that routine.
For example, if you've performed routines 5 and 6, with 5 last, then you would be in state (5,6):5, and there would be an edge to (3,5,6):3 that you could get to after performing routine 3.
Starting at the initial "nothing performed yet" state ():-, use Dijkstra's algorithm to find the least cost path to a state with all routines performed.
Total complexity is O(R2*2R) or so, depending exactly how you implement it.
For R=10, R2*2R is ~100 000, which won't take very long at all. For R=24 it's about 9 billion, which is going to take under half a minute in pretty good C++.

Finding all combinations of words of length 2 from list of words using python

temp1 = []
filtered_tokens = ['once','upon','a','time','in','the','forest']
for i in range(len(filtered_tokens)):
for j in range(i+1,len(filtered_tokens)):
temp1.append(filtered_tokens[i]+' '+filtered_tokens[j])
filetered_list, in the above code contains 10,000 words, i only gave the sample list.
output needed for me: once upon, once a, once in, once the, once forest, upon a, upon time, upon in, upon the, upon forest, a time, a in, a the, a forest, time in, time the, time forest, in the, in forest, the forest
when i wrote the logic and run it, compiler thrown me Low memory exception at run time.
Please help me how i can solve this using Combinations or any other python language.
Thank You
For combinations you can use the itertools module.
import itertools
temp1 = itertools.combinations(filtered_tokens, 2)
will create all combinations of 2 words. If you want the list just convert the generator:
temp1 = list(temp1)

How do I predict the output of Python's random number generator?

Here is my code
from random import randint
print(randint(0,9))
Now I want to know which number it will generate if run this code. What is the algorithm behind it?
Is there a way I can change it.
If that does not work, then let me ask something different
from random import randint
for i in range(10):
print(randint(0,9))
Let's take this example. This will print 10 random numbers
list[2,1,4,5,2,4,5,2,1,5]
If I know 9 numbers in the above list, is there a way to know the 10th number for that instance?
The whole point of a random number generator is to provide random numbers.
Ideally, no, there is no way to predict what's the 10th number given 9 numbers in the sequence (because, again,that's not random!)
What you can do is set the seed of the random number generator with random.seed(some_value). By using the same seed, the sequence of numbers generated by subsequent calls to randint() will be identical (note: identical, not predictable).

Tuples birthday paradox

Tuples is n
The birthday problem equation is this:
Question:
For n = 200, write an algorithm (in Python) for enumerating the number of tuples in the sample space that satisfy the condition that at least two people have the same birthday. (Note that your algorithm will need to scan each tuple)
import itertools
print(list(itertools.permutations([0,0,0]))
I am wondering for this question how do I insert a n into this?
"how to get n in there":
n = 200
space = itertools.permutations(bday_pairs, n)
I've left out a couple parts of your code:
itertools returns a list; you don't need to coerce it.
Printing this result is likely not what you want with n = 200; that's a huge list.
Now, all you need to do is to build bday_pairs, the list of all possible pairs of birthdays. For convenience, I suggest that you use the integers 1-365. Since you haven't attacked that part of the problem at all, I'll leave that step up to you.
You still need to do the processing to count the sets with at least one matching birthday, another part of the problem you haven't attacked. However, I trust that the above code solves your stated problem?

Categories