Forum

Forum (https://www.ms-office.gr/forum/)
-   Excel - Ερωτήσεις / Απαντήσεις (https://www.ms-office.gr/forum/excel-erotiseis-apantiseis/)
-   -   [Συναρτήσεις] Άθροιση υπό όρους (https://www.ms-office.gr/forum/excel-erotiseis-apantiseis/878-athroisi-ypo-oroys.html)

mdragon 14-12-10 12:24

Άθροιση υπό όρους
 
1 Συνημμένο(α)
Καλημέρα σε όλη την κοινότητα,
το θέμα μου είναι ότι έχω μία λίστα με ποσά μερικά από τα οποία θέλω να αθροίζω και να μου δίνουν σαν αποτέλεσμα ένα συγκεκριμένο ποσό που θα του ορίζω εγώ κάθε φορά.
Επισυνάπτω συνημμένο για να δείτε τι εννοώ.



Ευχαριστώ εκ των προτέρων,
Μάρω

gr8styl 14-12-10 22:32

Καλησπέρα Μάρω,

το θέμα σου μοιάζει πολύ με το κόψιμο βεργών σε Access δες εδώ

Θα πρέπει να μας διευκρινήσεις μερικά πράγματα για να σε βοηθήσουμε.
1) Πόσο μεγάλη μπορεί να είναι η λίστα με τα ποσά από όπου θα γίνεται η επιλογή ?
2) Ποιος είναι ο στόχος το λιγότερο ή το μεγαλύτερο δυνατό αριθμό επιμέρους ποσων για πλησιασουμε το τελικό ?
3) Υπάρχει καμιά σχέση μεταξύ επιμέρους ποσών και ζητούμενου ποσού ?
4) Τα επιμέρους ποσά είναι μοναδικές τιμές ή μπορεί να υπάρχουν και επαναλήψεις ?

Για πες μας: Αν ζητούσες να φτάσεις τον αριθμό 9 έχοντας στη διάθεσή σου τους αριθμούς από 1 έως 9 (από μια φορά τον κάθε έναν) ποιους θα διάλεγες και γιατί ? (1+2+6) (1+3+5) (1+8) (2+3+4) (2+7) (3+6) ή (4+5) :032:

Δώσε μας τα φώτα σου ώστε να μπορέσουμε να πάμε παραπέρα.:icon_yes:

Τα λέμε.
Θανάσης.

mdragon 15-12-10 09:23

Θανάση καλημέρα,
1) Η λίστα θα περιλαμβάνει περίπου 100 τιμές
2) Δεν με ενδιαφέρει ο αριθμός των επιμέρους ποσών
3) Καμία σχέση
4) Δύσκολο να έχω επαναλήψεις αλλά δεν αποκλείεται
5) Θα διάλεγα το 9 :biggrin: όσο λιγότεροι συνδυασμοί τόσο το καλύτερο.

Από τη λίστα θα μπορώ να χρησιμοποιώ την κάθε τιμή μία μόνο φορά.
Ελπίζω να σε διαφώτισα.



Ευχαριστώ,
Μάρω

kapetang 15-12-10 16:08

Καλησπέρα στην παρέα

Μάρω, σε συγχαίρω για το πρόβλημα, που έθεσες. Είναι απ’ αυτά που ακονίζουν το μυαλό.
Παρόμοιο πρόβλημα, όπως διαπίστωσε και ο Θανάσης, τέθηκε και στην access. Εκεί , αν ισχύουν κάποιοι περιορισμοί, δόθηκε λύση με κώδικα και βασικά ένθετες δομές επανάληψης (For ...Next).
Τώρα δίνεται η δυνατότητα το πρόβλημα να αντιμετωπιστεί και με το excel.
Η παρακάτω διατύπωση του προβλήματος, πιθανόν να βοηθούσε στην επίλυσή του, από τους εδικούς στο excel (Θανάση, Τάσο, κλπ):
  • Δίνεται μία τιμή S.
  • Τα κελιά μιας στήλης έχουν σταθερές τιμές T1, T2, …, Tn.
  • Τα διπλανά κελιά έχουν αντίστοιχα ονόματα X1, X2, …, Xn και μπορούν να πάρουν τιμή 0 ή 1.
  • Ζητείται ο προσδιορισμός των μεταβλητών X1, X2, …, Xn, ώστε η απόλυτη τιμή της διαφοράς abs(T1*X1+T2*X2+…+Tn*Xn-S) να είναι ελάχιστη.
Χωρίς να είμαι σίγουρος, έχω τη γνώμη ότι το excel διαθέτει εργαλεία που επιλύουν προβλήματα αυτής της μορφής.

Φιλικά/Γιώργος

mdragon 16-12-10 08:18

Καλημέρα σας,
προσπάθησα με συναρτήσεις μπας και βγάλω άκρη αλλά τίποτα.
Η λίστα που θα πρέπει να επεξεργαστώ είναι μεγάλη και το γεγονός ότι δεν
μπορώ να χρησιμοποιήσω το ίδιο ποσό δύο φορές δυσκολεύει ακόμα περισσότερο
την κατάσταση.
Η VBA μήπως θα μπορούσε να μας δώσει τη λύση?




Ευχαριστώ,
Μάρω

gr8styl 16-12-10 13:01

1 Συνημμένο(α)
Καλημέρα σε όλους.
Αγαπητή Μάρω και όμως με συναρτήσεις μπορεί να βγει κάποια άκρη. Όχι για 100 αριθμούς αλλά ... :icon_yes:

Στο συνημμένο (from_cuts2sums.zip λόγω μεγέθους) έχω μια λύση με συναρτήσεις και όχι VBA.
Στηρίζεται σε μια λύση που είχα φτιάξει για την κοπή ράβδων αλλά δεν την είχα ανεβάσει στο φόρουμ λόγω του ότι το θέμα είχε τεθεί για Access.

Έχω χρησιμοποιήσει τους αριθμούς του δικού σου παραδείγματος.
Ελέγχει για διπλούς αριθμούς όπως και για αριθμούς μεγαλύτερους του ζητούμενου αθροίσματος και σε ενημερώνει ανάλογα.

Νομίζω θα σε βοηθήσει. :wink:

Περιορίζεται σε max 12 αριθμούς λόγω πλήθους δυνατών συνδυασμών, που ισούται με 2 υψωμένο σε δύναμη ίση με το πλήθος των αριθμών. Δηλαδή για 12 αριθμούς έχουμε 2^12=4096 συνδυασμούς. Το from_cuts2sum θέλει πάρα πολλές αλλαγές για να αυξηθεί ο αριθμός των αριθμών.

Με VBA θα μπορούσες επίσης να δώσεις λύση αλλά θα έλεγα πρέπει να μπούνε έξυπνοι έλεγχοι στον κώδικα για την ελαχιστοποίηση των επαναλαμβανόμενων πράξεων (loops), γιατί 100 αριθμοί είναι υπερβολικά πολλοί. :worthy:

Το αφήνω όμως να ασχοληθούν οι γκουρού της VBA αν θέλουν και μπορούν.

Για πες μου γιατί πολύ θα με ενδιέφερε να μάθω σε τι σου χρησιμεύει να βρεις τους αριθμούς που μας δίνουν κάποιο συνολικό άθροισμα; :032:

Τα λέμε
:handshake:
Θανάσης.

officeandi 16-12-10 13:05

Καλημέρα στα μέλη του θέματος, καλημέρα Μάρω,

Σκέφτηκα λίγο το θέμα αυτό και πιστεύω πως ο μόνος τρόπος είναι να γίνει η πρόσθεση για όλους τους δυνατούς συνδυασμούς
για να κρατήσεις τους ας πούμε 10 ή 20 καλύτερους και στον καθένα από ποιον συνδυασμό παράχθηκε (τετράδα, πεντάδα, κλπ.).
Ο τρόπος αυτός είναι γνωστός ως brute force αλγόριθμος και στην περίπτωση αυτή ο μόνος δυνατός.

