panos_saxo Δημοσ. 25 Μαΐου 2016 Δημοσ. 25 Μαΐου 2016 Καλησπέρα , Ψάχνω όπως λέει και στον τίτλο κάποια freeware εφαρμογή που να κάνει το εξής: θέλω να φορτώσω ένα container με χύμα εμπόρευμα (όχι σε παλέτα , με τα κιβώτια ) . το ζητούμενο είναι , να δίνω κάποιες μεταβλητές στην εφαρμογή και πιο συγκεκριμένα μήκος - πλάτος - ύψος κιβωτίου , καθώς και τα αντίστοιχα μέτρα του container και να μου βγάζει πόσα κιβώτια χωράει το container και με ποιό τρόπο θα στηθούν , έτσι ώστε να είναι πλήρως φορτωμένο . δεν ξέρω αν όντως υπάρχει κάτι τέτοιο , ψάχνω από χθες αλλά βρήκα μόνο ένα αντίστοιχο πρόγραμμα που όμως προαπαιτεί να έχω δώσει εγώ την ποσότητα που θέλω να φορτώσω και κατόπιν απλά μου βγάζει τους τρόπους με τους οποίους μπορώ να στήσω τα κιβώτια. ευχαριστώ εκ των προτέρων .
Technology fan Δημοσ. 25 Μαΐου 2016 Δημοσ. 25 Μαΐου 2016 (επεξεργασμένο) Δεν ξέρω αν υπάρχει κάτι έτοιμο αλλά δε πιστεύω... Γενικότερα το πρόβλημα αυτό είναι δύσκολο, στην δική σου όμως περίπτωση πιστεύω οτι είναι απλούστερο το πρόβλημα επειδή λες οτι το κιβώτιο σου έχει ένα μέγεθος και όχι πολλά διαφορετικά. Οπότε μια απλή λύση θα ήταν η: Δεδομένου χώρου του container(Χ,Υ,Ζ) και δεδομένου του κιβωτίου (a,b,c), Υπολόγισε: Xmoda,Xmodb,Xmodc, Ymoda,Ymodb,Ymodc, Zmoda,Zmodb,Zmodc Βρες την ελάχιστη τιμή οπότε έχεις την αντιστοιχία οτι πχ στο ύψος του κονταινερ (Z) θα μπουν τα πλάτη των κιβωτίων ( c ).. μετά σβήνεις το ύψος και τα πλάτη απο τους παραπάνω υπολογισμούς Xmoda,Xmodb Ymoda,Ymodb Ξανά επιλέγεις την ελάχιστη τιμή για να βρεις την επόμενη αντιστοιχία εστω (X) --> a και στο τέλος δεν έχεις επιλογή διαλέγεις (Y) --> b Σύνολο κιβωτίων: Ζdivc *Xdiva*Ydivb Edit: Ακυρο ακόμη και αυτό είναι δύσκολο τελικά, εντόπισα ένα θέμα με το παραπάνω, ενδεχομένως να υπάρχει καλύτερη λύση αν τοποθετείς τα κιβώτια με διαφορετικό τρόπο οπότε έχει μια μικρή παραλλαγή, πρέπει να τοποθετείς μια στρώση και μετά τα ξαναυπολογίζεις τα υπόλοιπα Επεξ/σία 25 Μαΐου 2016 από Technology fan
panos_saxo Δημοσ. 25 Μαΐου 2016 Μέλος Δημοσ. 25 Μαΐου 2016 Οποτε θα πρεπει να κατάφύγω στον "μπακαλιστικο" τροπο που χρησιμοποιώ ως τώρα με οποιους κινδύνους αυτό κρύβει. Δλδ απλα διαιρω το μήκος πχ του container με το μήκος πχ του κιβωτίου και εχω θεωρητικά ποσά κιβώτια θα πάρει κατα μήκος σε μια σειρα. Μετα κάνω το ίδιο κατα πλάτος του container και πολλαπλασιαζω αυτά τα δυο μεταξύ τους.έτσι έχω το ποσά κιβώτια θα πάρει για μια στρώση (πάτωμα )και αντίστοιχα συνεχιζω με το υψος.
M2000 Δημοσ. 26 Μαΐου 2016 Δημοσ. 26 Μαΐου 2016 Ωχ τώρα το είδα..μιλάμε για container. Οπότε..το παρακάτω, δεν μετράει.. Βάλτε στο νου σας ότι τα φορτηγά παίρνουν παλέτες. Οι παλέτες δεν είναι τετράγωνες. Το μέγεθος είναι τέτοιο ώστε να μπορούν να περιστραφούν μέσα. Το πρόβλημα ανάγεται στο πακετάρισμα σε παλέτα. Στη παλέτα τοποθετούμε στρώσεις. Το ύψος της περιορίζεται από το μέγιστο επιτρεπόμενο, για να μπαίνει σε φορτηγό, και από το βάρος. Κάθε στρώση δεν πρέπει να είναι ίδια, ώστε να έχουμε καλύτερο κράτημα, σαν δέσιμο δηλαδή. Τα φορτηγά μπορούν να φορτώνονται από ένα μέρος πίσω, οπότε οι παλέτες προωθούνται με παλετοφόρο, ή από το πλάι του φορτηγού. Σε κάθε περίπτωση τις βάζει το κλαρκ, το οποίο όχι σπλά τις ανέβαζει αλλά τις περιστρέφει κιόλας και τις σπρώχνει. ...και ναι έχω κάνει και αυτή τη δουλειά! Σε μικρά φορτηγά έχουν παλετοφόρο μέσα και γρήγορα βάζουν τις παλέτες, από ράμπα. Προγραμματιστικά το εμβαδόν δείχνει πόσες παλέτες χωράει, και ο κατασκευαστής δεν έχει διαλέξει ό,τι να είναι εμβαδόν. Οπότε πάμε στο πρόβλημα...πώς στρώνουμε την παλέτα. Με 29 δολάρια το χρόνο http://www.easycargo3d.com
panos_saxo Δημοσ. 26 Μαΐου 2016 Μέλος Δημοσ. 26 Μαΐου 2016 Πολύ καλά τα λες , αλλά οντως μιλάμε για container με χύμα φόρτωση ! Το στήσιμο της παλέτας το έχω ,12 χρόνια αυτή τη δουλειά κάνω. Τώρα παρουσιάστηκε το θέμα με χύμα container. Και το μεγαλυτερο μου πρόβλημα είναι οτι προκειμενου να οριστικοποιησω μια παραγγελία κάποιου πελάτη για εξωτερικο , που το container δλδ θα πρεπει να φύγει με πλοίο , πρεπει πρωτα να βρω εγώ εναν ακριβή αριθμο κιβωτίων που θα φορτωσω ώστε να γεμίσει το container πλήρως , τουλαχιστον πλευρικά και κατα μήκος.το υψος δε με νοιάζει τόσο να το φτάσω πανω πανω , αλλά σε καμια περίπτωση δε θέλω να αφήσω μεγαλο κενό στο πλάι και στο πίσω μέρος του container γτ μιλάμε για κιβώτιο που εύκολα μπορεί να πέσει /σπάσει το περιεχόμενο του . Οποία λύση πέρα του προχειρου τρόπου υπολογισμού που λέω πιο πάνω είναι ευπρόσδεκτη!
M2000 Δημοσ. 26 Μαΐου 2016 Δημοσ. 26 Μαΐου 2016 Πρέπει να είναι στέρεο, και χρειάζεται μετά παραγεμίσματα! Στη σύνδεση που έδωσα έχει και με 3.5 ευρώ χρήση μιας μέρας. Μια φορά θα τα δώσεις και ξέρεις τι θα κάνεις!
giso Δημοσ. 27 Μαΐου 2016 Δημοσ. 27 Μαΐου 2016 Στη λογική του 'Technology fan' έχει γίνει το προγραμματάκι (screenShot στο επισυναπτόμενο αρχείο). Αν σου κάνει μπορώ να στο στείλω. Απλά απαιτεί εγκαταστημένη java 8.
Technology fan Δημοσ. 27 Μαΐου 2016 Δημοσ. 27 Μαΐου 2016 Στη λογική του 'Technology fan' έχει γίνει το προγραμματάκι (screenShot στο επισυναπτόμενο αρχείο). Αν σου κάνει μπορώ να στο στείλω. Απλά απαιτεί εγκαταστημένη java 8. Ωραίο, αν το χεις κάνει εσύ με θα με ενδιέφερε να δω πως το λύνεις (javawise)...
panos_saxo Δημοσ. 27 Μαΐου 2016 Μέλος Δημοσ. 27 Μαΐου 2016 ναι φυσικα και με ενδιαφερει αν και μαλλον θα χρειαστω και καποιες οδηγιες χρησης!
giso Δημοσ. 27 Μαΐου 2016 Δημοσ. 27 Μαΐου 2016 (επεξεργασμένο) Ωραίο, αν το χεις κάνει εσύ με θα με ενδιέφερε να δω πως το λύνεις (javawise)... package containerstuffing; import java.awt.GraphicsEnvironment; import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.stage.Stage; /* Controls the application's screen */ public class StuffingController { @FXML private Button fillButton; @FXML private Button clearButton; @FXML private Button exitButton; @FXML private TextField containerLength; @FXML private TextField containerWidth; @FXML private TextField containerHeight; @FXML private TextField boxWidth; @FXML private TextField boxLength; @FXML private TextField boxHeight; @FXML private TextField totalBoxes; @FXML private TextArea results; private double[] containerDimensions; private double[] boxDimensions; private double maxContainerDimension; private double minBoxDimension; private String resultString; private int sumNumBoxes; public void initManager(Scene scene, Stage stage) { int graphicsDeviceWidth = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width; int graphicsDeviceHeight = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height; int x = graphicsDeviceWidth/2 - 225; int y = graphicsDeviceHeight/2 - 280; stage.setX(x); stage.setY(y); stage.show(); containerDimensions = new double[3]; boxDimensions = new double[3]; sumNumBoxes = 0; Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("Alert message"); alert.setHeaderText(null); alert.initOwner(stage); fillButton.setOnAction((ActionEvent event) -> { resultString = ""; boolean validDimensions = true; sumNumBoxes = 0; results.clear(); totalBoxes.clear(); if (containerLength.getText().matches("^[0-9]+(\\.[0-9]+)?$")) containerDimensions[0] = Double.valueOf(containerLength.getText()); else { validDimensions = false; alert.setContentText("Wrong number for the length of the container"); alert.showAndWait(); containerLength.clear(); containerLength.requestFocus(); } if (containerWidth.getText().matches("^[0-9]+(\\.[0-9]+)?$")) containerDimensions[1] = Double.valueOf(containerWidth.getText()); else { validDimensions = false; alert.setContentText("Wrong number for the width of the container"); alert.showAndWait(); containerWidth.clear(); containerWidth.requestFocus(); } if (containerHeight.getText().matches("^[0-9]+(\\.[0-9]+)?$")) containerDimensions[2] = Double.valueOf(containerHeight.getText()); else { validDimensions = false; alert.setContentText("Wrong number for the height of the container"); alert.showAndWait(); containerHeight.clear(); containerHeight.requestFocus(); } if (boxWidth.getText().matches("^[0-9]+(\\.[0-9]+)?$")) boxDimensions[0] = Double.valueOf(boxWidth.getText()); else { validDimensions = false; alert.setContentText("Wrong number for the widht of the box"); alert.showAndWait(); boxWidth.clear(); boxWidth.requestFocus(); } if (boxLength.getText().matches("^[0-9]+(\\.[0-9]+)?$")) boxDimensions[1] = Double.valueOf(boxLength.getText()); else { validDimensions = false; alert.setContentText("Wrong number for the length of the box"); alert.showAndWait(); boxLength.clear(); boxLength.requestFocus(); } if (boxHeight.getText().matches("^[0-9]+(\\.[0-9]+)?$")) boxDimensions[2] = Double.valueOf(boxHeight.getText()); else { validDimensions = false; alert.setContentText("Wrong number for the height of the box"); alert.showAndWait(); boxHeight.clear(); boxHeight.requestFocus(); } double containerVolume = containerDimensions[0] * containerDimensions[1] * containerDimensions[2]; double boxVolume = boxDimensions[0] * boxDimensions[1] * boxDimensions[2]; if (containerVolume < boxVolume) { validDimensions = false; alert.setContentText("Box larger than container"); alert.showAndWait(); boxWidth.clear(); boxLength.clear(); boxHeight.clear(); boxWidth.requestFocus(); } if (validDimensions) { minBoxDimension = boxDimensions[0]; for (int i = 1; i < 3; i++) if (boxDimensions[i] <= minBoxDimension) minBoxDimension = boxDimensions[i]; maxContainerDimension = containerDimensions[0]; for (int i = 1; i < 3; i++) { if (containerDimensions[i] > maxContainerDimension) { maxContainerDimension = containerDimensions[i]; } } calculateFilling(); } }); clearButton.setOnAction((ActionEvent event) -> { containerLength.clear(); containerWidth.clear(); containerHeight.clear(); boxWidth.clear(); boxLength.clear(); boxHeight.clear(); results.clear(); totalBoxes.clear(); containerLength.requestFocus(); }); exitButton.setOnAction((ActionEvent event) -> { Platform.exit(); // The program is ended }); } private void calculateFilling() { double[][] mods = new double[3][3]; int[][] conns = null; int k = 1; int rowBoxes = 0; do { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { mods[i][j] = (double)Math.round((containerDimensions[i] % boxDimensions[j]) * 1000d) / 1000d; } } resultString += "Row " + k + ": "; conns = fillRow(mods); for (int i = 0 ; i < 3; i++) { switch(i) { case 0: if (conns[i][1] == 0) resultString += "L <--> a "; if (conns[i][1] == 1) resultString += "L <--> b "; if (conns[i][1] == 2) resultString += "L <--> c "; break; case 1: if (conns[i][1] == 0) resultString += "W <--> a "; if (conns[i][1] == 1) resultString += "W <--> b "; if (conns[i][1] == 2) resultString += "W <--> c "; break; case 2: rowBoxes = (int) Math.floor(containerDimensions[0] / boxDimensions[conns[0][1]]) * (int) Math.floor(containerDimensions[1] / boxDimensions[conns[1][1]]); if (conns[i][1] == 0) resultString += "H <--> a : " + rowBoxes + " boxes\n"; if (conns[i][1] == 1) resultString += "H <--> b : " + rowBoxes + " boxes\n"; if (conns[i][1] == 2) resultString += "H <--> c : " + rowBoxes + " boxes\n"; break; } } sumNumBoxes += rowBoxes; k++; }while(containerDimensions[2] >= minBoxDimension); results.setText(resultString); totalBoxes.setText("Total number of boxes: " + sumNumBoxes); } private int[][] fillRow(double[][] mods) { int[][] connections = new int[3][2]; int[] temp = null; for (int i = 0; i < 3; i++) { connections[i][0] = i; connections[i][1] = 0; } for (int k = 0; k < 2; k++) { temp = findMinMod(mods); connections[temp[0]][1] = temp[1]; if (temp[0] == 2) { containerDimensions[2] -= boxDimensions[temp[1]]; } for (int i = 0; i < 3; i++) { mods[temp[0]][i] = maxContainerDimension; mods[i][temp[1]] = maxContainerDimension; } } for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (mods[i][j] < maxContainerDimension) { connections[i][1] = j; if (i == 2) { containerDimensions[2] -= boxDimensions[j]; } } return connections; } private int[] findMinMod(double[][] mods) { int[] temp = new int[2]; double min = mods[0][0]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (mods[i][j] <= min) { min = mods[i][j]; temp[0] = i; temp[1] = j; } } } return temp; } } ναι φυσικα και με ενδιαφερει αν και μαλλον θα χρειαστω και καποιες οδηγιες χρησης! Δε χρειάζονται οδηγίες χρήσης. Απλά εισάγεις τις διαστάσεις container & box και κλικ στο κουμπί 'Fill'. Υπάρχει μέριμνα να αποφεύγονται no valid τιμές. Δώσε email για να βρώ τρόπο να στο στείλω. Επεξ/σία 28 Μαΐου 2016 από giso 2
Technology fan Δημοσ. 27 Μαΐου 2016 Δημοσ. 27 Μαΐου 2016 @giso Νομίζω οτι έχει μια βελτίωση.. Θεωρεις οτι όλα τα κιβώτια τοποθετούνται με τον ίδιο τρόπο μεσα στο κονταινερ, το οποίο δεν είναι απαραίτητα σωστό. Η λογική του αλγορίθμου αυτή είναι, απλά κάθε φορά που τοποθετείς μια στρώση, πρέπει να ξαναυπολογίσεις τις modulo αριθμητικές (με το μέγεθος του κονταινερ που απομένει μετά την τοποθέτηση της κάθε σειράς). Δεν μπορώ να σκεφτώ τώρα τα νούμερα για να ορίσω συγκεκριμένη περίπτωση αλλά σκέψου μια περίπτωση του να έχει σχεδόν γεμίσει το κονταινερ και εχει που λες δεν χωράνε άλλα κιβώτια, αν τα περιστρέψεις χωράνε κι άλλα. Ίσως Κυριακή έχω λίγο χρόνο να το τροποποιήσω λίγο, βλέπω έκανες και fxml. Ωραίο...
giso Δημοσ. 27 Μαΐου 2016 Δημοσ. 27 Μαΐου 2016 (επεξεργασμένο) @giso Νομίζω οτι έχει μια βελτίωση.. Θεωρεις οτι όλα τα κιβώτια τοποθετούνται με τον ίδιο τρόπο μεσα στο κονταινερ, το οποίο δεν είναι απαραίτητα σωστό. Η λογική του αλγορίθμου αυτή είναι, απλά κάθε φορά που τοποθετείς μια στρώση, πρέπει να ξαναυπολογίσεις τις modulo αριθμητικές (με το μέγεθος του κονταινερ που απομένει μετά την τοποθέτηση της κάθε σειράς). Δεν μπορώ να σκεφτώ τώρα τα νούμερα για να ορίσω συγκεκριμένη περίπτωση αλλά σκέψου μια περίπτωση του να έχει σχεδόν γεμίσει το κονταινερ και εχει που λες δεν χωράνε άλλα κιβώτια, αν τα περιστρέψεις χωράνε κι άλλα. Ίσως Κυριακή έχω λίγο χρόνο να το τροποποιήσω λίγο, βλέπω έκανες και fxml. Ωραίο... Μετά από το γέμισμα μιας σειράς υπολογίζει ξανά τα modulo αλλάζοντας τιμές μόνο κατά τη διάσταση του ύψους 'Η' του container, γιατί αυτή μόνο μεταβάλλεται. do { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { mods[i][j] = (double)Math.round((containerDimensions[i] % boxDimensions[j]) * 1000d) / 1000d; } } Ο υπολογισμός των modulo γίνεται μέσα στη do-while. Φαίνεται και στην εικόνα ο τρόπος τοποθέτησης των κιβωτίων της 1ης σειράς διαφέρει από τη δεύτερη και τη 3η. Επεξ/σία 28 Μαΐου 2016 από giso
groot Δημοσ. 27 Μαΐου 2016 Δημοσ. 27 Μαΐου 2016 Θεωρείς τις διαστάσεις του κουτιού: X_box >= Y_box >= Z_box.Επίσης, έχεις X_cont, Y_cont, Z_cont, οι διαστάσεις του container.Σε python για να μην πλέκω με types... import math x_mod = math.floor(X_cont/x_box) xy_mod = math.floor(x_mod/y_box) if x_mod > y_mod else 0 xyz_mod = math.floor(xy_mod/z_box) if xy_mod else math.floor(x_mod/z_box) if x_mod > z_box else 0 x_mod += xy_mod + xyz_mod y_mod = math.floor(X_cont/y_box) yz_mod = math.floor(y_mod/z_box) if y_mod > z_box else 0 y_mod += yz_mod z_mod = math.floor(X_cont/z_box) vals = [x_mod, y_mod, z_mod] vals_names = ['x_box', 'y_box', 'z_box'] print('First dimension to use: ' + vals_names[vals.index(max(vals))]) Εφόσον έχεις την πρώτη διάσταση, εφαρμόζεις το ίδιο σκεπτικό και στην επόμενη αλλά αποκλείοντας από τους υπολογισμούς την διάσταση που επέλεξες ως πρώτη. Π.χ., εάν επιλέξεις να βάλεις για πρώτη διάσταση το ύψος του container και το y_box ως καλύτερη λύση τότε για το πλάτος του container δεν θα υπολογίσεις μέσα την y_box.Υ.Γ. Οι τιμές δεν είναι mod.. αλλά έμεινε έτσι λόγω λάθους συλλογισμού στην αρχή.Υ.Γ.2 Το κάνεις άνετα loop με τις γεννήτριες από itertools.
giso Δημοσ. 27 Μαΐου 2016 Δημοσ. 27 Μαΐου 2016 Αυτό "Θεωρείς τις διαστάσεις του κουτιού: X_box >= Y_box >= Z_box." από που προκύπτει; Για τα mod έχεις δίκιο.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα