WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Lösen eines GLS durch finden der passenden Ziffern

 

Tamu

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.04.2017, 12:18     Titel: Lösen eines GLS durch finden der passenden Ziffern
  Antworten mit Zitat      
Hallo liebe Community,
auf meiner Suche nach Übungsaufgaben, um fitter in matlab zu werden, bin ich auf folgende Aufgabe gestoßen:

Bestimmen sie die Buchstaben A, B, C, D, E und F aus der
Menge {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} , sodass folgende Gleichung erfüllt
ist: 9D800^4 + 21751A^4 + 4145BC^4 = 42E48F^4.

mein Ansatz war das ganze in mehreren for-Schleifen zu lösen. In etwa so:
Code:

n=0:9;
g_es=90800;
g_zs=217510;
g_ds=414500;
g_vs=420480;


for a=0:9
    g_zs=g_zs+a;
    for b=0:9
        g_ds=g_ds+b*10;
        for c=0:9
            g_ds=g_ds+c*1;
            for d=0:9
                g_es=g_es+d*1000;  
                for e=0:9
                    g_vs=g_vs+e*1000;
                    for f=0:9
                        g_vs=g_vs+f;  
                    end
                end
            end
        end
    end
end
 


Mir ist klar, dass ich jetzt eine Abbruchbedingung einführen muss. Nur wie genau erschließt sich mir nicht. Hat jemand von euch vielleicht eine Idee?

Vielen Dank!


Friidayy
Forum-Century

Forum-Century


Beiträge: 225
Anmeldedatum: 17.12.13
Wohnort: ---
Version: R2012b
     Beitrag Verfasst am: 16.04.2017, 14:23     Titel:
  Antworten mit Zitat      
Hallo,

hast du die Möglichkeit eine andere Programmiersprache zu nutzen? Matlab ist für so eine Verkettung von for-Schleifen extrem ungeeignet und sehr langsam.

Als Abbruchskriterium würde ich nehmen:

abs ( g_es^4 + g_zs^4 + g_ds^4 - g_vs^4 )< eps mit eps << 1.


Spoiler

Code:
tol=1e-3;
g_es=90800;
g_zs=217510;
g_ds=414500;
g_vs=420480;

for a=0:9
    z1=g_zs+a;
    for b=0:9
        z2=g_ds+b*10;
        for c=0:9
            z2=z2+c*1;
            for d=0:9
                z3=g_es+d*1000;  
                for e=0:9
                    z4=g_vs+e*1000;
                    for f=0:9
                        z4=z4+f;
                        if abs( z3^4 + z1^4 + z2^4 - z4^4 )<tol
                            sol=[a b c d e f];
                        end
                    end
                end
            end
        end
    end
end
Private Nachricht senden Benutzer-Profile anzeigen
 
Tamu

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.04.2017, 15:06     Titel:
  Antworten mit Zitat      
Hallo,

Ich hatte anfangs eigentlich überlegt das Ganze mit Vektoren und Matrizen zu lösen, da matlab ja nicht wirklich dafür bekannt ist mit for-Schleifen zu arbeiten. Aber schien mir dann doch sinnvoller es auf diese Weise zu machen...

Deine Lösung ist super, vielen lieben Dank Smile Der Wink mit der Abbruchbedingung hat mit leider gefehlt.

schönes Fest,
Tamu
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 18.04.2017, 02:12     Titel: Re: Lösen eines GLS durch finden der passenden Ziffern
  Antworten mit Zitat      
Hallo Tamu,

Dein Code stimmt nicht ganz.
Code:
   for b=0:9
        g_ds = g_ds + b*10;
        for c = 0:9
            g_ds = g_ds+c*1;
...

Hier wird g_ds immer größer, das entspricht aber nicht mehr dem Schema 4145BC^4.

Der Vorschlag von Friidayy enthält einen ähnlichen Fehler:
Code:
for e=0:9
                    z4=g_vs+e*1000;
                    for f=0:9
                        z4 = z4+f;

Besser:
Code:
for e=0:9
                    z4t = g_vs + e*1000;
                    for f = 0:9
                        z4 = z4t + f;

Ansonsten wird nicht [0, 1, 2, 3, 4, ...] an z4 angehängt, sondern [0, 1, 3, 7, ...].

Dass Matlab schlecht mit Schleifen umgehen kann ist ein Gerücht, dass seit der JIT-Acceleration in der Version 6.5 aus dem Jahr 2002 veraltet ist. Leider halten sich solche Ideen hartnäckig.
Der Code leidet eher unter der wiederholten Berechnung der Potenzen. Schneller:

Code:
for a = 0:9
   z1 = (g_zs + a) ^ 4;
   for b = 0:9
      z22 = g_ds + b * 10;
      for c  =0:9
         z2 = (z22 + c) ^ 4;
         for d = 0:9
            z3 = (g_es + d * 1000) ^ 4;
            for e = 0:9
               z44 = g_vs + e * 1000;
               for f = 0:9
                  z4 = (z44 + f) ^ 4;
                  if abs(z3 + z1 + z2 - z4) < tol
                     sol = [a b c d e f]
                  end
               end
            end
         end
      end
   end
end

Nun könnte man die wiederholte Berechnung der Potenzen in den inneren Schleifen reduzieren, indem man die Werte einmalig berechnet:
Code:
tic
% 9D800^4 + 21751A^4 + 4145BC^4 = 42E48F^4
zD  = ( 90800 + (0:9) * 1000) .^ 4;
zA  = (217510 + (0:9)) .^ 4;
zBC = (414500 + (0:9) * 10 + (0:9).') .^ 4;
zEF = (420480 + (0:9) * 1000 + (0:9).') .^ 4;

for iD = 0:9
   xD = zD(iD + 1);
   for iA = 0:9
      xA = zA(iA + 1);
      for iB = 0:9
         for iC = 0:9
            xBC = zBC(iB + 1, iC + 1);
            for iE = 0:9
               for iF = 0:9
                  xEF = zEF(iE + 1, iF + 1);
                  if abs(xD + xA + xBC - xEF) < tol
                     sol = [iA, iB, iC, iD, iE, iF]
                  end
               end
            end
         end
      end
   end
end
toc

Während Friidayys Code 1.04 sec benötigt, läuft dies (trotz der Schleifen) in 0.036 sec (R2016b/64/Win7).

Merke:
Der Power-Operator ist sehr teuer.
Schleifen laufen dann effizient, wenn man wiederholte Berechnungen vermeidet.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.432
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 18.04.2017, 10:10     Titel:
  Antworten mit Zitat      
Hallo,

ich habe es interessehalber auch mal ohne geschachtelte Schleife versucht:

Code:
nums = 0:999999;
for k = 6:-1:1
    kombis(k,:) = floor(nums / 10^(k-1));
    nums = nums - kombis(k,:)*10^(k-1);
end
A = kombis(1,:);
B = kombis(2,:);
C = kombis(3,:);
D = kombis(4,:);
E = kombis(5,:);
F = kombis(6,:);

results = (90800 + 1000*D).^4 ...
    + (217510 + A).^4  ...
    + (414500 + 10*B + C).^4 ...
    - (420480 + 1000*E + F).^4;

good = abs(results) < 1e-3;
kombis(:, good)

... und das ist langsamer als Jans Ansatz.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Tamu

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.04.2017, 15:04     Titel:
  Antworten mit Zitat      
Hallo Jan und Harald,
vielen Dank für eure Ratschläge und Ideen.

Jan, du meintest ich habe einen kleinen Fehler. Ich komme aber trotzdem mit meinem Code auf das richtige Ergebnis. Woran könnte das liegen? Oder habe ich etwas übersehen?

besten Gruß,
Tamu

[Code]

clc;
clear all;
close all;
format long;

g_es=90800;
g_zs=217510;
g_ds=414500;
g_vs=420480;

tic
for a=0:9
sum1=g_zs+a;
for b=0:9
sum2=g_ds+b*10;
for c=0:9
sum2=sum2+c*1;
for d=0:9
sum3=g_es+d*1000;
for e=0:9
sum4=g_vs+e*1000;
for f=0:9
sum4=sum4+f;
if sum3^4+sum1^4+sum2^4-sum4^4 == 0
sol=[a b c d e f];
end
end
end
end
end
end
end
toc

disp(' ');
disp('Die Gleichung ist erfüllt, wenn');
disp('für die Ziffern gilt: ');
disp(['A= ', num2str(sol(1)),'; B= ', num2str(sol(2)),...
'; C= ', num2str(sol(3)),'; D= ', num2str(sol(4)),...
'; E= ', num2str(sol(5)),'; F= ', num2str(sol(6))]);
 
Tamu

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.04.2017, 15:07     Titel:
  Antworten mit Zitat      
Oh Entschuldigt, die Eile..

Code:


clc;
clear all;
close all;
format long;

g_es=90800;
g_zs=217510;
g_ds=414500;
g_vs=420480;


tic
for a=0:9
    sum1=g_zs+a;
        for b=0:9
            sum2=g_ds+b*10;
                for c=0:9
                    sum2=sum2+c*1;
                        for d=0:9
                            sum3=g_es+d*1000;
                                for e=0:9
                                    sum4=g_vs+e*1000;
                                        for f=0:9
                                        sum4=sum4+f;
                                            if sum3^4+sum1^4+sum2^4-sum4^4 == 0
                                                 sol=[a b c d e f];
                                            end
                                        end
                                end
                        end
                end
        end
end
toc


% Ausgabe der Lösung im cmd wd
disp(' ');
disp('Die Gleichung ist erfüllt, wenn');
disp('für die Ziffern gilt: ');
disp(['A= ', num2str(sol(1)),'; B= ', num2str(sol(2)),...
   '; C= ', num2str(sol(3)),'; D= ', num2str(sol(4)),...
   '; E= ', num2str(sol(5)),'; F= ', num2str(sol(6))]);

 
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 01.05.2017, 15:20     Titel:
  Antworten mit Zitat      
Hallo Tamu,

Zitat:
Jan, du meintest ich habe einen kleinen Fehler. Ich komme aber trotzdem mit meinem Code auf das richtige Ergebnis. Woran könnte das liegen?

Der Original-Code enthielt:
Code:
               for e=0:9
                    g_vs=g_vs+e*1000;
                    for f=0:9
                        g_vs=g_vs+f;

Hier wird zu g_vs zuerst 0*1000 addiert, dann 1*1000, dann 2*2000 usw. Du erhältst also g_vs, g_vs+1000, g_vs+3000 usw, aber niemals g_vs+2000 oder g_vs+4000. Dass Du trotzdem das richtige Ergebnis findest, ist reiner Zufall.

Im aktuellen Code ist das Problem nicht mehr vorhanden, weil Du korrekt "sum4 = g_vs + ..." berechnest und nicht mehr "g_vs = g_vs + ...".

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Tamu
Forum-Newbie

Forum-Newbie


Beiträge: 1
Anmeldedatum: 25.04.17
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.05.2017, 15:15     Titel:
  Antworten mit Zitat      
Oh, jetzt seh ichs auch. Vielen Dank!
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.