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

Werte in Matrix sortieren für möglichst geringe Spaltensum

 

Thorsten82

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.12.2013, 17:47     Titel: Werte in Matrix sortieren für möglichst geringe Spaltensum
  Antworten mit Zitat      
Hallo zusammen,

ich suche nach Lösungsansätzen für folgendes Problem:

Ich habe eine Matrix die z.B. folgendermaßen aufgebaut ist:
Code:

              3    3     3     0     0     0     0  

              5    5     5     5     5     0     0

              2    2     0     0     0     0     0

              3    3     3     3     3     3     0
-----------------------------------------------
Summe: 13  13   11    8      8     3     0
 


Ziel ist es die Werte innerhalb einer Reihe derart zu vertauschen, dass man am Ende eine Matrix erhält, in der die größte Spaltensumme, die auftritt, möglichst klein ist.

Das ganze würde ich gerne mit Matlab umsetzen.

Ich habe mich bereits ein wenig in Suchalgorithmen und Genetische Algorithmen eingelesen. Allerdings kann ich die Begrifflichkeiten "Knoten" und "Kanten", die bei der Erklärung der Algorithmen verwendet werden, noch nicht so richtig auf mein Problem übertragen.

Hätte jemand eine Idee für einen Lösungsansatz?

Ich würde mich sehr über Vorschläge freuen!
Vorab schonmal vielen Dank.


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.12.2013, 00:49     Titel:
  Antworten mit Zitat      
Hallo,

was meinst du mit "Reihe"? Zeile oder Spalte?

Wie groß wird die Matrix letztlich sein? Anders gesagt: Ist ein "brute force"-Ansatz machbar, d.h. das Durchprobieren aller möglichen Kombinationen?

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.12.2013, 11:20     Titel:
  Antworten mit Zitat      
Hallo,

entschuldigung. Ich meinte, dass die Werte innerhalb einer Zeile vertauscht werden sollen.

Also zum Beispiel zu:

Code:

              0    3     3     0     0     0     3  

              5    5     5     5     5     0     0

              2    0     0     0     0     2     2

              0    3     3     3     3     3     3
-----------------------------------------------
Summe: 7   11   11    8      8     5     8
 


Die Größe der Matrix beträgt 100 Spalten und max. 15 Zeilen.

Die Rechenzeit sollte nicht länger als mehrere Sekunden betragen.

Ich vermute, dass da die "brute force" Methode zu lange dauern wird, oder?

Gibt es eine schnellere Methode, die dann vielleicht nicht das optimale, aber ein gutes Ergebnis liefert?
 
Thorsten82

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.12.2013, 11:28     Titel:
  Antworten mit Zitat      
In der dritten Zeile habe ich mich vertan. Da ist eine Zwei zu viel drin.
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.12.2013, 12:37     Titel:
  Antworten mit Zitat      
Hallo,

da scheidet brute force aus.

Ist es so, dass in einer Zeile immer nur Nullen und ein von Null verschiedener Wert stehen? (in deinem Beispiel ist das ja so)
Gibt es andere/weitere systematische Strukturen in der Matrix, die man ausnützen könnte?
Dann könntest du das als binäres Optimierungsproblem auffassen.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.12.2013, 16:21     Titel:
  Antworten mit Zitat      
Hallo Harald,

genau du hast es richtig erfasst.

In einer Zeile stehen immer nur Nullen und ein von Null verschieder Wert.

In jeder Zeile kann es ein anderer Wert sein, der von Null verschieden ist.

Und die Anzahl an Nullen in einer Zeile kann sich auch in jeder Zeile unterscheiden.


Ansonsten gibt es keine weiteren systematischen Strukturen.

Gruß
Thorsten
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.12.2013, 18:15     Titel:
  Antworten mit Zitat      
Hallo,

ich würde es mal mit ga probieren.
Dir muss aber klar sein: du hast im Grunde genommen 1500 Variablen, an denen man drehen kann. Da wirst du i.d.R. kein sinnvolles Resultat innerhalb von Sekunden erwarten können.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.12.2013, 21:14     Titel:
  Antworten mit Zitat      
