2013-08-29 2 views
0

Я пытаюсь найти все комбинации четырехэлементного вектора, который содержит только 1 и -1. Ex (1,1,1,1), (- 1,1,1,1), ... (- 1, -1, -1, -1) и т. Д. Моя идея сделать это довольно неэффективно im конечно, но я не могу придумать другого способа сделать это, поэтому вот что я пытался сделать. Я нашел, сколько всего векторов было бы, а затем создало много пустых списков. Я начал с вектора A, а затем сравнил его с каждым списком в vectors. Если A соответствовал любому из списков, то я случайно изменил знак элемента A, а затем снова проверил новый список A против vectors. Если A не нашел совпадения, то он заменил на списки в vectors, а цикл while был увеличен на 1. Это должно продолжаться до тех пор, пока не будут найдены и распечатаны все возможные комбинации. Однако мой код просто выплевывает первое изменение в vectors, затем непрерывно зацикливается, не добавляя никаких новых A в vectors. Может ли кто-нибудь определить, что в моем коде не делает то, что я намеревался сделать, и/или указать мне в правильном направлении? БлагодаряПопытка найти все комбинации вектора 2-состояния (в python)

import random 
numvec = 2**4 # number of macrostates for a 4 component 2-state system 

vectors = [[0,0,0,0] for i in range(numvec)] #initializing the numvec vectors 
A = [1,1,1,1] 
i = 0 
while i < 16: 
    if any(x == A for x in vectors): 
     y = random.randrange(0, 3) 
     A[y] = A[y] * -1 
    else: 
     vectors[i] = A 
     print vectors[i] 
     i += 1 

print vectors 

О, и снова я понимаю, этот метод является невероятно неэффективным, но, как это домашнее задание я больше озабочен возможность получить питона делать то, что я хочу, чтобы это сделать, то, используя кучу встроенных в функциях для работы для меня. Еще раз спасибо.

ответ

1
vectors[i] = A 

Это не создает копию A. Когда вы меняете A, содержимое vectors изменяется, потому что vectors[0] и A - это тот же объект после первого запуска этой строки. Чтобы исправить это, создайте новый объект A каждый раз или скопируйте A и вставьте копию в список.

Если вы хотите, чтобы сделать копию, вы можете использовать Python's slice notation:

vectors[i] = A[:] 
+0

да! вот и все! это была единственная проблема, и теперь она работает. Спасибо большое – user2727518

3

Я думаю, что вы можете сделать это легко с помощью встроенной функции itertools.product:

list(itertools.product([-1,1], repeat=4)) 

В качестве альтернативы, вы можете написать все это с списком пониманием. Это гораздо более многословен, но он избегает использования itertools библиотеки:

list((i,j,k,l) for i in (-1,1) for j in (-1,1) for k in (-1,1) for l in (-1,1)) 
+0

да я получил такое впечатление, что я мог бы использовать 'itertools', но я стараюсь не использовать его, как это было бы слишком легко. точка назначения заключалась в том, чтобы получить некоторый опыт использования, если статуты – user2727518

+0

хорошо, это хорошая пища для размышлений, я вызывающе посмотрю, что «itertools» может делать для будущих проектов. – user2727518

+0

Второй ответ не использует itertools, если вы не заметили. – Joohwan

0

Для образовательных целей (если учесть, что люди с подобной проблемой, вероятно, ищет общерекурсивной подход - классическая задача)

def get_possibilities(elements, length=1): 
    if length == 0: 
     return [[]] 

    if length > 0: 
     tails = get_possibilities(elements, length=length-1) 
     return [[x] + t for x in elements for t in tails] 

results = get_possibilities([1,-1], 4) 

Как это работает, например:

[1,-1], length=4 
call get_possibilities([1,-1],4) (main) 
call get_possibilities([1,-1],3) (from get_possibilities) 
call get_possibilities([1,-1],2) (from get_possibilities) 
call get_possibilities([1,-1],1) (from get_possibilities) 
call get_possibilities([1,-1],0) (from get_possibilities) 

return [[]] (from the [1,-1], 0 call) 

merge any element (here 1,-1, as list) with any element of the prior return 
return [[1],[-1]] (from the [1,-1], 1 call) 

merge any element (here 1,-1, as list) with the prior return 
return [[1, 1], [1, -1], [-1, 1], [-1, -1]] (from the [1,-1], 2 call) 

merge any element (here 1,-1, as list) with the prior return 
return [[1, 1, 1], [1, 1, -1], [1, -1, 1]...] (8 elements, 2**3) (from the [1,-1], 3 call) 

merge any element (here 1,-1, as list) with the prior return 
return [[1, 1, 1, 1], [1, 1, 1, -1], ...] (16 elements 2**4) (from the [1,-1], 4 call) 

поздравления

PS: я бы предположил, что itertools.product работает аналогично;)

Смежные вопросы