Κατά τη γνώμη μου θα έπρεπε όλες οι τιμές να εισαχθούν σε ένα array

Στη συνέχεια ξεκινούμε ένα for loop από το j=1 έως το 100, όπου το κάθε j το μεταφράζουμε κάθε φορά στο δυαδικό σύστημα (bitmask).
Αν μια ορισμένη θέση του bitmask έχει τιμή 1(true), τότε επιλέγουμε την αντίστοιχη τιμή από το array για πρόσθεση, διαφορετικά την παραλείπουμε.
Όλο αυτό θα μπορούσε να το αναλάβει ένα VBA-module.

Τώρα στην πράξη: Έστω ότι δεν έχουμε 100 διαφορετικές τιμές, αλλά:
  • 8 => πλήθος συνδυασμών 2^8 = 256
  • 16 => πλήθος συνδυασμών 2^16 = 65536
  • 32 => πλήθος συνδυασμών 2^32 = 4 294 967 296
  • 64 => πλήθος συνδυασμών 2^64 = 18 446 744 073 709 551 616
  • 100 => πλήθος συνδυασμών 2^100 = 1 267 650 600 228 229 401 496 703 205 376
Μπορείς να μου διαβάσεις τον τελευταίο αριθμό; :)

Για τον κάθε συνδυασμό λοιπόν πρέπει να γίνει μια πρόσθεση.

Επειδή δεν είμαι απόλυτα σίγουρος για τα παραπάνω, παρακαλώ ας σχολιάσουν οι υπόλοιποι.
Αν όμως έχω δίκιο, καταλαβαίνεις ότι για τέτοιους υπολογισμούς τα PC μας δεν είναι έτοιμα ακόμη.

Φιλικά
Ανδρέας

mdragon 16-12-10 13:43

Καλημέρα σε όλους,
το ξέρω ότι ακούγεται υπερβολικό αλλά θα σας εξηγήσω και πιστεύω πως θα με
καταλάβετε.
Κάθε μήνα γίνονται κάποιες εργασίες - ποσά (περίπου 100).
Θα πρέπει λοιπόν να επισυνάπτω πίσω από την πιστοποίηση - αρχικό ποσό
τις επιμέρους εργασίες και να συμφωνώ στο σύνολο μόνο με απόκλιση ολίγων λεπτών.
Αυτό το κάνω κάθε φορά χειροκίνητα και έλεγα μπας και το γλυτώσω.:pchit:


Όπως καταλαβαίνετε Θανάση, Γιώργο και Ανδρέα ....... έχω πρόβλημα........:icon_choc:





Φιλικά,
Μάρω

gr8styl 16-12-10 14:03

Παράθεση:

Αρχική Δημοσίευση από officeandi (Μήνυμα 4712)
Στη συνέχεια ξεκινούμε ένα for loop από το j=1 έως το 100, όπου το κάθε j το μεταφράζουμε κάθε φορά στο δυαδικό σύστημα (bitmask).
.....
Επειδή δεν είμαι απόλυτα σίγουρος για τα παραπάνω, παρακαλώ ας σχολιάσουν οι υπόλοιποι.
Αν όμως έχω δίκιο, καταλαβαίνεις ότι για τέτοιους υπολογισμούς τα PC μας δεν είναι έτοιμα ακόμη.

Φιλικά
Ανδρέας

Σωστά φίλε Ανδρέα με μια διόρθωση ότι το loop θα χρειαστεί να πάει μέχρι τον αριθμό που δεν διαβάζεται και όχι το 100. :011:

Ακριβώς αυτή είναι και η δική μου προσέγγιση αν δεις στο προηγούμενο μήνυμά μου που μάλλον γράφαμε παράλληλα. Εγώ βέβαια το προσέγγισα με απλές συναρτήσεις του Excel και όχι VBA.
Τέλος δεν θα έλεγα ότι το πλήθος των συνδυασμών είναι αυτό που θα μας εμποδίσει να κάνουμε τους υπολογισμούς.
Είναι απλά θέμα χρόνου. Δηλαδή ποσο θα περιμένουμε για να πάρουμε την απάντηση. Το λές άλλωστε και στην υπογραφή σου "Οι υπολογιστές είναι εδώ για να μας λύνουν προβλήματα, που δίχως αυτούς δε θα είχαμε !! "

Τώρα αν κάποιοι διαφωνούν ας το καταθέσουν έμπρακτα για να λύσει και η Μάρω το πρόβλημά της.

Τα λέμε
Θανάσης

editolis 16-12-10 14:19

1 Συνημμένο(α)
Διαβαζοντας τα ποστ των φιλων του φορουμ καταθετω μια ΒΔ της ACCESS που την ειχα για καποιον αλλο σκοπο αλλα νομιζω οτι αντικατροπτιζει πανω - κατω αυτο που ζητατε.

Μια γεννητρια αριθμων.

Οι ειδικοι του EXCEL εαν μπορουν να το μετατρεψουν. Πιστευω οτι μπορει να γινει.

Καλη συνεχεια...:d020:

gr8styl 16-12-10 14:20

Παράθεση:

Αρχική Δημοσίευση από mdragon (Μήνυμα 4714)
....
Κάθε μήνα γίνονται κάποιες εργασίες - ποσά (περίπου 100).
Θα πρέπει λοιπόν να επισυνάπτω πίσω από την πιστοποίηση - αρχικό ποσό
τις επιμέρους εργασίες και να συμφωνώ στο σύνολο μόνο με απόκλιση ολίγων λεπτών.
....

Συγνώμη αλλά δεν το καταλαβαίνω. :wall:
Δηλαδή το αρχικό ποσό δεν έχει σχέσει με τις εργασίες ?
Γίνονται εργασίες χωρίς να υπάρχουν χρήματα ?
πιστοποίηση = ???

Συγχωρέστε μου την άγνοια. :dft001:

mdragon 16-12-10 14:52

Δυστυχώς Θανάση μου δεν μπορώ να στο εξηγήσω διαφορετικά για να το καταλάβεις.
Δεν έχω τον τρόπο.
Δέξου μόνο ότι έτσι έχουν τα δεδομένα 100 αριθμοί (περίπου) που με τον αντίστοιχο
συνδυασμό θα μας δίνουν σαν αποτέλεσμα το ποσό που θα ορίζω εγώ.





Φιλικά,
Μάρω

kapetang 16-12-10 19:33

Καλησπέρα στην παρέα

Όπως αναφέρθηκε (Θανάσης, Αλέξανδρος) ο αλγόριθμος για την επίλυση του προβλήματος της Μάρως απαιτεί τεράστιο αριθμό επαναλήψεων. Θεωρητικά 2^n , όπου n το πλήθος των κελιών που περιέχουν τους αριθμούς από τους οποίους θα σχηματιστεί το άθροισμα.
Χωρίς να ξέρω λεπτομέρειες, έχουν αναπτυχθεί αλγόριθμοι οι οποίοι περιορίζουν δραστικά το πλήθος των επαναλήψεων και δίνουν εφικτές λύσεις.
Το πρόβλημα προσομοιώνεται με την ακόλουθη εξίσωση: T1*X1+T2*X2+ …+ Tn*Xn=S των n μεταβλητών, όπου:
  • Ti είναι τα κελιά που έχουν τις τιμές.
  • Xi είναι μεταβλητές με τιμή 1, όταν επιλέγεται η τιμή του αντίστοιχου κελιού και 0 όταν δεν επιλέγεται.
  • S Η τιμή προς την οποία θα συγκλίνει το άθροισμα.
