Avatar
Jirka
Člen
Avatar
Jirka:

Ahoj jsem Jirka,

jsem začátečníkem v programování v jazyce Python. Mám již nějaké dlouhodobější (pár stránek s kompletní správou webového obsahu) zkušenosti s PHP, MySQL, HTML, CSS, JavaScript. Bohužel je toto vše pouze můj osobní koníček a věnuju se tomu pouze ve chvílích volna.

Jelikož pracuji ve strojírenství, přesněji vyrábíme CNC stroje a jejich příslušenství, tak se k psaní programů pro stroj a hrabání v strojních parametrech trošku věnuji ale žádné terno, jsem hlavně mechanik.

Vytvořil jsem prográmek ( Já jsem napsal Python program, kolega dodal rovnice ), který vyhodnocuje geometrie. Abych to upřesnil pracuji zde s 2 plochami, které jsou vyjádřeny jako proměnné A, B. Další dvě proměnné Cx a Cy jsou vyjádřeny jako v kartézské soustavě souřadnic takže Cx je směr X a Cy směr Y.

Proto těch 12 rovnic mám rozdělených do 6 (v ose X) a 6 (v ose Y). Tyto rovnice mají za úkol po dosazení desetinných čísel dojít co nejblíže k nule. Myslím si že by se dal vymyslet lepší postup při dosazování protože můj program pracuje s 5 cykly a každý cyklus dosazuje čísla po 0.25. Což je při hrubém nastavení (-10, 11) solidní nálož kombinací pro výsledný výpočet.

K vyhodnocení dochází vždy když se rovnice dokážou vypočítat tak, že jsou co nejblíže k 0 a podle znamének ve proměnných A, B, Cy, Cx zjistím v jakém směru mám upravit plochu.

Vím, že můj kod asi nebude z těch nejlepších a asi by se tam dalo ledacos vychytat ale momentálně se snažím snížit dobu vyhodnocení rovnic. Od vás bych chtěl vědět jestli někoho nenapadá lepší systém pro vyhodnocování tolika rovnic, kdy platí, že při vyhodnocování musí být vždy v 2 skupinách po 6 rovnicích A nebo B stejné a může se měnit pouze Cy nebo Cx.

Pokud se podíváte na kod najdete zde jestě jednu proměnou ERROR, která se přičítá po 0.25 a upravuje výsledek rovnice. Maximálně však do 2.5.

První optimalizace mě napadla. Je to o snížení kombinací, výpočtem nejvyšších dosazovaných hodnot. (program vždy pracuje vždy od -10 do +10 i když z toho je 50% zbytečných kombinací)

Moc se omlouvám, ale strašně těžko se to vysvětluje. Ale snad když kouknete do kodu tak pochopíte princip fungování programu aniž nebudete vědět k čemu to slouží.

Všem díky za nápady.