Danke für die Hinweise, Harald!

Vor allem der Tipp, das als binäres Optimierungsproblem zu betrachten, hat mich weiter gebracht.

Ich habe nun als Zielfunktion (beim ga entspricht dies der Fitnessfunktion?) bestimmt:

g = max( a, b, c, d, ...) wobei a, b, c, d, ... der Summe der 1., 2., 3., 4., ... Spalte entspricht.

Diese Zielfunktion gilt es zu minimieren.

Pro Zeile, die die Matrix hat, hat man noch eine Nebenbedingung.
In der Nebenbedingung wird festgehalten, wieviele von Null verschiedene Werte in der jeweiligen Zeile sein müssen.

Ich werde mal versuchen, es so mit dem ga umzusetzen.

Gruß
Thorsten
 
Thorsten82

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.01.2014, 19:23     Titel:
  Antworten mit Zitat      
Hallo und frohes neues Jahr,

ich habe den ga mal für folgende "einfache" Matrix angesetzt:

Code:

3 3 0 0 0 0
5 5 5 5 5 5
2 2 2 0 0 0
 


Mit folgenden zusätzlichen Einstellungen:
Population size = 50
Generations und Stall generations = 1000

Nach mehreren Durchgängen musste ich feststellen, dass nicht immer eine optimale Lösung gefunden wird.


Muss ich die Generationen vielleicht noch weiter Erhöhen?

Gibt es vielleicht noch andere Einstellungen, die ich für dieses Problem anpassen müsste?
"Creation function" und "Crossover" lassen sich bei Integer Variablen ja nicht verändern.

Wie ich der Doku entnehmen konnte, kommt, alternativ zum ga, für ein binäres Optimierungsproblem nur noch bintprog in Frage, wo allerdings die Funktion linear sein muss.

Oder habe ich was übersehen und es gibt doch einen alternativen solver?
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 01.01.2014, 20:21     Titel:
  Antworten mit Zitat      
Hallo,

das ist eine Eigenheit der Evolution, dass nicht immer das Optimum herauskommt.

Meistens hilft es eher, PopulationSize zu erhöhen (nimm ruhig 500) anstatt die Anzahl der Generationen.

Zudem könnte man mit custom mutation / crossover functions arbeiten. Das Problem an Evolutionen ist, dass sie auch in die falsche Richtung laufen können. Oft kann man da etwas nachhelfen.

bintprog ist generell eine Alternative, wird hier aber nicht helfen, weil die Zielfunktion eben nicht linear ist.

Wenn du deinen bisherigen Code postest, kann ich mir das gerne mal genauer ansehen.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.01.2014, 20:58     Titel:
  Antworten mit Zitat      
Danke für das Angebot.

Hier der Code:

Code:

function z = my_fun(x)

a = [3*x(1) + 5*x(6) + 2*x(11);
    3*x(2) + 5*x(7) + 2*x(12);
    3*x(3) + 5*x(8) + 2*x(13);
    3*x(4) + 5*x(9) + 2*x(14);
    3*x(5) + 5*x(10) + 2*x(15)];
z = max(a);

-----------------------------------------------------

%Linear inequalities
A=[3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
     -3, -3, -3, -3, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
      0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0;
      0, 0, 0, 0, 0, -5, -5, -5, -5, -5, 0, 0, 0, 0, 0;
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2;
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, -2];

b=[9; -9; 25; -25; 4; -4];

%Bounds
lb = zeros(1,15);
ub = ones(1,15);

%Integer variable indices
v = [1:15];

%Number of variables
count = 15;
 


Dann werde ich mich mal mit custom mutation / crossover functions beschäftigen.
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 01.01.2014, 23:15     Titel:
  Antworten mit Zitat      
Hallo,