Η παραπάνω εξίσωση είναι ακέραια γραμμική και μπορεί να λυθεί με τη μέθοδο Simlex.
Όπως διάβασα στο διαδίκτυο το πρόσθετο Solver (Επίλυση) του excel περιλαμβάνει τη μέθοδο Simlex και συνεπώς θα μπορούσε να χρησιμοποιηθεί για τη λύση του προβλήματος. Έτσι θα ξεπερνούσανε τον σκόπελο των συναρτήσεων και του κώδικα.
Αν και εγκατέστησα το πρόσθετο δε μπόρεσα να το εφαρμόσω, επειδή δε βρήκα στο διαδίκτυο λεπτομέρειες χρήσεις του στα ελληνικά. Με τα αγγλικά δεν έχω καλές σχέσεις.
Πιστεύω ότι η υπόλοιπη παρέα (Μάρω, Θανάσης, Αλέξανδρος, Τόλης ....) θα τα καταφέρει.Μια λύση «της πυρκαγιάς» είναι να εφαρμοστεί ο αλγόριθμος που δημιούργησα σε VBA για τη βέλτιστη κοπή ράβδων, με κάποια προσαρμογή και με κάποια δυσκολία για μένα που δεν είμαι εξοικειωμένος με τα αντικείμενα του excel.
Ο αλγόριθμος έχει περιορισμούς και προκειμένου να δω αν μπορεί να εφαρμοστεί, Μάρω θα σου βάλω δύσκολα.
Αν υποθέτουμε ότι οι τιμές στα 100 περίπου κελιά είναι ταξινομημένες κατά αύξουσα σειρά και έχουμε σχηματίσει και τα μερικά αθροίσματα, ποια είναι η τάξη του κελιού που για πρώτη φορά το μερικό άθροισμα υπερβαίνει τον αριθμό προς τον οποίο θα συγκλίνει το άθροισμα;
Αυτό εξαρτάται. Αν επιλέξουμε μεγάλο αριθμό και οι τιμές στα κελιά είναι μικρές μπορεί να γίνει πχ στο 90ο κελί, οπότε τη βάψαμε. Αν όμως ισχύει το αντίθετο μπορεί να γίνει πχ στο 7ο κελί, οπότε υπάρχει λύση.

Φιλικά/Γιώργος

officeandi 17-12-10 16:44

2 Συνημμένο(α)
Αγαπητή Μάρω,

Νομίζω ότι κατάφερα να γράψω ένα πρόγραμμα που βρίσκει τα πιο κατάλληλα μερικά ποσά, όπως βλέπεις και στις φωτογραφίες που έχω ανεβάσει.

Από το Excel αρχείο που ανέβασες πήρα τις τιμές για να δοκιμάσω. Εδώ οι μεταβλητές είναι 8, οπότε τα αποτελέσματα τα έχεις σε χρόνο μηδέν.

Θα χρειαζόμουν όμως ένα παράδειγμα που να ανταποκρίνεται στην πραγματικότητα.

Όπως βλέπεις το πρόγραμμα δεν είναι γραμμένο σε Excel.
Εκτός από τις λύσεις που θα προσφέρει το πρόγραμμα, θα πρέπει να ληφθούν και ορισμένα άλλα πράγματα υπόψη.
  • Επειδή δε ξέρω πόση ώρα θα δουλεύει το πρόγραμμα μέχρι να βρει τους πιο κατάλληλους συνδυασμούς, θα πρέπει τουλάχιστον ανά πάσα στιγμή να δείχνει που βρίσκεται και ο χρήστης να μπορεί να το διακόψει, (π.χ. έδωσε κάποια στοιχεία λάθος)
  • Το PC θα πρέπει να μπορεί να κάνει συγχρόνως και άλλες δουλειές και το βασικότερο σε τακτά χρονικά διαστήματα να ενημερώνει το γραφικό περιβάλλον δίνοντας πληροφορίες που βρίσκεται και πόσο έχει ακόμη μπροστά του(π.χ. ProgressBar).

Σημειώνω για τα υπόλοιπα μέλη ότι τα παραπάνω είναι κάπως δύσκολο να υλοποιηθούν σε VBA, διότι στις πράξεις που γίνονται, αν δεν έχει ορισθεί διαφορετικά, τις αναλαμβάνει το UI-thread του Excel. Γι’ αυτό φαίνεται το Excel σα να έχει κολλήσει. Συνεπώς χρειάζεται κάτι σαν ένα BackgroundWorker.

Σε παρακαλώ, ανέβασε ένα από τα πραγματικά σου σενάρια όσο το δυνατό το γρηγορότερο για να κάνω κι εγώ μια σειρά από τεστ όσο το δυνατό το γρηγορότερο.

Φιλικά
Ανδρέας

gr8styl 18-12-10 00:30

2 Συνημμένο(α)
Κατ αρχήν καλησπέρα/καλημέρα σε όλους.

Απλά θέλω να διευκρινίσω μερικά πράγματα
1) Από το 6ο ποστ του θέματος έχω ανεβάσει το from_cuts2sums.xls που λύνει το πρόβλημα με 12 αριθμούς και auto-calculation. Δείτε το εδώ
2) Η ΜΟΝΗ πλήρης και έγκυρη λύση για το πρόβλημα με 100 αριθμούς είναι η δημιουργία και ο έλεγχος των 2^100 συνδυασμών.
3) Η πρόταση του φίλου Γιώργου (kapetang) για χρήση της Επίλυσης (solver) δεν μας δίνει καμιά απολύτως εγγύηση όταν οι αριθμοί είναι περισσότεροι από 32

Για του λόγου το αληθές ενώ άφησα το PC μου να δουλεύει με Excel 2010 όλη νύχτα χθες με 100 τυχαίους αριθμούς (από 1,00 έως 9999,99) και ζητούμενο ένα τυχαίο άθροισμα μεταξύ 10.000,00 και 99.999,99 το πρωί βρήκα την λύση που θα δείτε στο συνημμένο η οποία είναι πλήρως αποδεκτή. Δείτε την συνημμένη εικόνα.

Όσες φορές όμως και αν ξαναπροσπάθησα να λύσω το πρόβλημα με "Επίλυση" δεν μου έδωσε καμιά αποδεκτή λύση.:016:

Σε ξένα sites βρήκα διάφορα περί "επίλυσης", αλλά από ότι δείχνουν τα πειράματά μου και οι δοκιμές μου ( αλλά και τα σχόλια των χρηστών στα ξένα sites) όταν έχουμε πολλές μεταβλητές (στη περίπτωσή μας 100) ο περιορισμός δυαδικών τιμών (binary) δεν λαμβάνεται υπόψιν από το πρόσθετο της επίλυσης. Ο solver μπερδεύεται όπως λένε οι δημιουργοί του.:023:

Τώρα η φίλη Μάρω από την άλλη δεν μας δίνει τα αναγκαία στοιχεία
"Δέξου μόνο ότι έτσι έχουν τα δεδομένα 100 αριθμοί (περίπου) που με τον αντίστοιχο συνδυασμό θα μας δίνουν σαν αποτέλεσμα το ποσό που θα ορίζω εγώ."
άρα μάλλον μιλάμε για να μιλάμε και να καταναλωνόμαστε. :hammer-smilies-0001

Μάρω μου, και εγώ θέλω 10.000.000 euro αλλά που θα τα βρω δεν με απασχολεί. Εσύ θα πρέπει να μου απαντήσεις απλά δεχόμενη ότι θέλω 10 εκατομμύρια. Φαντάζομαι ότι δεν μπορείς να βοηθήσεις σε αυτή την περίπτωση. Νομίζω θα συμφωνήσεις μαζί μου !!! :hmm:

Πιστεύω ότι σαφώς πρέπει να υπάρχει σχέση μεταξύ αριθμών και ζητούμενου αποτελέσματος αλλιώς δεν είναι δυνατόν να εγγυηθούμε κάποια λύση, και προσωπικά δεν διαθέτω τις γνώσεις για τον προσδιορισμό αυτής της σχέσης, αφού μάλλον αγνοώ τι σημαίνει "πιστοποίηση".

