Ottenere tutti i possibili stati di un oggetto per un NP-completo (?) Problema in Python

StackOverflow https://stackoverflow.com/questions/539676

  •  22-08-2019
  •  | 
  •  

Domanda

Non sono sicuro che l'esempio (né il caso d'uso reale) si qualifica come NP-completo, ma mi chiedo il modo più Pythonic di fare il seguito ammesso che questo era l'algoritmo a disposizione.

Diciamo che avete:

class Person:
  def __init__(self):
    self.status='unknown'
  def set(self,value):
    if value:
      self.status='happy'
    else :
      self.status='sad'
  ... blah . Maybe it's got their names or where they live or whatev.

e qualche operazione che richiede un gruppo di persone. (Il valore della chiave è qui se la persona è felice o triste.)

Quindi, dato Persona, PersonB, PersonC, PersonD - mi piacerebbe finire un elenco dei possibili 2 ** 4 combinazioni delle persone tristi e felici. cioè.

[
[ PersonA.set(true), PersonB.set(true), PersonC.set(true), PersonD.set(true)], 
[ PersonA.set(true), PersonB.set(true), PersonC.set(true), PersonD.set(false)], 
[ PersonA.set(true), PersonB.set(true), PersonC.set(false), PersonD.set(true)], 
[ PersonA.set(true), PersonB.set(true), PersonC.set(false), PersonD.set(false)], 
etc..

C'è un buon modo Pythonic di fare questo? Stavo pensando di list comprehension (e modificare l'oggetto in modo che si potrebbe chiamare e ottenere tornati due oggetti, vere e false), ma i formati di comprensione che ho visto mi avrebbe bisogno di conoscere il numero delle persone in anticipo. Mi piacerebbe fare questo indipendentemente dal numero di persone.

EDIT: Si supponga che qualunque cosa ciò operazione che stavo andando a correre su questo è parte di un problema più ampio set - abbiamo bisogno di testare tutti i valori di persona per un determinato insieme al fine di risolvere il nostro problema. (Vale a dire So che questo non sembra NP-completo adesso =)) tutte le idee?

Grazie!

È stato utile?

Soluzione

Secondo quello che hai indicato nel tuo problema, hai ragione - avete bisogno di itertools.product, ma non esattamente il modo in cui hai dichiarato

.
import itertools
truth_values = itertools.product((True, False), repeat = 4)
people = (person_a, person_b, person_c, person_d)
all_people_and_states = [[person(truth) for person, truth in zip(people, combination)] for combination in truth_values]

Questo dovrebbe essere più lungo le linee di quello che lei ha citato nella sua interrogazione.

Altri suggerimenti

Credo che questo potrebbe farlo:

l = list()
for i in xrange(2 ** n):
    # create the list of n people
    sublist = [None] * n
    for j in xrange(n):
        sublist[j] = Person()
        sublist[j].set(i & (1 << j))
    l.append(sublist)

Si noti che se hai scritto Person in modo che il suo costruttore ha accettato il valore, o tali che il metodo set restituito alla persona in sé (ma questo è un po 'strano in Python), è possibile utilizzare un elenco di comprensione. Con il modo in cui il costruttore:

l = [ [Person(i & (1 << j)) for j in xrange(n)] for i in xrange(2 ** n)]

Il tempo di esecuzione della soluzione è O(n 2**n) come si può dire, cercando in loop, ma non è davvero un "problema" (cioè una domanda con una risposta sì / no) quindi non si può davvero chiamare NP-completo . Vedere Cos'è un NP-completo in informatica? Per ulteriori informazioni su tale anteriore.

È possibile utilizzare un prodotto cartesiano per ottenere tutte le possibili combinazioni di persone e gli stati. Richiede Python 2.6 +

import itertools
people = [person_a,person_b,person_c]
states = [True,False]
all_people_and_states = itertools.product(people,states)

La variabile all_people_and_states contiene una lista di tuple (x, y), dove x è una persona ey è True o False. Conterrà tutti i possibili abbinamenti di persone e gli stati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top