Vorschläge:
1. Das Ausschreiben der Funktion dürfte bei größeren Matrizen mühsam sein. Ich würde daher versuchen, mit Matrix-Operationen zu arbeiten (z.B. jede Zeile konstant und dann Multiplikation mit einer 0-1 - Matrix, um die momentane Matrix zu erhalten).
2. Als Creation Function: zufällige Anordnungen der 1en innerhalb jeder Zeile
3. Als Mutation Function: ein Paar von Einträgen wird vertauscht (alternativ mehrere Paare). Führt das zu einem besseren Ergebnis, wird dies übernommen. Aber auch wenn das Ergebnis schlechter wird, wird es mit einer gewissen Wahrscheinlichkeit übernommen - die Evolution nimmt ja auch nicht unbedingt den geraden Weg.
4. Als Crossover Function: die Zeilenbelegung der Elternpaare wird zufällig übernommen. Alternativ kann man nach Auswahl einer gewissen Zeilenzahl auch schauen, welche Möglichkeit besser wäre.

Durch 2.-4. braucht man dann gar keine Nebenbedingungen mehr, da sie ja implizit berücksichtigt werden.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 02.01.2014, 23:47     Titel:
  Antworten mit Zitat      
Danke für die Vorschläge.

Ich habe versucht sie so umzusetzen.

Für eine Matrix der Größe 3 x 15 scheint dies auch noch halbwegs zuverlässig zu funktionieren.
Bei einer Größe von 3 x 20 dann aber schon nicht mehr. Auch wenn man mit der Population size auf bis zu 1000 und Generations = 100 geht.

Dabei habe ich 3 Varianten als Mutation Function probiert:

1. Dein Vorschlag, ein Paar zu vertauschen
2. Dein alternativer Vorschlag, mehrere Paare zu vertauschen. Dabei wird geprüft wieviele Nullen oder Einsen in einer Zeile sind. Je nach Anzahl wird ein zufällige Anzahl von Paaren vertauscht.
3. In jeder Zeile eine Zufallszahl bilden, anhand der man die Zeile mit circshift rotiert.

Als Crossover Function:
In jeder Zeile wird zufällig entschieden, welchem Elternteil die Zeile übernommen wird.

Zitat:
Alternativ kann man nach Auswahl einer gewissen Zeilenzahl auch schauen, welche Möglichkeit besser wäre.


Kannst du deinen alternativen Vorschlag nochmal erläutern?
Meinst du man kombiniert die Zeilen von zwei Eltern auf verschiedene Weisen, und überprüft welche Möglichkeit eine Verbesserung bringt?

Gruß
Thorsten
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 03.01.2014, 00:02     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Meinst du man kombiniert die Zeilen von zwei Eltern auf verschiedene Weisen, und überprüft welche Möglichkeit eine Verbesserung bringt?

Z.B. so:
wenn man drei Zeilen hat, wählt man die ersten beiden zufällig aus den Elternpaaren aus und als dritte Zeile dann die, die das bessere Ergebnis bringt.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.01.2014, 02:56     Titel:
  Antworten mit Zitat      
Hallo,

es scheint jetzt ganz gut zu funktionieren.

Ich möchte nun an mehreren kleineren Matrizen testen, ob der ga auch wirklich das Optimum findet. Hierfür würde ich gerne vorher das Optimum mittels "brute force"-Methode bestimmen.

Ich habe bis jetzt nur den Befehl perms gefunden, um alle Permutationen einer Zeile sofort zu erhalten, wobei man dann ab der Länge 10 Probleme bekommt.
Mit Hilfe des Steinhaus-Johnson-Trotter-Algorithmus habe ich eine Funktion geschrieben, um die Permutationen einer Zeile einzeln zu erhalten.

Nun fehlen mir allerdings noch die Kombinationen der Zeilen zueinander.

Gibt es in Matlab eine Funktion, um systematisch die Permutationen der Zeilen sowie jede mögliche Kombination zu einander zu erhalten?

Oder muss man dies irgendwie über verschachtelte For-Schleifen realisieren?
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

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 - 2025 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.