Αν σας έλεγα βρείτε τους πραγματικούς θετικούς αριθμούς που μας δίνουν σαν σύνολο άθροισμα 5 η απάντηση είναι ότι οι αριθμοί μπορεί να είναι άπειροι.
Αν σας έλεγα όμως να βρείτε του ακέραιους θετικούς αριθμούς τότε θα μπορούσατε να δώσετε μια ή περισσότερες απαντήσεις.
Αν σας έδινα κάποιους αριθμούς και σας ζητούσα να βρείτε αυτούς που μας δίνουν άθροισμα 5 θα μου απαντούσατε ότι ότι απλά δεν στέκει το ερώτημα και σαν λείπουν λεπτομέρειες, γιατί αν όλοι οι αριθμοί είναι μεγαλύτεροι του ζητούμενου αθροίσματος ΔΕΝ ΥΠΑΡΧΕΙ ΛΥΣΗ. Το αν υπάρχει λύση και ποια, εξαρτάται από τους συγκεκριμένους αριθμούς και το πλήθος τους.

Ελπίζω να είναι σαφές ότι η φίλη Μάρω πρέπει να βοηθήσει περισσότερο αν θέλει να βρεθεί κάποια λύση στο ζητούμενο, αλλιώς όποιος θέλει μπορεί να παλέψει το "έλεγχος όλων των 2^100 συνδυασμών" με κάποιο κώδικα.
Εναλλακτικά αν θέλετε παίξτε με το χωρισμό των 100 αριθμών σε δωδεκάδες (ποστ #6) και μοιράστε το τελικό ποσό σε ανάλογα τμήματα οπότε να υπολογίσετε 8-9 επιμέρους αθροίσματα.

Συγνώμη αν υπήρξα κουραστικός αλλά ήθελα να κάνω τις παραπάνω διευκρινήσεις.


Δείτε το συνημμένο xlsx (excel 2010) για το πως θα μπορούσε να γίνει χρήση του πρόσθετου Επίλυση (solver) που πρότεινε ο φίλος Γιώργος, και σε μια νύχτα έδωσε αποδεκτή λύση για τους συγκεκριμένους 100 τυχαίους αριθμούς και το συγκεκριμένο επιθυμητό αποτέλεσμα αθροίσματος !!!
Δεν θα το διακινδυνεύσω να πω ότι μέσω solver έχετε τη λύση.


Θανάσης.

Tasos 18-12-10 02:06

1 Συνημμένο(α)
Καλημέρα σε όλους!
Δείτε το συνημμένο παράδειγμα παρακάτω για αρχή.

Θεωρητικά μπορεί να συνδυάζει 1000 νούμερα και νομίζω ότι είναι αρκετά γρήγορο.
Έχει ακόμα μεγάλα περιθώρια βελτίωσης αλλά κι έτσι που είναι λειτουργεί ικανοποιητικά.

Τα λέμε... καλό ξημέρωμα!

Τάσος

gr8styl 18-12-10 11:35

Παράθεση:

Αρχική Δημοσίευση από Tasos (Μήνυμα 4730)
Καλημέρα σε όλους!
Δείτε το συνημμένο παράδειγμα παρακάτω για αρχή.

Θεωρητικά μπορεί να συνδυάζει 1000 νούμερα και νομίζω ότι είναι αρκετά γρήγορο.
Έχει ακόμα μεγάλα περιθώρια βελτίωσης αλλά κι έτσι που είναι λειτουργεί ικανοποιητικά.

Τα λέμε... καλό ξημέρωμα!

Τάσος


Πολύ καλό !!!
ΜΠΡΑΒΟ Τάσο.

Θα πρότεινα να το ανεβάσεις στα χρήσιμα.


kapetang 18-12-10 17:31

Καλησπέρα στην παρέα

Φίλε Θανάση ευχαριστώ για τις πληροφορίες σχετικά με το Solver και τις δοκιμές, που έκανες. Πίστευα ότι είναι κομμένο και ραμμένο για το πρόβλημα της Μάρως. Φαίνεται όμως ότι ήμουν υπερβολικά αισιόδοξος.
Αγαπητέ Αλέξανδρε θα με ενδιέφερε να δω την προσέγγισή σου ( έτσω με εικονικά δεδομένα) και πιστεύω σ’ αυτό να συμφωνούν και οι υπόλοιποι.
Τάσο μου χτύπησες την κατάλληλη στιγμή. Είχα αρχίσει να προσαρμόζω, στο ζητούμενο, τη λύση για τη βέλτιστη κοπή, που έχει πολλούς περιορισμούς και ευτυχώς με πρόλαβες.
Ένα μεγάλο μπράβο και από μένα :thumbup:. Θα μελετήσω τον κώδικα και ίσως αντιληφθώ τον «σφαιράτο» αλγόριθμο, που χρησιμοποίησες. Διαφορετικά θα ζητήσω φροντιστήριο :hammer-smilies-0001.
Αγαπητή Μάρω συνέχισε να βάζεις δύσκολα και να μας προβληματίζεις.

Γιώργος

mdragon 18-12-10 18:18

Παράθεση:

Αρχική Δημοσίευση από gr8styl (Μήνυμα 4728)
Τώρα η φίλη Μάρω από την άλλη δεν μας δίνει τα αναγκαία στοιχεία
"Δέξου μόνο ότι έτσι έχουν τα δεδομένα 100 αριθμοί (περίπου) που με τον αντίστοιχο συνδυασμό θα μας δίνουν σαν αποτέλεσμα το ποσό που θα ορίζω εγώ."
άρα μάλλον μιλάμε για να μιλάμε και να καταναλωνόμαστε. :hammer-smilies-0001

Μάρω μου, και εγώ θέλω 10.000.000 euro αλλά που θα τα βρω δεν με απασχολεί. Εσύ θα πρέπει να μου απαντήσεις απλά δεχόμενη ότι θέλω 10 εκατομμύρια. Φαντάζομαι ότι δεν μπορείς να βοηθήσεις σε αυτή την περίπτωση. Νομίζω θα συμφωνήσεις μαζί μου !!! :hmm:

Πιστεύω ότι σαφώς πρέπει να υπάρχει σχέση μεταξύ αριθμών και ζητούμενου αποτελέσματος αλλιώς δεν είναι δυνατόν να εγγυηθούμε κάποια λύση, και προσωπικά δεν διαθέτω τις γνώσεις για τον προσδιορισμό αυτής της σχέσης, αφού μάλλον αγνοώ τι σημαίνει "πιστοποίηση".

Θανάσης.

Φίλε Θανάση καλησπέρα,
νομίζω πως με παρεξήγησες ...... δεν κατάφερα να σε κάνω να με καταλάβεις για τον ίδιο λόγο που δεν θα καταλάβαινα τη δουλεία ενός γιατρού αφού είμαι μια απλή λογίστρια :scratch_one-s_head:
Από την άλλη νομίζω πως το παράδειγμα σου ήταν ατυχές γιατί δεν χρησιμοποιώ την excel για να παίξω tetris ούτε να περάσω την ώρα μου. Ειναί κλειδί της δουλειάς μου και για το λόγο αυτό σου είπα απλά να δεχτείς ότι έτσι έχουν τα πράγματα.
Στην προσπάθεια να κατανοήσεις το πρόβλημά μου "κόλλησες" στη λέξη πιστοποίηση..... είναι αυτό που λέμε ...... βλέπεις το δέντρο και χάνεις το δάσος !!!!
Και για να μην σε αφήσω με την απορία πιστοποίηση είναι η ανάλυση της δουλειάς κάποιου μεταφραζόμενη σε ποσότητα επι τιμή (αναλυτικά). Στην ουσία εκεί πρέπει αναφέρεις λεπτομερώς τις εργασίες σου κοστολογόντας τις.
Όπως και να έχει σε ευχαριστώ για την προσπάθειά σου.
:friends: ???


Σας ευχαριστώ ΟΛΟΥΣ πραγματικά για την ανταπόκρισή σας στο πρόβλημα μου και σας εύχομαι καλά Χρίστουγεννα με υγεία.
Ένα μεγάλο-μεγάλο ευχαριστώ στο Forum και έυχομαι να χιλιάσει τα μέλη του για να έχουμε περισσότερα προβλήματα να λύνουμε και συνεπώς περισσότερο ελεύθερο χρόνο για όλους μας.

Μάρω

officeandi 18-12-10 21:41

Καλησπέρα σε όλους,

Κι εγώ θα ήθελα να συγχαρώ τον Τάσο για τη λύση που δίνει, αφού οι περισσότεροι από εμάς δε φαντάζονταν να φτάνει κανείς τόσο γρήγορα στο αποτέλεσμα. Εγώ μάλιστα συνεχίζω να είμαι αυτής της άποψης.

Θα ήθελα όμως να το σχολιάσω και λίγο.

Παράθεση:

1) Από το 6ο ποστ του θέματος έχω ανεβάσει το from_cuts2sums.xls που λύνει το πρόβλημα με 12 αριθμούς και auto-calculation. Δείτε το εδώ
2) Η ΜΟΝΗ πλήρης και έγκυρη λύση για το πρόβλημα με 100 αριθμούς είναι η δημιουργία και ο έλεγχος των 2^100 συνδυασμών.
3) Η πρόταση του φίλου Γιώργου (kapetang) για χρήση της Επίλυσης (solver) δεν μας δίνει καμιά απολύτως εγγύηση όταν οι αριθμοί είναι περισσότεροι από 32
Καταρχήν, συμφωνώ απολύτως με το Θανάση και στα τρία σημεία που επισημαίνει.

