|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 581
|
[JAVA]Ricerca e confronto dati in una Hashtable
Salve ragazzi, sto preparando un algoritmo di bilanciamento fatto ad agenti. Il problema è che al nodo controllore arriva una hashtable che contiene la coppia (container-carico nodo) ora io dovrei cercare all'interno della hashtable se il carico di un determinato nodo supera una determinata soglia, se la supera devo spostare l'applicazione che sto monitorado.
Il problema è che con le hashtable non sono tanto ferrato e percio vi chiedo come fare a confrontare il valore delle chiavi della hashtable con un valore esterno di soglia. Grazie per l'aiuto. Ciao
__________________
Toshiba M40-281 |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 581
|
![]()
__________________
Toshiba M40-281 |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Se è una tabella Container-Carico, le chiavi sono i container e
non puoi che fare una scansione delle singole coppie contenute nella HashTable. Codice:
for(Map.Entry<Container, Carico> entry : hashtable) { Container co = entry.getKey(); Carico ca = entry.getValue(); vedi un po' che fare con co e ca } Se sai che la tabella contiene un solo container col relativo carico puoi andare a guardare direttamente il carico: Carico c = tabella.elements().next(); Alla fine della fiera la tabella ti è utile in quanto tale, e non semplicemente in quanto collezione di coppie da macinare una per una, se conosci già la chiave, cioè il contenitore. Allora potresti dire: Container c = il container che so essere presente nella tabella Carico y = tabella.get(c); Se la tabella che ti arriva contiene un numero sufficiente di dati a renderlo conveniente e le ricerce che devi fare sono più d'una, allora puoi "ottimizzare" la ricerca - dal punto di vista algoritmico - trasferendo le coppie Container-Carico (cioè i vari Map.Entry che ottieni dalla tabella con il metodo entrySet()) in un TreeSet, "ordinato" per carico. Il treeset ha dei metodi che restituiscono sottoinsiemi ottenuti per inclusione in un range di valori (subste, headset e tailset), che sono ovviamente dei log(n) anziche degli N.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 581
|
Ti ringrazio della risposta, la tabella contiene sempre piu di un container ma non è mai fissa perche ho possibità di configurarla per vari nodi cluster, quello che mi servirebbe è confrontare il carico di ogni nodo con un valore di soglia e se uno di questi carichi supera la soglia mi deve restituire il container associato al carico corrispondente.
Quindi se ho capito bene devo usare questo TreeSet per ordinare i carichi? Hai qualche esempio per fare cio? Grazie mille
__________________
Toshiba M40-281 |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
A meno che tu non abbia una quantità esorbitante di dati ti basta la tabella e il ciclo for del post precedente.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 581
|
Sto provando con il tuo suggerimento ma ho un errore a cui non riesco a trovare soluzione
Ho tolto tutto dal for perchè mi dava un errore ma non ho capito che tipo di errore era allora per fare una prova ho fatto: Codice:
Set entries=LoadInf.entrySet(); Map.Entry entry = (Map.Entry) entries.iterator().next(); String co = (String) entry.getKey(); float ca = (float) entry.getValue(); System.out.println(co+ca); Come devo fare per eliminare quest'errore?
__________________
Toshiba M40-281 |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Usa:
float ca = (Float) entry.getValue(); nota la F maiuscola. Le mappe lavorano, sia come chiavi che come valori, su riferimenti. I tipi numerici con la lettera minuscola sono primitivi, quelli con la maiuscola denota i "wrapper" di quei primitivi. Il wrapper è, in sintesi, l'istanza di una classe che ha un campo del tipo numerico primitivo corrispondente. L'assegnazione del valore di un Float a quello di un float funziona per via dell'auto-unboxing, in pratica dire: float ca = (Float) entry.getValue(); equivale a dire: Float temp = (Float) entry.getValue(); float ca = temp.floatValue(); Sarebbe meglio, per evitare errori nelle conversioni esplicite, usare i tipi parametrici, cioè avere nel codice anzichè: Set entries=LoadInf.entrySet(); una cosa di questo genere: Set<Entry<String, Float>> entries = LoadInf.entrySet(); quindi LoadInf sarebbe una Hashtable<String, Float>, ma, a parte il controllo sulle conversioni, non cambia nulla.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 581
|
Grazie per l'aiuto molto esauriente nelle spiegazioni, solo che vorrei un altra delucidazione su Map per applicarla al meglio nella mia applicazione.
Allora le mie coppie Container(chiave)-CaricoNodo(valore) attualmente sono 4 e restituiscono diciamo questi valori: Codice:
Main-Container@localhost 0.56 Container-1@localhost 0.50 Container-2@localhost 0.45 Container-3@localhost 0.8 in quest esempio quindi nella mia ricerca devo prendere quello che c'è in container 3 e spostarlo in container 2.Lo spostamento lo so fare e funziona quello che non so fare è appunto quello di trovare e il max e il min tra questi valori. Qui c'è una bozza dei codice ma mi ritorna sempre l'ultimo container. Codice:
float Lh=(float) 0.7; Set entries=LoadInf.entrySet(); Iterator i=entries.iterator(); while(i.hasNext()){ Map.Entry entry = (Map.Entry)i.next(); Location co = (Location) entry.getKey(); float ca = (Float) entry.getValue(); System.out.println(co); System.out.println(ca); if (ca>Lh){ .... } } ![]() ![]()
__________________
Toshiba M40-281 |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Il tuo codice è corretto: lì effettivamente entry nell'if per ogni elemento che supera la soglia. Il problema potrebbe derivare dal bilanciamento durante l'iterazione, vale a dire che se cambi il carico di un elemento che hai già "ciclato" non sei più in grado di rilevare lo sforamento della soglia nel corso dello stesso ciclo: devi ripeterlo.
Se questo è il caso allora anzichè avere un ciclo sugli elementi della mappa a te interessa avere un ciclo condizionato dall'esistenza di un elemento il cui carico superi la una certa soglia. Cioè diresti: Codice:
while(condizione) { per ogni elemento e che supera la soglia prendi l'elemento m col carico minore sposta un po' di carico da e a m } esiste almeno un elemento con carico maggiore di un tot E esiste almeno un elemento con carico minore di tot Se è così (e ho un mezzo sospetto che lo sia) puoi affrontare la questione creando una tua struttura immaginaria che risponda esattamente all'esigenza che hai per poi passare a concretizzare i meccanismi attraverso cui ottieni quella risposta. Posso cioè ipotizzare che esista una struttura così definita: Codice:
package soglie; import java.util.List; import java.util.Map.Entry; public interface MiaStrutturaDati { boolean esisteContainerConCaricoMaggioreDi(float soglia); boolean esisteContainerConCaricoMinoreDi(float soglia); List containerConCaricoMaggioreDi(float soglia); Entry containerConCaricoMinoreDi(float soglia); } Codice:
MiaStrutturaDati struttura = null; while(struttura.esisteContainerConCaricoMaggioreDi(0.7f) && struttura.esisteContainerConCaricoMinoreDi(0.7f)) { List daSpostare = struttura.containerConCaricoMaggioreDi(0.7f); for (Object object : daSpostare) { Entry containerSovraccarico = (Entry) object; Entry containerScarico = struttura.containerConCaricoMinoreDi(0.7f); if(containerScarico == null) { break; } //finiti i container "scarichi" float sovraccarico = (Float) containerSovraccarico.getValue(); float scarico = (Float) containerScarico.getValue(); float bilanciamento = sovraccarico - 0.7f; containerSovraccarico.setValue(sovraccarico - bilanciamento); containerScarico.setValue(scarico + bilanciamento); } } Una versione efficace ma non efficiente sarebbe questa: Codice:
package soglie; import java.util.Hashtable; import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; public class FunnyHashtable implements MiaStrutturaDati { private final Hashtable table; /** * Instance initializer */ public FunnyHashtable(Hashtable table) { this.table = table; } public boolean esisteContainerConCaricoMaggioreDi(float soglia) { for (Object object : table.values()) { Float value = (Float) object; if(value > soglia) return true; } return false; } public boolean esisteContainerConCaricoMinoreDi(float soglia) { for (Object object : table.values()) { Float value = (Float) object; if(value < soglia) return true; } return false; } public List containerConCaricoMaggioreDi(float soglia) { List entries = new LinkedList(); for (Object object : table.entrySet()) { Entry entry = (Entry) object; Float value = (Float) entry.getValue(); if(value > soglia) entries.add(entry); } return entries; } public Entry containerConCaricoMinoreDi(float soglia) { for (Object object : table.entrySet()) { Entry entry = (Entry) object; Float value = (Float) entry.getValue(); if(value < soglia) return entry; } return null; } } Codice:
MiaStrutturaDati struttura = new FunnyHashtable(pippo); while(struttura.esisteContainerConCaricoMaggioreDi(0.7f) && struttura.esisteContainerConCaricoMinoreDi(0.7f)) { List daSpostare = struttura.containerConCaricoMaggioreDi(0.7f); for (Object object : daSpostare) { Entry containerSovraccarico = (Entry) object; Entry containerScarico = struttura.containerConCaricoMinoreDi(0.7f); if(containerScarico == null) { break; } //finiti i container "scarichi" float sovraccarico = (Float) containerSovraccarico.getValue(); float scarico = (Float) containerScarico.getValue(); float bilanciamento = sovraccarico - 0.7f; containerSovraccarico.setValue(sovraccarico - bilanciamento); containerScarico.setValue(scarico + bilanciamento); } } En passant, in FunnyHashtable trovi comunque il modo di ottenere gli Entry il cui valore è maggiore o minore di una certa soglia. Per ottenere non solo un Entry il cui float è minore di soglia ma anche quello che è minore tra tutti gli entry, il codice sarebbe: Codice:
public Entry containerConCaricoMinoreDi(float soglia) { Entry risultato = null; float minimo = soglia; for (Object object : table.entrySet()) { Entry entry = (Entry) object; Float value = (Float) entry.getValue(); if(value < minimo) { risultato = entry; minimo = value; } } return risultato; }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 581
|
Ciao per prima cosa ti ringrazio vivamente del tuo interesse per il mio problema, stai salvando la mia tesi, ora sto cercando di leggere il tuo codice domani cerco di mettere mano modificando il mio.
Comunque in effetti la mia hashtable mi viene mandata da un altro agente che ogni tre secondi si fa un viaggetto tra i vari container e va prelevando i carichi, quando poi ha finito il giro ritorna alla base e prima di morire rilascia la hashtable a quest'agente bilanciatore che deve operare il bilanciamento. Domattina cercherò (a mente fresca) di giocare un po col tuo codice ma, essendo pessimista, ti anticipo che dovrai rispondere a qualche domanda. ![]() Grazie mille Ciao
__________________
Toshiba M40-281 |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 581
|
Ciao allora sto provando il tuo codice e su questo ti ringrazio ancora infinitamente, sto risolvendo alcuni problemi perche l'Entry containerScarico lo devo convertire in un oggetto di tipo Location per jade ma il cast non funziona e sto trovando metodi alternativi, a meno che tu non conosci una soluzione
![]() il mio agente ha un behaviour di tipo ciclico quindi non si ferma mai e bilancia continuamente al superamento della soglia critica, ammettiamo che ho una situazione di questo tipo: Codice:
Main-Container@localhost 0.23 Container-1@localhost 0.29 Container-2@localhost 0.75 Container-3@localhost 0.8 Container-2 e Container-3 e i container scarichi sono Main-container e Container-1 Ora che entro nel for succede che trovo un container scarico alla volta? Cioè nel primo ciclo for trovo come container scarico Main-container e quindi prendo quello che c'è in Container-2 e lo sposto in Main-container e al secondo for prendo quello che c'è in Container-3 e lo sposto in Container-1. E' questo teoricamente il funzionamento del sistema di bilanciamento? Te lo chiedo per essere sicuro di aver capito bene il funzionamento. Intanto cerco di risolvere i miei problemi cosi poi passiamo alla pratica Ancora grazie. Ciao Ciao
__________________
Toshiba M40-281 |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Devo premettere che le mie esperienze col bilanciamento si risolvono in una richiesta che di quando in quando faccio al gommista.
Detto questo, intendi correttamente. Il codice determina quale sia il container più scarico ad ogni passaggio nel ciclo. Usando, attenzione, la versione del metodo containerConCaricoMinoreDi che trovi in fondo al post: quella restituisce il minimo, l'altra restitituisce semplicemente un container con carico minore della soglia.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 08:31.