Sediamoli a tavola



  • Sediamoli a tavola
    di Jack (utente non iscritto) data: 01/11/2015 18:55:04

    Ho un file Excel molto semplice nel quale sto annotando i prenotati ad una sagra paesana:
    NOME | NUMERO

    Dove "nome" è la persona che prenota e "numero" è il numero delle persone prenotate.

    I tavoli sono tutti da 22 persone. Devo combinare i prenotati per fare in modo che riempano le tavole il più possibile (dunque devo in pratica fare dei gruppetti pari a 22 persone, oppure 21, comunque ottimizzando i posti).

    Esempio:
    Tizio 16
    Caio 4
    Sempronio 8
    Rossi 2
    Verdi 10
    Gialli 13

    Gialli e Sempronio, assieme, potrebbero fare una tavolata da 21
    Tizio, Caio e Rossi, assieme, potrebbero fare una tavolata da 20

    Apparentemente si tratta di un problema banale, che a mano si può risolvere con relativa facilità. Ma essendoci molte prenotazioni, a mano ci vuole molto molto tempo. Come gestire questo file per fargli organizzare le tavolate e far sedere a tavola la gente nel migliore dei modi?

    Ps. cena in sagra offerta a chi risolve il problema!



  • di Cucù data: 01/11/2015 19:00:41

    Divertente da risolvere ^_^
    La prima domanda che mi viene in mente è:
    Che si mangia in questa sagra???
    Seconda domanda:
    se qualcuno prenota per più di 22 persone come gestire la cosa???
    Cucù


  • Numero di prenotati
    di Jack (utente non iscritto) data: 01/11/2015 19:11:49

    La tua domanda denota il fatto che hai capito benissimo la questione. E infatti, in effetti, c'è anche questo problema. A volte ci sono gruppi da 30 prenotati, ad esempio. Ma si può bypassare con un passaggio manuale antecedente, aggiungendo un gruppo e smezzando il gruppo in base ai desiderata (ad esempio da un gruppo da 30 si possono fare due da 15 o uno da 10 e uno da 20, ma comunque attraverso un veloce passaggio manuale).

    Insomma: il problema dei numeri sopra i 22 è reale, ma si può ignorare poiché facilmente risolvibile a mano.

    Inoltre: svelo l'ingrediente centrale soltanto al termine , ma confermo fin da ora l'invito a cena!



  • di Cucù data: 02/11/2015 13:28:00

    Prova ad allegare il solito file di esempio giusto per capire bene la situazione sperando di aver tempo per risponderti altrimenti vedrai che qualche esperto una dritta te la darà..
    Cucù



  • di Marius44 data: 02/11/2015 16:33:07

    Salve a tutti
    Meglio non m'è venuto. Penso che l'utilizzo sia intuitivo ma ho messo delle indicazioni nel foglio stesso.

    Credo di essermi guadagnato .. un posto a tavola.

    Ciao,
    Mario


  • Il tempo di provare
    di Jack (utente non iscritto) data: 02/11/2015 17:00:31

    Il tempo di accedere al file originale e provare. Devo capire come adattare questa soluzione al foglio in possesso, perché a una prima occhiata non mi è parso intuitivo.

    Tra qualche ora vi faccio sapere!



  • di Marius44 data: 02/11/2015 18:19:38

    @Cucù
    Avrei piacere di conoscere il tuo parere sul mio allegato (che, lo riconosco, non è perfetto ma aiuta).

    Ciao,
    Mario



  • di perché (utente non iscritto) data: 02/11/2015 18:31:54

    La questione non è banale. E' riducibile al cosiddetto

    Problema dello zaino (o Knapsack problem)
    h t t p s://it.wikipedia.org/wiki/Problema_dello_zaino

    che ha diverse soluzioni, più p meno ottimizzate, ma non di facile implementazione.

    Anche per VBA esistono esempi (ovviamente da adattare) sul web, in generale l'argomento è uno di più trattati in informatica.



  • di ninai data: 02/11/2015 22:44:43

    ciao
    prendendo spunto dal link di Perchè, ma non sapendo di VBA , ho cercato di applicare con formule "Algoritmo Greedy", richiamato da Wikipedia.

    Ho messo in ordine decrescente il numero delle varie prenotazioni, ho aggiunto una colonna vuota di servizio (fra la B e la C) ed in D5:
    =SE(($B5<=($B$1-SOMMA(D$4:D4)))*(SOMMA($C5:C5)<$B5);$B5;"")
    ed ho trascinato in basso ed a destra
    vi è qualche differenza, ma citando WP:
    "È bene far notare come questi algoritmi siano euristici: essi, quindi, non garantiscono l'ottimalità della soluzione ma sono in grado di fornire una "buona" soluzione in tempo ragionevole"

    il ragionamento si potrebbe sviluppare anche per prenotazioni oltre le 22 persone.

    allego file di lavoro



  • di cromagno data: 03/11/2015 00:34:34

    Ciao a tutti,
    non ho avuto modo di cimentarmici ma ho visto i file di Mario e ninai e posso solo dire bel lavoro
    Come ha giustamente detto ninai, tutto questo procedimento è molto euristico ma i risultati si ottengono.
    Ancora complimenti



  • di Mister_x (utente non iscritto) data: 03/11/2015 00:37:10

    ciao

    ciao ninai
    mi sono permesso di apportare alcune modifiche alle formule e ai dati inseriti
    varie modifiche alla formattazione delle celle per determinare alcuni calcoli onde creare un secondo foglio con inseriti i nominativi e il relativo numero di ogni tavolo
    ps questi riporti ho dovuto farli su una base di classifica di una gara da come si vedra' onde evitare riporti di nomi doppi
    quindi ora la tua formula di partenza e' diventata questa
    =SE(($B5<=($B$1-SOMMA(D$4:D4)))*(SOMMA($C5:C5)<$B5);$B5+RIF.RIGA()/1000000;"")
    in foglio2 in A2 ho inserito quest'altra formula
    =SE.ERRORE(INDICE(Ins!$A$5:$A$29;CONFRONTA(GRANDE(Ins!D$5:D$29;RIF.RIGA($A1));Ins!D$5:D$29;0);1)&" "&INDICE(Ins!$B$5:$B$29;CONFRONTA(GRANDE(Ins!D$5:D$29;RIF.RIGA($A1));Ins!D$5:D$29;0);1);"")

    il tutto per avere un elenco riferito ad ogni singolo tavolo

    PS per chi volesse usare questo file si ricordi che le formule vanno ampliate per maggiori valori,
    piu' nominativi , piu' tavoli ecc. ecc.

    allego il file con le modifiche

    ciao




  • Loop?
    di Jack (utente non iscritto) data: 03/11/2015 00:48:13

    Ho fatto una serie di tentativi ma non sono andati a buon fine: La procedura sembrava essere un ciclo infinito e non si arrivava al risultato. Non nego che potrei essermi perso qualche passaggio nella trasposizione dei dati, chiaramente: non so a cosa imputare il tutto.

    Potrei provare a creare un file avente un quadro realistico della situazione. Con dati reali. Cosi la prova si fa direttamente e diventa facile capire ove stia eventualmente il problema. Perché a quel punto vasta cambiare nomi e numeri e deve funzionare per forza.

    Ora sono da mobile, domani tento di standardizzare il tutto e vediamo. Mi sembra comunque che siate sulla buona strada. Io ammetto di essermi perso qualche passaggio fa... :)



  • di mb data: 03/11/2015 11:31:08



    forse un'altra dritta la si può trovare qui con le opportune modifiche

    h t t p://www.excelvba.it/Forum/story/Excel_e_gli_applicativi_Office/Tavoli_per_matrimonio.html

    ninai ne sa qualcosa .....




  • di Cucù data: 03/11/2015 15:08:50

    Avrei piacere di conoscere il tuo parere sul mio allegato (che, lo riconosco, non è perfetto ma aiuta).

    Concordo con il contenuto che hai inserito tra parentesi...

    Nel frattempo anche io ho provato a risolvere il problema dell'amico Jack nella speranza che la sagra non sia quella della "prugna cotta" ^_^
    Allego il mio file di esempio.
    In colonna A i nomi degli iscritti
    In colonna B il numero di prenotati
    In colonna C con la scritta "Gestione manuale" nel caso in cui gli iscritti siano superiori a 22, "X" conferma inserimento in un tavolo
    Colonna D totale per tavolo
    Colonna E Numero di tavolo da assegnare
    Da colonna F in poi Nomi delle prenotazioni

    Cucù



  • di Cucù data: 03/11/2015 15:11:00

    Avrei piacere di conoscere il tuo parere sul mio allegato (che, lo riconosco, non è perfetto ma aiuta).

    Concordo con il contenuto che hai inserito tra parentesi...

    Nel frattempo anche io ho provato a risolvere il problema dell'amico Jack nella speranza che la sagra non sia quella della "prugna cotta" ^_^
    Allego il mio file di esempio.
    In colonna A i nomi degli iscritti
    In colonna B il numero di prenotati

    Al click del pulsante avremo:

    In colonna C con la scritta "Gestione manuale" nel caso in cui gli iscritti siano superiori a 22, "X" conferma inserimento in un tavolo
    Colonna D totale per tavolo
    Colonna E Numero di tavolo da assegnare
    Da colonna F in poi Nomi delle prenotazioni

    Cucù



  • di Cucù data: 03/11/2015 15:27:07

    Perchè?

    Perchè invece che modificare il messaggio ne mette uno nuovo?
    A che serve allora il pulsante "modifica"



  • di Marius44 data: 03/11/2015 18:02:05

    Salve a tutti
    Brutto o no, datemi almeno la paternità per ... lo schema!!
    Ma bando agli scherzi. Ho notato che tutti abbiamo trovato una soluzione per combinare (chi più chi meno) i commensali fino a 22. Rimangono da sistemare quelli la cui prenotazione supera la soglia indicata.
    Perché non provare a trovare una soluzione (perché no, anche con sistemici euristici) per coloro che attualmente sono da sistemare a mano? E' Possibile?

    Ciao a tutta la ... banda,
    Mario



  • di Cucù data: 03/11/2015 18:15:48

    @Mario

    Insomma: il problema dei numeri sopra i 22 è reale, ma si può ignorare poiché facilmente risolvibile a mano.

    Questa era la volontà del richiedente che... è stata rispettata...

    Ciao Cucù
    PS Cmq se Jack lo richiede la modifica al codice si può fare senza particolari problemi.



  • di ninai data: 03/11/2015 19:35:42

    cit.
    Brutto o no, datemi almeno la paternità per ... lo schema!!
    scusa "papa"

    scusa Mario
    me ne sono accorto adesso che il file iniziale che io ho usato per le formule era il tuo e non di Jack.


  • ...funziona :)
    di Jack (utente non iscritto) data: 04/11/2015 00:27:49

    Ragazzi... funziona!
    Ho portato a 45 il numero delle tavolate e a un centinaio il numero dei prenotanti. Rimane il "vezzo" dei 22, risolto il quale l'intera casistica sarebbe a posto. Ma nel caso specifico si risolverà "a mano" perché solo un essere umano può decidere come splittare un gruppo ampio in base a parametri vari.

    Cercherò ora di sviluppare la casella delle tavolate con altro ordinamento (invertire colonne e righe per poter stampare agli addetti un elenco ben formato delle varie tavolate) ed a quel punto secondo me la questione é risolta.

    Mi prendo ancora 48 ore per deliberare: Sto applicando lo schema a tutti gli appuntamenti culinari della festa cosi il test sarà approfondito e vasto.

    Poi vediamo che vuol venire a ritirare l'invito omaggio



  • di Cucù data: 04/11/2015 08:21:58

    Tanto per sapere chi ha vinto l'invito alla sagra della "Prugna Cotta" , quale soluzione hai adottato?
    Cucù
    PS
    Ho fatto una piccola correzione nel file allegato.



  • di Raffaele_53 data: 04/11/2015 14:53:39

    Ciao a tutti
    >>>il problema dei numeri sopra i 22 è reale, ma si può ignorare poiché facilmente risolvibile a mano
    ???

    L'altra sera stavo provando, poi ho dovuto smettere.
    Sulla falsa riga di "Cucù" (ordinare i gruppi a scalare), riunivo i "tavoli dei gruppi" maggiori di 22.

    Ex Se il 1°gruppo fosse 65, creo tavola1 di 22 e subito a fianco creo tavola2 di 22, i rimanenti 11 in tavola3 (in modo che stiano tutti vicini).
    Passando al 2°Gruppo 40, "potrei scegliere" se i rimanenti 18 ci stanno in tavola3 (in questo caso = NO), allora tavola4 con 22 e tavola5 con 18 (cosi stanno tutti vicini)
    Anche per questo caso valutando i rimanenti del 3°gruppo, non posso farli sedere alla tavola5°, pertanto saranno in tavola6 e tavola7.
    Per il gruppo 4°, il rimanente 1 sarà alla tavola7 e i 22 in tavola8. NB*

    Cosi via sino al complettare tutti i gruppi maggiori di 22 e anche per quelli uguali a 22. A questo punto un ciclo for sui tavoli incomplettiper trovare le combinazioni mancanti.
    Naturalmente e solo il mio punto di vista

    Che siano 5/10/50/100 tavoli, non è detto che tutti i tavoli siano pieni.
    Diverse combinazione di TOT prenotazioni potrà essere ideale a riempirli tutti. Tutte le altre lasceranno alcuni posti vuoti nei tavoli.

    NB* Tolleranza Zero, oppure prevedere che per 1/2 persone (eccezione) appartenenti allo stesso gruppo mangiare al stesso tavolo?



  • di Cucù data: 04/11/2015 15:30:58

    Ciao raffaele

    solo per diletto ho anche risolto l'evenienza dei gruppi superiori a 22 ma non l'ho postata volutamente anche perchè ho pensato che un gruppo per esempio da 60 persone potrebbe essere diviso in moltissimi modi a secondo anche dei gusti degli stessi invitati, quindi ritengo più corretto lasciare all'operatore la possibilità di intervenire manualmente almeno su questo.
    Cucù



  • di Mister_x (utente non iscritto) data: 05/11/2015 01:05:45

    ciao

    per passare il tempo una sub() che divide i commensali su i tavoli indifferentemente dal loro numero
    ma solamente dando quanti per tavolo e quanti tavoli abbiamo a disposizione

    allego il file che ho gia trovato impostato con valori

    ciao
     
    Option Explicit
    Sub Organizza()
    Dim i As Long, o As Long, z As Long
    Dim NcXt As Long, TotaT As Long, Npre As Long
    Dim tavoli As Long
    Dim Nscala As Long
    Range("C3:ZZ1000").ClearContents
    tavoli = Cells(3, 2)
    NcXt = Cells(1, 2).Value
    Npre = Cells(Rows.Count, 1).End(xlUp).Row
    For i = 4 To 3 + tavoli
     Cells(4, i) = "Tav. " & i - 3
    Next i
    ''------------
    For o = 5 To Npre
     If Cells(o, 2) > NcXt Then
      For i = 4 To 3 + tavoli
        TotaT = Application.Sum(Range(Cells(5, i), Cells(Npre, i)))
          If TotaT = 0 Then
          Cells(o, i) = NcXt
          Nscala = Cells(o, 2) - NcXt
            For z = 1 To Fix(Cells(o, 2) / NcXt)
              If Nscala >= NcXt Then
                Cells(o, i + z) = NcXt
                Nscala = Nscala - NcXt
              Else
                Cells(o, i + z) = Nscala
              End If
            Next z
        Exit For
          End If
      Next i
     End If
    Next o
    ''--------------
    For i = 4 To 3 + tavoli
     TotaT = Application.Sum(Range(Cells(5, i), Cells(Npre, i)))
     For o = 5 To Npre
       If Cells(o, 3) = "" Then
         If TotaT + Cells(o, 2) <= NcXt Then
           Cells(o, i) = Cells(o, 2)
           Cells(o, 3) = "X"
           TotaT = TotaT + Cells(o, 2)
         End If
       End If
     Next o
     Cells(3, i) = Application.Sum(Range(Cells(5, i), Cells(Npre, i)))
    Next i
    End Sub
    






  • di Raffaele_53 data: 07/11/2015 00:23:56

    Riciao a tutti
    Non desidero rompere, però vorrei imparare
    Dato che sono in pensione, mi diletto con excel "certo che ninai,canapone,scossa non sono commestibili" per me
    Seguivo questo post per natura simile a "nesting tubi", dove vorrei utlizzare gli eventuali scarti precedenti
    Ho visto tutti gli allegati, il codice "Cucù 3/4"...un pò lento mi piace (se puoi allega le tavolate sopra i 22), faccio fatica a capirlo, però funziona.
    Se Vuoi ti passo il "riunire dei gruppi maggiori". Sempre fosse una priorità


  • Ritira il premio...
    di Jack (utente non iscritto) data: 07/11/2015 01:13:08

    Per quanto mi riguarda la seduta è tolta!

    Domani inizia la fiera e la soluzione adottata è assolutamente adeguata e funzionante. Senza utilizzare alcune raffinatezze che avete aggiunto (ma chissà, in futuro...), ho utilizzato il file allegato da Ninai (con modifiche di Mister_X) e seguito alcuni consigli di Cucù. Insomma, per quanto mi concerne meritate un posto a tavola tutti e tre. Se qualcuno di voi passa da queste parti, faccia un fischio!
    --> amicidicervere.it/fiera-porro-programma/

    Grazie per la collaborazione! Ho risolto un problema e ne ho imparato qualche pezzettino di più. Se passate in zona, mi troverete dietro un PC. E sceglierà lui la tavola per voi



  • di mb data: 07/11/2015 10:49:51

    buongiorno

    arriva il "braidese pignolo"
    nel foglio ins ho scritto marco 25 persone

    marco 25 22 3 25

    premetto che ho corretto a mano i dati del tavolo 7 e 8 altrimenti non li inseriva

    nel file di misterx è possibile modificare la formula perché verifichi i valori nelle colonne e non in colonna B perché il risultato che ottengo nel foglio tavoli è

    tav.7 tav.8
    marco 25 marco 25

    la risposta non mi serve adesso perché è solo per studiare i vari processi di vba Excel ecc.

    godetevi la festa e se avete tempo anche a fine mese o dicembre Vi ringrazio





  • di Mister_x (utente non iscritto) data: 07/11/2015 11:44:47

    ciao

    per il file di ninai e modificato da me, quindi tutto in excel la formula e' la seguente

    in tavoli A2 e poi trasinare

    =SE.ERRORE(INDICE(Ins!$A$5:$A$29;CONFRONTA(GRANDE(Ins!D$5:D$29;RIF.RIGA($A1));Ins!D$5:D$29;0);1)&" "&INT(INDICE(Ins!D$5:D$29;CONFRONTA(GRANDE(Ins!D$5:D$29;RIF.RIGA($A1));Ins!D$5:D$29;0);1));"")
    ps in questo file con le formule attualmente, mai dire mai, non e' possibile baipassare il valore di persone per tavolo e aggiungerli su altro
    se controlli il file che lavora in VBA questi fa tutto questo lavoro di posizionare questi su un tavolo vicino
    PS ti allego un nuovo file dove con una sub() elabora anche i nominativi per tavolo con la relativa quantità a sedere
    file = sagra tavolate 2
    dove ho inserito anche questa sub() elencata

    ciao
     
    Option Explicit
    Sub Elenco_per_tavolo()
    Dim i As Long, o As Long
    Dim Nriga As Long
    Dim Ntavoli As Long, Nnomi As Long
    ''--------------
    Range("a3:zz1000").ClearContents
    Ntavoli = Sheets("Ins").Cells(3, 2)
    Nnomi = Sheets("Ins").Cells(Rows.Count, 1).End(xlUp).Row
     For i = 1 To Ntavoli
       Cells(3, i) = "Tavolo " & i
     Next i
    For i = 1 To Ntavoli
    Nriga = 5
      For o = 5 To Nnomi
        If Sheets("Ins").Cells(o, i + 3) > 0 Then
           Cells(Nriga, i) = Sheets("Ins").Cells(o, 1) & " " & Sheets("Ins").Cells(o, i + 3)
           Nriga = Nriga + 1
        End If
      Next o
    Next i
    End Sub
    






  • di mb data: 07/11/2015 12:53:09

    Che dire Grazie Misterx

    buon fine settimana

    alla prossima