Τάσο, αν κατάλαβα καλά, το πρόγραμμα με την εκκίνηση ακολουθεί βάση του recursion που έχει, μια δενδροειδή αναζήτηση, έτσι ώστε στην κατεύθυνση που ψάχνει, αν δεν καταλήξει εντός ορίων ανοχής, να κάνει το backtracking. Δηλαδή να αλλάξει κατεύθυνση, δίχως να χρειάζεται να διανύσει όλο το δρόμο προς τα πίσω. Αν κατά το ψάξιμο πετύχει ένα άθροισμα να είναι εντός ορίων ανοχής, τότε σταματά.

Αν στέκουν τα παραπάνω, τότε σίγουρα έχει βρει την πρώτη λύση. Αυτό δε σημαίνει ότι έχει βρει και την ιδανική.

Θα σου ήμουν ευγνώμων, αν μου(μας) εξηγούσες λίγο τη στρατηγική που ακολουθείς.

Στη συνέχεια (κάτι άσχετο με το πρόβλημα) παρατήρησα ότι χρησιμοποιείς το DoEvents, και θυμήθηκα τον πονοκέφαλο που μου έχει προξενήσει αυτή η εντολή. Με την εντολή αυτή καταφέρνει το παράθυρο του Excel (και συνεπώς το UI-thread) να επεξεργαστεί τυχόν μηνύματα που στέλνει το λειτουργικό (message-pump). Έτσι μπορεί το παράθυρο να αντιδρά σε εντολές του χρήστη. Αυτό όμως επιτρέπει στο χρήστη παράλληλα, να ξεκινήσει δεύτερη αναζήτηση, ενώ τρέχει η πρώτη!



Φιλικά
Ανδρέας

gr8styl 19-12-10 01:27

Καλησπέρα/Καλημέρα σε όλους και όλες.

Επειδή δεν μου αρέσουν οι προσωπικές διαμάχες θα περιοριστώ στο να πω ότι:
όταν εγώ ρώτησα όχι μόνο για το δάσος:
"Δηλαδή το αρχικό ποσό δεν έχει σχέση με τις εργασίες ?"
ρώτησα και για το δέντρο:
"Γίνονται εργασίες χωρίς να υπάρχουν χρήματα ?"
και ζήτησα να μάθω ακόμα και το είδος του δέντρου:
"πιστοποίηση = ???"

Δεν πήρα συγκεκριμένη απάντηση σε κανένα από τα 3 ερωτήματα και ερμήνευσα την απάντηση σαν:

"δεν μας γ..... Αν μπορείς δώσε μου την λύση σε αυτό που ζητάω και μην με σκοτίζεις."
Γεγονός που με δυσαρέστησε :angry: και έκφρασα σε επόμενο μήνυμα μου.

Μάλλον πρόκειται για παρεξήγηση (και ίσως λάθος ερμηνεία της απάντησης) που όμως νομίζω ξεκαθάρισε. :friends:

Τέλος καλό όλα καλά βρέθηκε κάποια λύση και αυτό μετράει. :047:

Πάμε παρακάτω.

Θέτω λοιπόν νέο διπλό ερώτημα::023:

α) Χρειάζεται να συνεχίσουμε το ψάξιμο; Μιας και η πολύ καλή λύση του Τάσου "δεν ικανοποιεί πλήρως" το ζητούμενο όπως το προσδιόρισε τόσο ο ίδιος λέγοντας "σαν αρχή..." αλλά και ο Ανδρέας λέγοντας ότι "έχει βρει την πρώτη λύση" και όχι απαραίτητα την ιδανική.
(Δηλαδή αν έχουμε σαν αριθμούς τους αριθμούς από 1-9 και ψάχνουμε αποτέλεσμα 9 θα μας δώσει σαν λύση το 1, 2, 6 και όχι το 9 που όπως είπε η Μάρω είναι το επιθυμητό αποτέλεσμα.
Με άλλα λόγια το ποια λύση θα πάρουμε με το κώδικα του Τάσου εξαρτάται από το πως είναι καταχωρημένοι οι αριθμοί μας. Ο κώδικας δεν λαμβάνει καθόλου υπόψιν το πόσοι αριθμοί συμμετέχουν στο αποτέλεσμα.
Μια ταξινόμηση κατά αύξουσα σειρά (δυνατότητα που μας δίνει ο Τάσος με το checkbox) νομίζω θα μας δώσει πάντα την λύση με το μεγαλύτερο πλήθος αν δεν κάνω λάθος. Το αντίστροφο δηλαδή μια ταξινόμηση με φθίνουσα σειρά δεν νομίζω ότι θα μας δώσει την λύση με το μικρότερο πλήθος.
)
Για να βρούμε δηλαδή την ιδανική λύση πρέπει να εξετάσουμε όλους τους συνδυασμούς όπως έχω ήδη πει.

ή β) θεωρούμε ότι έχει καλυφθεί το θέμα; Άρα πάμε για άλλα.

Γεγονός είναι ότι το συγκεκριμένο ερώτημα έφερε στην επιφάνεια δύο νέα για το φόρουμ μας ζητήματα:
1) Επίλυση (Solver) στο excel και 2) χρήση recursion σε κώδικα VBA.
όπου ίσως θα ήταν σκόπιμο να ανοιχτούν σαν νέα θέματα αν υπάρχει ανάγκη.

Φιλικά
Θανάσης

mdragon 19-12-10 19:28

Συμφωνώ μαζί σου Θανάση στο θέμα της ταξινόμησης.
Η λύση του Τάσου με γλύτωσε πάντως από ένα μεγάλο πονοκέφαλο.
Δεν είμαι πλεονέκτρα αλλά αν υπήρχε λύση για μικρότερο πλήθος δεν θα έλεγα όχι :015:.
Δυστυχώς οι γνώσεις μου δεν φτάνουν μέχρι εκεί για να μπορώ να βοηθήσω παραπάνω.



Την καλησπέρα μου,
Μάρω

gr8styl 20-12-10 00:56

Καλησπέρα/ καλημέρα σε όλους και όλες

Φίλε Τάσο,
υπάρχει κάποιο λάθος στο xl_CompineNumbers.xls που ανέβασες, και δεν εννοώ το p αντί του b για το combine :033:
Αν δώσουμε σαν αριθμούς
8 , 7, 6, 5, 3, 2 χωρίς ταξινόμηση
ή αν ο πρώτος αριθμός είναι μεγαλύτερος του ζητούμενου, δηλαδή
για τους αριθμούς
11, 9 , 3, 6 χωρίς ταξινόμηση