def calculate(self):
        # HORIZONT-ČELO
        # vzorec A0°C0° ; (chyba) + (A) + (B) + (Cy) = 0
        # vzorec A0°C180° ; (chyba) + (A) + (B) - (Cy) = 0
        # vzorec A0°C+90° ; (chyba) + (A) + (B) - (Cx) = 0
        # vzorec A0°C-90° ; (chyba) + (A) + (B) + (Cx) = 0

        # VERTIKAL-VRCH
        # vzorec A180°C0 ; (chyba) - (A) + (B) + (Cy) = 0
        # vzorec A180°C180° ; (chyba) + (A) - (B) + (Cy) = 0
        # vzorec A180°C+90° ; (chyba) + (Cy) = 0
        # vzorec A180°C-90° ; (chyba) + (Cy) = 0

        # VERTIKAL-BOK
        # vzorec xA180°C0° ; (chyba) + (Cx) = 0
        # vzorec A180°C180° ; (chyba) + (Cx) = 0
        # vzorec A180°C+90° ; (chyba) + (A) - (B) + (Cx) = 0
        # vzorec A180°C-90° ; (chyba) - (A) + (B) + (Cx) = 0

        CyOK = FALSE
        CxOK = FALSE
        self.labelCy_p.set("")
        for error in self.frange(0, 2.5, 0.25):
            for A in self.frange(-10, 11, 0.25):
                for B in self.frange(-10, 11, 0.25):
                    if not CyOK:
                        for Cy in self.frange(-10, 11, 0.25):
                            if abs(float(self.A0C0.get()) + (A) + (B) + (Cy)) <= error and abs(float(self.A0C180.get()) + (A) + (B) - (Cy)) <= error and abs(float(self.A180C0_t.get()) - (A) + (B) + (Cy)) <= error and abs((float(self.A180C180_t.get())) + (A) - (B) + (Cy)) <= error and abs(float(self.A180C90_p_t.get()) + (Cy)) <= error and abs(float(self.A180C90_m_t.get()) + (Cy)) <= error:
                                self.labelA0C180.set(str(float(self.A0C180.get()) + (A) + (B) - (Cy)))
                                self.labelA0C0.set(str(float(self.A0C0.get()) + (A) + (B) + (Cy)))
                                self.labelA180C0_t.set(str(float(self.A180C0_t.get()) - (A) + (B) + (Cy)))
                                self.labelA180C180_t.set(str(-(float(self.A180C180_t.get())) - (A) + (B) - (Cy)))
                                self.labelA180C90_m_t.set(str(float(self.A180C90_m_t.get()) + (Cy)))
                                self.labelA180C90_p_t.set(str(float(self.A180C90_p_t.get()) + (Cy)))
                                CyOK = TRUE
                                break


                    if not CxOK:
                        for Cx in self.frange(-10, 11, 0.25):
                            if abs(float(self.A0C90_p.get()) + (A) + (B) - (Cx)) <= error and abs(float(self.A0C90_m.get()) + (A) + (B) + (Cx)) <= error and abs((float(self.A180C90_p_s.get())) + (A) - (B) + (Cx)) <= error and abs(float(self.A180C90_m_s.get()) - (A) + (B) + (Cx)) <= error and abs(float(self.A180C0_s.get()) + (Cx)) <= error and abs(float(self.A180C180_s.get()) + (Cx)) <= error:
                                self.labelA0C90_m.set(str(float(self.A0C90_m.get()) + (A) + (B) + (Cx)))
                                self.labelA0C90_p.set(str(float(self.A0C90_p.get()) + (A) + (B) - (Cx)))
                                self.labelA180C90_p_s.set(str(-(float(self.A180C90_p_s.get())) - (A) + (B) - (Cx)))
                                self.labelA180C90_m_s.set(str(float(self.A180C90_m_s.get()) - (A) + (B) + (Cx)))
                                self.labelA180C0_s.set(str(float(self.A180C0_s.get()) + (Cx)))
                                self.labelA180C180_s.set(str(float(self.A180C180_s.get()) + (Cx)))
                                CxOK = TRUE
                                break

                    if CyOK and CxOK:

                        print("Cx---")
                        print("A0C90 "+str(float(self.A0C90_p.get()) + (A) + (B) - (Cx)))
                        print("A0C-90 "+str(float(self.A0C90_m.get()) + (A) + (B) + (Cx)))
                        print("A180C90 side "+str(-(float(self.A180C90_p_s.get())) - (A) + (B) - (Cx)))
                        print("A180C-90 side "+str(float(self.A180C90_m_s.get()) - (A) + (B) + (Cx)))
                        print("A180C0 side "+str(float(self.A180C0_s.get()) + (Cx)))
                        print("A180C180 side"+str(float(self.A180C180_s.get()) + (Cx)))
                        print("A "+str(A))
                        print("B "+str(B))
                        print("Cx "+str(Cx))

                        print("Cy---")
                        print("A0C0 "+str(float(self.A0C0.get()) + (A) + (B) + (Cy)))
                        print("A0C180 "+str(float(self.A0C180.get()) + (A) + (B) - (Cy)))
                        print("A180C0 top"+str(float(self.A180C0_t.get()) - (A) + (B) + (Cy)))
                        print("A180C180 top"+str((-float(self.A180C180_t.get()) - (A) + (B) - (Cy))))
                        print("A180C90 top"+str(float(self.A180C90_p_t.get()) + (Cy)))
                        print("A180C-90 top"+str(float(self.A180C90_m_t.get()) + (Cy)))
                        print("A "+str(A))
                        print("B "+str(B))
                        print("Cy "+str(Cy))

                        if A < 0:
                            self.labelA_m.set(A)
                        else:
                            self.labelA_p.set(-A)
                        if B < 0:
                            self.labelB_m.set(B)
                        else:
                            self.labelB_p.set(-B)
                        if Cx < 0:
                            self.labelCx_m.set(Cx)
                        else:
                            self.labelCx_p.set(-Cx)
                        if Cy < 0:
                            self.labelCy_m.set(Cy)
                        else:
                            self.labelCy_p.set(-Cy)
                        return
                    else:
                        CyOK = FALSE
                        CxOK = FALSE
 
Odpovědět 31.8.2015 18:37
Avatar
coells
Redaktor
Avatar
coells:

Těžko radit bez přesného zadání.

Obvykle se vytvoří multivarietní residuální funkce na základě systému rovnic a snažíš se minimalizovat její hodnotu.
Pokud se na proměnné A, B, C vztahují omezující podmínky, dá se použít L-BFGS.
Pokud proměnné omezené nejsou, tak jednoduše konjugovaný gradient.
SciPy stack podporuje obě funkce a výpočet pro 3 proměnné bude okamžitý.

Každopádně je to práce pro matematika.

 
Nahoru Odpovědět  +1 31.8.2015 20:11
Avatar
coells
Redaktor
Avatar
coells:

A mimochodem, pokud jsou ty chyby na levé straně (AXXXCXXX) nezávislé na A, B, C, mělo by stačit použít normálové regresní rovnice a rovnou dostat přesný výsledek.

 
Nahoru Odpovědět 31.8.2015 20:17
Avatar
Drakeman
Redaktor
Avatar
Odpovídá na Jirka
Drakeman:

Trosku jsem to zrefaktoroval, at se v tom da lepe cist, ale ted vecer se mi uz nechce premyslet nad nejakymi dalsimi optimalizacemi.
http://www.itnetwork.cz/dev-lighter/635

Nahoru Odpovědět  +1 20.9.2015 22:39
Když se chce, tak jde všechno,
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.