Efficiente struttura "Oggetto con pesi"

1

Ho bisogno di trovare una struttura / insieme di algoritmi "efficienti" per fare le seguenti cose:

Ho una lista di oggetti. Devo assegnare loro pesi e successivamente aumentare o diminuire questi pesi.

Ad esempio: Abbiamo hashmaps {o1}, {o2}, {o3} . I {o} non hanno alcuna struttura particullare, solo json casuali.

Sto cercando un modo per dire: Aumenta il peso di o1 di 1. Aumenta il peso di o2 di 1. Aumenta il peso di o1 di 1. Adesso dammi i risultati ordinati in base al loro peso.

Sto usando Python. Finora ho provato ad usare una normale hashmap per memorizzarli, ma il problema è che non posso semplicemente cancellare il {o} . Ho pensato di nascondere il puntatore del {o} in memoria, ma sembra che non abbia accesso ad esso in Python.

    
posta Slytael 08.09.2014 - 17:06
fonte

4 risposte

2

Ovviamente è possibile memorizzare il peso in ogni oggetto o memorizzare una directory di istanze nella classe, se si creano o controllano le classi.

In caso contrario, potresti essere interessato alla classe Counter , un dizionario che esegue la mappatura in valori numerici. Può essere esteso per mappare oggetti a pesi. Ecco uno schizzo:

from collections import Counter

class Weights(object):
    def __init__(self):
        self.counts = Counter()
        self.objs = dict()
    def __setitem__(self, item, value):
        _id = id(item)
        self.counts[_id] = value
        self.objs[_id] = item
    def __getitem__(self, item):
        _id = id(item)
        return self.counts[_id]
    def keys(self):
        return [ self.objs[i] for i in self.counts.keys() ]  
    def items(self):
        return [ (self.objs[i], c) for (i, c) in self.counts.items() ]
    def most_common(self, n=None):
        return [ (self.objs[i], c) for (i, c) in self.counts.most_common(n) ]


o1, o2, o3 = [ object() for i in range(3) ]

weight = Weights()

weight[o1] = 3
weight[o2] = 4.4
weight[o3] = 1.1
weight[o2] += 1.1
print weight.most_common() # tuples sorted by highest weight first

Produce qualcosa come:

[(<object object at 0x106cd30b0>, 5.5), (<object object at 0x106cd30c0>, 3), (<object object at 0x106cd30d0>, 1.1)]

(Il primo elemento di ogni tupla è l'oggetto corrispondente).

Mentre Counter richiede un valore hashable come chiave, Weights mappa ogni oggetto nel suo id (che è intrinsecamente lavabile), internamente. Mentre questo è solo uno schizzo (non sono forniti altri metodi Counter ), fa il tipo di tracciamento dell'oggetto cercato.

    
risposta data 08.09.2014 - 23:59
fonte
1

Utilizza una classe

class Thing(object):
    def __init__(self, o):
        self.o = o
        self.weight = weight

Puoi creare un elenco di Things o un dict o qualsiasi altra cosa che funzioni per te.

    
risposta data 08.09.2014 - 17:16
fonte
1

I am looking for a way of saying: Increase the weight of o1 by 1. Increase the weight of o2 by 1. Increase the weight of o1 by 1. Now give me the results sorted by their weight.

Questo sembra un lavoro per una coda di priorità , dove priority_number è il peso che vuoi assegnare.

    
risposta data 09.09.2014 - 17:32
fonte
0

Per l'ordinamento puoi sostituire __lt__ e altri confrontare la funzione :

import heapq

class Item(object):
    def __init__(self, o, weight):
        self.o = o
        self.weight = weight

    def increase_weight(self, amount=1):
        self.weight += amount

    def __lt__(self, other):
        return self.weight < other.weight

    def __str__(self):
        return '<Item o={o} weight={weight}>'.format(
            o=self.o, weight=self.weight
        )
    __repr__ = __str__

items = [
    Item('o1', 1),
    Item('o2', 5),
    Item('o3', 4),
    Item('o4', 3),
]

items.sort()
print items

items[0].increase_weight(5)
items.sort()
print items
    
risposta data 09.09.2014 - 08:00
fonte

Leggi altre domande sui tag