Με ζητούμενο αποτέλεσμα 9 και στις δύο περιπτώσεις δεν βρίσκει λύση, ενώ είναι προφανές.

Κάνω λοιπόν μια πρόταση/διόρθωσης :dft001:
αλλάζουμε το τελευταίο "Exit FOr" σε "ccrMatch = ccrMatch - ArrItems(x)" και έτσι νομίζω ότι λύνεται το πρόβλημα.

Τώρα για το ελάχιστο πλήθος νομίζω ότι θα γίνει πολύ χρονοβόρα για να εξετάσει όλους τους συνδυασμούς και να βρει τον ιδανικό.
Μάλλον θα πρέπει να αρκεστούμε στην αντίστροφη ταξινόμηση που όμως όπως προείπα ναι μεν δεν εγγυάται το ελάχιστο πλήθος, αλλά είναι σαφώς μικρότερο από την αύξουσα ταξινόμηση η οποία δίνει το μέγιστο πλήθος.

Ας αλλάξουμε λοιπόν και το "Order1:=xlAscending" σε "Order1:=xlDescending" στην CommandButton2_Click()

Καλή βδομάδα σε όλους και καλές γιορτές.
Θανάσης :icon_out:

ΥΓ. Τάσο, ξαναλέω ότι θα πρέπει να το ανεβάσεις στα χρήσιμα.

Tasos 20-12-10 09:30

1 Συνημμένο(α)
Φίλοι μου καλημέρα!

Το αρχικό συνημμένο που είχα ανεβάσει φτιάχτηκε "στα γρήγορα" λόγω ώρας (δείτε την ώρα του
μηνύματος...) και φόρτου εργασίας:001_rolleyes: αφήνοντας το ανοιχτό για οποιαδήποτε προγραμματιστική βελτίωση /επέκταση.
Στο παρακάτω συνημμένο πρόσθεσα κάποιες λεπτομέρειες, λαμβάνοντας υπ όψη μου τις παρατηρήσεις σας.
Φυσικά όποιος θέλει μπορεί να το μετατρέψει/βελτιώσει ή να κάνει τις παρατηρήσεις του.

Να είστε καλά

Τάσος

gr8styl 20-12-10 19:19

Φίλε Τάσο,
Το πρόβλημα που περιέγραψα στο προηγούμενο post (αριθμοί 11, 9, 3 ζητώντας το 9) δεν δίνει λύση, ενώ είναι προφανής.
θα πρέπει όπως είπα:
να αλλάξουμε το τελευταίο "Exit FOr" σε "ccrMatch = ccrMatch - ArrItems(x)" τέταρτη γραμμή από το τέλος της CompineNumbers(...)
Με το Exit For αγνοείς τις υπολειπόμενες συγκρίσεις, και παρότι πολύ σωστά αφαιρείς την τελευταία καταχώρηση από την NowVal (NowVal.Remove NowVal.Count) δεν αφαιρείς από το ccrMatch την τιμή της.
Νομίζω ότι αυτό είναι λάθος στην περίπτωση όπου το ccrMatch δεν είναι μικρότερο από το (SetPt + 0.001 + ccrValOver).

Τι λες μήπως κάνω εγώ λάθος; :dft012:

Τα λέμε.
Θανάσης.

Tasos 20-12-10 22:55

Φίλε Θανάση καλησπέρα!
Έχεις δίκιο με τη γραμμή "ccrMatch = ccrMatch - ArrItems(x)"

Στην αρχή, όταν έκανα τις δοκιμές μου το είχα κι εγώ έτσι (είναι λογικό).
Όμως λαμβάνοντας υπόψη μου:
Παράθεση:

1. Την μέχρι και 500% αύξηση χρόνου που προκαλεί η γραμμή αυτή κατά την εκτέλεση του Script.

2. Τον λόγο δημιουργίας/ύπαρξης αυτού του αρχείου.
Δεν φτιάχτηκε για να υπολογίζει 5 - 10 αριθμούς αλλά εκατοντάδες, ακόμα και χιλιάδες, κάτι που είναι αδύνατο για τον ανθρώπινο νου.
(που όπως φαίνεται και στην πράξη το κάνει σωστά!)

αποφάσισα να αλλάξω την "ccrMatch...." σε Exit for!

Σε κάθε άλλη περίπτωση θα χρησιμοποιούσα την "ccrMatch...."

Καλό βράδυ!

Τάσος

nisgia 21-12-10 02:53

1 Συνημμένο(α)
Γεια και χαρά στη παρέα!

Μιας και (όπως λέτε) το θέμα βρίσκεται ακόμη στο "εργαστήριο", αν έχετε ακόμη όρεξη,
δείτε στο συνημμένο και μια δική μου (για την ώρα όχι και τόσο έξυπνη) πρόταση.

Χωρίς να έχω δει τις τελευταίες εξελίξεις, είχα σκεφτεί και εγώ τη χρήση αναδρομής (προφανώς Τάσο είχαμε συνάντηση πνευμάτων πάλι :grin:)
μιας και η σειριακή υλοποίηση τέτοιων περιπτώσεων μοιάζει αρκετά δύσκολη (αν όχι αδύνατη).

Η συνάρτηση SumNums στο συνημμένο, αθροίζει όσο γίνεται πιο κοντά στον στόχο τα διαθέσιμα ποσά, επαναλαμβάνει τη διαδικασία
καλώντας τον εαυτό της κάθε φορά με διαφορετική θέση εκκίνησης και στην επιστροφή της συγκρίνονται τα αθροίσματα
και επιλέγεται το μεγαλύτερο άρα και πιο κοντινό στο στόχο.
Για την ώρα, τα αθροίσματα που επιστρέφει είναι πάντα μικρότερα ή ίσα του στόχου.
(Αν φυσικά υπάρχει διαθέσιμο ποσό μικρότερο ή ίσο του στόχου.)

Όταν την έγραφα, είχα στο μυαλό μου τα διαθέσιμα ποσά σε φθίνουσα ταξινόμηση και νομίζω πως έτσι δουλεύει και καλύτερα.

Στην περιοχή "Ομάδα1" του μοναδικού φύλλου έχει εισαχθεί η προσαρμοσμένη συνάρτηση χρήστη (UDF) SumTarget
ως τύπος πίνακα (Ctrl+Shift+Enter) πολλαπλών κελιών η οποία χρησιμοποιεί τη συνάρτηση SumNums
και επιστρέφει τα ποσά που επιλέχθηκαν για το άθροισμα-στόχο1.
Στις υπόλοιπες ομάδες ο τύπος λαμβάνει υπόψη τα ποσά που έχουν χρησιμοποιηθεί στις προηγούμενες ομάδες
ώστε να αποφευχθεί η επιλογή ενός διαθέσιμου ποσού άνω της μιας φοράς.

Αν δεν βαριέστε λοιπόν, κάντε μερικές δοκιμές, και αν προκύψουν, θέστε και τα σχόλια σας. :003:

Ομολογώ πως, όπως αυτό της βέλτιστης κοπής, έτσι και αυτό εδώ, είναι ένα πάρα πολύ
ενδιαφέρον και προκλητικό για την κοινότητα του φόρουμ θέμα! :drool:
Συνεπώς, δεν έχω παρά να ευχαριστήσω θερμά τη Μάρω που το έθεσε. :thanks: Μάρω!

Αν λοιπόν βρεθεί η βέλτιστη λύση για το άθροισμα βάσει στόχου και βελτιωθεί η λύση της βέλτιστης κοπής,
τότε θα ανοίξουμε και ένα θέμα για τη συμμετρική κατανομή φορτίων σε τριφασικό δίκτυο. :icon_alien:

Εις το επανιδείν λοιπόν!
Γιάννης

mdragon 21-12-10 12:18

Γιάννη καλώς όρισες στην κουβέντα μας,
"έπαιξα" λίγο με το συνημμένο σου αλλά δεν κατάφερα να φτάσω στο επιθυμητό αποτέλεσμα.
Σχεδόν πάντα μου έδινε αποκλίσεις έως και 0,60€ (πράγμα που δεν μας βολεύει).
Εάν για παράδειγμα δώσουμε το πόσο 1.087,63 μας δίνει απόκλιση έως 0,09€ ενώ θα μπορούσε
να χρησιμοποιήσει τα ποσά:
544,17 €
257,13 €
125,97 €
72,96 €
30,50 €
30,26 €
26,64 €
όπως το παράδειγμα του Τάσου.
Θα το κοιτάξω καλύτερα και αν έχω προτάσεις θα σου πω.
Σε ευχαριστώ πολύ για το χρόνο σου.:wink:


Καλημέρα σε όλους,
Μάρω

kapetang 21-12-10 19:06

Καλησπέρα στην παρέα

Γιάννη, με χαρά βλέπω να συμμετέχεις στο γοητευτικό και ζόρικο πρόβλημα της Μάρως.
Έκανα κάποιες δοκιμές αθροίζοντας κάποιους αριθμούς και βάζοντας ως στόχο το άθροισμά τους. Το πρόγραμμα στην πλειοψηφία των περιπτώσεων έδωσε αποτέλεσμα άμεσα και κοντά στο στόχο. Διαπίστωσα ότι δε χρησιμοποιούσε υποχρεωτικά τους αριθμούς που άθροιζα, γι’ αυτό υπήρχαν και οι μικροαποκλίσεις.
Έπεσα όμως και σε μία περίπτωση που προβληματίζει.
Ενώ υπάρχουν τα ποσά 30,50 και 30,26 (30,50 + 30,26 = 60,76), αν θέσουμε ως στόχο το άθροισμα τους (60,76) παίρνουμε αποτέλεσμα 57,47 (=45,42 + 12,05).

Φιλικά/Γιώργος

officeandi 23-12-10 00:18

1 Συνημμένο(α)
Γειά σε όλους σας,

προσπάθησα κι εγώ να ψάξω για μια καλή λύση.

Ουσιαστικά ακολούθησα την τακτική του Τάσου (concept), θέλησα να αποφύγω όμως την υλοποίηση με recursion και να δώσω μια iterative λύση (με loops). Το θέμα με μια συνάρτηση, η οποία καλεί τον εαυτό της, είναι, ότι «κοστίζει» πολύ. Επιπλέον το βάθος είναι διαφορετικό σε κάθε compiler.

Το τελευταίο τεστ έδειξε ότι καταφέρνει με 20.000 τιμές μέσα σε λιγότερο από 10 δευτερόλεπτα να δείξει τα 50 καλύτερα αθροίσματα.

Ο κώδικας δεν είναι γραμμένος με VBA, αλλά με C# και ενσωματωμένος στο αρχείο του Excel.

Στο μήνυμα αυτό επισυνάπτω την εγκατάσταση (Setup) του αρχείου, διότι η λύση απαιτεί:
  • MS Office 2007/2010
  • .NET 4 Framework
  • VSTO 2010 (VSTO 4)

Σε περίπτωση που δεν έχετε κάτι από τα παραπάνω, η εγκατάσταση τα κατεβάζει αυτόματα, οπότε εγκαθίστανται και αυτά.

Η απεγκατάσταση γίνεται ως γνωστόν από τον πίνακα ελέγχου.

Το αρχείο Excel έχει ακριβώς ένα φύλλο (BestFit), όπου περιμένει τις τιμές. Οι τιμές μπορούν να γραφούν σε μια στήλη, σε μια σειρά, σε περισσότερες στήλες και σειρές, σε περισσότερα areas (σύνθετες επιλογές). Οι τιμές μπορούν να είναι και συναρτήσεις.

Το πλήθος των κελιών που αποτελεί τα επιμέρους ποσά, πρέπει να είναι επιλεγμένο (selected).
Στη συνέχεια επιλέγετε το «Mdragon-ribbon», όπου εκεί καθορίζετε τη τιμή για το επιθυμητό άθροισμά (GOAL), το όριο ανοχής (EPSILON), και πόσα αποτελέσματα να δείξει (KEEP).Αν επιλέξετε π.χ. 5, τότε δείχνει τα 5 καλύτερα αποτελέσματα (όχι τα 5 πρώτα). Έπειτα START.

Τα αποτελέσματα τα γράφει ανοίγοντας καινούργιο φύλλο εργασίας. Σε περίπτωση που υπάρχει είδη ένα φύλλο με αποτελέσματα, ανοίγει καινούργιο φύλλο εργασίας και το αριθμεί.

Όποιος ενδιαφέρεται, ας κάνει μερικές δοκιμές.

Φιλικά
Ανδρέας

officeandi 23-12-10 01:09

1 Συνημμένο(α)
Και να 'μαι πάλι,

Εδώ ανεβάζω ένα Demo με 20.0000 τιμές (randoms), καθώς και τα TOP50 αποτελέσματα.

Προσοχή! Για ν' αωοιχτεί αυτό το αρχείο χωρίς πρόβλημα, θα πρέπει να έχει γίνει η εγκατάσταση που έστειλα με το προηγούμενο μήνυμα.

Φιλικά
Ανδρέας

nisgia 23-12-10 17:36

1 Συνημμένο(α)
Καλησπέρα στη παρέα!

Επιστρέφω και πάλι με βελτιώσεις στην αρχική μου πρόταση διότι, όπως πολύ σωστά διαπιστώσατε
όσοι μπήκατε στον κόπο να τη δοκιμάσετε, οι αστοχίες της ήταν πάρα πολλές.
Με λίγα λόγια, όχι μόνο έξυπνη δεν ήταν αλλά πολύ χαζή.

Η αλήθεια είναι πως το πιο δύσκολο ήταν να κατανοήσω τον τρόπο σκέψης μου στην αναζήτηση
του πιο κοντινού στο στόχο αθροίσματος μέσα σε μια λίστα με ποσά.
(ίσως αυτό οφείλεται και στο ότι τελευταία το "καίω" με πιο αφηρημένες έννοιες το τσερβέλο μου :worry:)

Αυτή τη φορά όμως νομίζω πως η σημερινή μου προσπάθεια πλησιάζει αρκετά το επιθυμητό
και αυτό φαίνεται να οφείλεται στην πραγματικά αναδρομική (και πολύ πιο απλή) νέα SumNums.
(Δείτε το σχετικό αρχείο "Sum2Target" στο συνημμένο.)

Μετά από μερικές δοκιμές που έκανα (μην φανταστείτε πως εξαντλήθηκα και στα τεστ) όσον αφορά την απόδοση,
αυτό που παρατήρησα είναι πως δεν επηρεάζεται τόσο από το πλήθος των διαθέσιμων ποσών
αλλά από τις "απαιτήσεις" του ζητούμενου αθροίσματος.
Για παράδειγμα, όσο το ζητούμενο άθροισμα πλησιάζει το μέγιστο άθροισμα της λίστας ποσών,
αν το ζητούμενο δεν μπορεί να επιτευχθεί, ο χρόνος ολοκλήρωσης και οι επαναλήψεις (αναδρομές) αυξάνονται εκθετικά.

Γι' αυτό έχω φροντίσει η συνάρτηση SumToTarget να εκτυπώνει κάποια αποτελέσματα στο παράθυρο Immediate
ώστε να γίνει πιο εύκολη η εξέταση της συμπεριφοράς της.
Σε περίπτωση ανάγκης, να θυμάστε πως η εκτέλεση μπορεί να διακοπεί και με Ctrl+Break
όμως μετά θα χρειαστεί Reset η Static μεταβλητή (n) της SumNums.
Αυτό μπορεί να γίνει και με επανεκκίνηση του αρχείου.


Επίσης, αν η προηγούμενη SumNums προτιμούσε τα ποσά σε φθήνουσα ταξινόμηση, η σημερινή (για την ώρα) τα απαιτεί έτσι.

Μάρω και Γιώργο (kapetang), ελπίζω να μην εξάντλησα την υπομονή σας με την πρώτη μου πρόταση και να δώσετε και σε αυτή
μια μικρή προσοχή διότι αυτός που φτιάχνει κάτι δεν είναι σε θέση (ή καλύτερα, δεν θέλει) να εντοπίσει τα μειονεκτήματα του. :021:

Γιώργο (kapetang), χαίρομαι που χαίρεσαι τη συμμετοχή μου αλλά να ξέρεις πως εγώ την απολαμβάνω ειλικρινά.
Όσο για τις αποκλίσεις που ανέφερες, εκτός από την έλλειψη νοημοσύνης της συνάρτησης, ευθύνη έφεραν και οι μεταβλητές
τύπου Double με αποτέλεσμα συνθήκες του τύπου 123,24 = 123,24 να βγαίνουν ψευδείς (!!!).
Γι' αυτόν ακριβώς το λόγο άλλαξα τον τύπο τους με αυτόν του Currency.

Τα λέμε!
Γιάννης

Υ.Γ.
Φίλε Ανδρέα, αρπάζω την ευκαιρία και σε καλωσορίζω και εγώ με τη σειρά μου στην παρέα! :thumbup:

Δυστυχώς δεν είδα ακόμη την πρότασή σου διότι βρίσκομαι σε ξένο υπολογιστή για να φορτώσω Frameworks και VSTOs.
Με βάση την περιγραφή σου όμως μοιάζει να κάνει πάρα πολλά και γρήγορα και αγωνιώ να τη δω.

Θα ήθελα όμως να μου επιτρέψεις να θεωρήσω πως η χρήση γλωσσών τύπου C σε ένα φόρουμ σχεδιασμένο
για χρήστες του MS Office+VBA ξεπερνάει κάπως τα θεματικά του πλαίσια.
Εδώ ο Τόλης μας "βάζει χέρι" όταν δίνουμε "έτοιμες" λύσεις με VBA, πόσο μάλλον όταν η υλοποίηση
δεν μπορεί να εξετασθεί από τον αποδέκτη
. :crying:

Πραγματικά δεν θέλω να με παρεξηγήσεις ως αντίθετο στην (όποια) εξέλιξη ή ως δογματικό όμως πιστεύω
πως η πρόταση εργαλείων εκτός του "πακέτου" (που αναμφίβολα αυξάνουν την αποτελεσματικότητα),
μοιάζει με πρόταση χρήσης εκτυπωτή Inkject σε ομάδα συζήτησης ζωγράφων. :036:

Παρόλο που μοιάζει να στη "λέω" λίγο με το "καλημέρα", θέλω να σε διαβεβαιώσω πως
χαίρομαι ειλικρινά που βρίσκεσαι στη παρέα μας! :happy:

(Σας ζητώ συγγνώμη για το "σεντόνι"...)
Γιάννης

mdragon 23-12-10 19:28

Γιάννη καλησπέρα και χρόνια πολλά.
Έχεις κάνει καλή δουλειά αλλά.......νομίζω πως κάτι δεν παει καλά.
Τι γίνεται στην περίπτωση που δεν έχουμε ακριβές αποτέλεσμα?
Το προσπάθησα πολλές φορές (για ποσά που ήξερα ότι δεν είχα αποτέλεσμα)
και όλες της φορές μου κόλλαγε η excel και δεν ανταποκρινόταν το πρόγραμμα.
Ρίξ΄του μια ματιά και εσύ, δεν ξέρω τι φταίει. :scared:



Φιλικά,
Μάρω

officeandi 24-12-10 23:31

1 Συνημμένο(α)
Καλησπέρα σε όλα τα μέλη,

Εύχομαι σε όλους χαρούμενα Χριστούγεννα, ό,τι ποθείτε, και άντε να δούμε πόσο καλά θα τραγουδήσουμε το «πάει ο παλιός ο χρόνος…».

Αγαπητέ Γιάννη (nisgia),

Κατ’ αρχήν σε ευχαριστώ για το καλωσόρισμα. Είστε μια πολύ καλή παρέα και όποιος αισθάνεται πως βρίσκεται μέσα σε αυτή, είναι σίγουρα υπερήφανος.

Σχετικά με αυτά που αναφέρεις στο μήνυμά σου για μένα, θα ήθελα να ξέρεις, ότι το τελευταίο που θα έκανα, θα ήταν να σε παρεξηγήσω. Ίσα, ίσα αυτό με ώθησε να το ξαναγράψω σε VBA και το επισυνάπτω σε αυτό το μήνυμα. Απλά νιώθω λίγο πιο άνετα με την C#, και νομίζω ότι όταν κάποιος έχει μια ιδέα, προσπαθεί να την καταγράψει όσο πιο εύκολα είναι γι’ αυτόν.

Πολύ σύντομα όμως θα ήθελα να αναφερθώ στους λόγους, για τους οποίους ανέβασα το προηγούμενο σαν εγκατάσταση.
  • Τις επιλογές που πρέπει να κάνει ο χρήστης πριν από την εκκίνηση για την εύρεση των αθροισμάτων, ήθελα να είναι έξω από το φύλλο εργασίας των δεδομένων, διότι οι επιλογές οι ίδιες δεν είναι δεδομένα. Σκέφτηκα να φτιάξω ένα Ribbon, αλλά όπως γνωρίζουμε το Office 2007 δεν έχει τα απαραίτητα εργαλεία. Μια ματιά στη βοήθεια του Excel και ξεκαθαρίζεται αμέσως. Ίσως αυτό όμως να έχει αλλάξει στο Office 2010.
  • Όταν ταξινομώ εσωτερικά το array που σχηματίζεται από την επιλογή του χρήστη, χρησιμοποιώ για αυτό ένα ξένο Module για τη ταξινόμηση, δηλαδή πράγματα, τα οποία σε άλλες γλώσσες έχουν λυθεί εδώ και καιρό. Θα μπορούσα και να ταξινομήσω με τη βοήθεια του Excel, αλλά θεωρώ ότι δεν είναι καλό για το χρήστη να αλλάζει η προβολή των δεδομένων.
  • Τέλος, για να είμαι από μέρος μου σίγουρος ότι ο χρήστης έχει εγκατεστημένο ό,τι χρειάζεται για να λειτουργεί το αρχείο, δημιούργησα την εγκατάσταση. Η εναλλακτική λύση θα ήταν να κατεβάσει ο ίδιος αυτά που χρειάζονται από το Διαδίκτυο σε περίπτωση που δεν τα έχει, να ξέρει που θα τα βρει και να εισάγει ορισμένες ρυθμίσεις στο μητρώο του υπολογιστή, πράγμα επικίνδυνο.

Ο αλγόριθμος σε VBA συμπεριφέρεται ακριβώς το ίδιο. Ως προς την ταχύτητα δεν νομίζω ότι διαφέρει και πάρα πολύ. Ο προηγούμενος ενώ είναι πολύ πιο γρήγορος στον υπολογισμό (και θα μπορούσε να γίνει ακόμη πιο γρήγορος), χάνει ώρα στη επικοινωνία με το Excel. Η μόνη διαφορά είναι ότι ο καινούργιος (VBA) κατά τον υπολογισμό δείχνει και την πρόοδο (ποσοστό).

Προσπάθησα να σχολιάσω τον κώδικά όσο πιο πιο αναλυτικά μπορούσα.

Και πάλι καλά Χριστούγεννα, υγεία και καλή καρδιά σε όλους!

Φιλικά
Ανδρέας


Η ώρα είναι 10:57.

Ms-Office.gr - ©2000 - 2026, Jelsoft Enterprises Ltd.


Search Engine Optimization by vBSEO 3.3.2