2016-07-29 34 views
1

Ich habe die nächsten Vektoren zu generieren:sortieren eine Reihe von Punkten einen Umschlag in MATLAB

A = [0;100;100;2100;100;2000;2100;2100;0;100;2000;2100;0]; 
B = [0;0;1450;1450;1550;1550;1550;1550;2500;2500;3000;3000;0] 

Wenn wir A und B zeichnen, werden wir die folgende Grafik erhalten:

enter image description here

Dann frage ich mich, wie kurz die Punkte, um das nächste Grundstück zu haben:

enter image description here

Wie Sie sehen können, gibt es einige Bedingungen wie: alle von ihnen bilden rechte Winkel; Es gibt keinen Schnittpunkt zwischen Linien.

Vielen Dank im Voraus für eine Antwort!

+1

Können Sie dies garantieren: "Wie Sie sehen können, gibt es einige Bedingungen wie: alle bilden rechte Winkel; es gibt keinen Schnittpunkt zwischen den Linien."? Wird das immer so sein? –

+0

Ohne einen klaren Algorithmus klingt das nicht sehr gut definiert. Sie könnten etwas wie ['boundary'] (http://www.mathworks.com/help/matlab/ref/boundary.html#buh3c7k-3) mit einem hohen Schrumpfungsfaktor versuchen, aber ich würde nicht viel darauf wetten Erfolg. Wie @Stewie angedeutet hat: Die Existenz einer Lösung ist schon lange nicht trivial. –

+1

Ich kann diese Ausgabe generieren: http://i.stack.imgur.com/s4TEj.jpg –

Antwort

0

Wenn alle Schnittpunkte in 90-Grad-Winkeln liegen müssen, können wir einen Graph der möglichen Verbindungen bilden.

Hinweis: Es kann wichtig sein/die Leistung zu verbessern, um kollineare Punkte zu trennen.

Danach wird die Lösung auf die Suche nach Hamiltonian Cycle reduziert. Leider ist das ein NP-schweres Problem, aber glücklicherweise existiert bereits eine MATLAB-Lösung: https://www.mathworks.com/matlabcentral/fileexchange/51610-hamiltonian-graph--source--destination- (obwohl ich es nicht getestet habe).

2

Dies kann in der herkömmlichen rekursiven ‚Labyrinth‘ Lösung ‚kriechenden an Wänden‘ gelöst werden:

%%% In file solveMaze.m 
function Out = solveMaze (Pts,Accum) 

    if isempty (Pts); Out = Accum; return; end % base case 

    x = Accum(1, end); y = Accum(2, end); % current point under consideration 
    X = Pts(1,:);  Y = Pts(2,:);   % remaining points to choose from 

    % Solve 'maze' by wall-crawling (priority: right, up, left, down) 
    if  find (X > x & Y == y); Ind = find (X > x & Y == y); Ind = Ind(1); 
    elseif find (X == x & Y > y); Ind = find (X == x & Y > y); Ind = Ind(1); 
    elseif find (X < x & Y == y); Ind = find (X < x & Y == y); Ind = Ind(1); 
    elseif find (X == x & Y < y); Ind = find (X == x & Y < y); Ind = Ind(1); 
    else error('Incompatible maze'); 
    end 

    Accum(:,end+1) = Pts(:,Ind); % Add successor to accumulator 
    Pts(:,Ind) = [];    % ... and remove from Pts 

    Out = solveMaze (Pts, Accum); 
end 

Anrufen wie folgt, angegeben A und B wie oben;

Pts = [A.'; B.']; Pts = unique (Pts.', 'rows').'; % remove duplicates 
Out = solveMaze (Pts, Pts(:,1));     % first point as starting point 
plot(Out(1,:), Out(2,:),'-o');     % gives expected plot 
+1

Wirklich genial !! + 1 Fügen Sie die ursprünglichen Punkte hinzu !! "Halt durch; Streuen (A, B); ' –

+0

Wenn Sie den ersten Punkt als letzten Eintrag hinzufügen, wird die Schleife automatisch geschlossen. – Adriaan

+0

@Adriaan die Schleife * ist * geschlossen, weil der Startpunkt, mit dem ich den Akkumulator initialisiere, nicht aus dem 'Pts'-Array entfernt wurde, so dass er schließlich zu ihm zurückkehren wird. Es wäre "offen" gewesen, wenn ich stattdessen so gerufen hätte: "Out = solveMaze (Pts (:, 2: end), Pts (:, 1))" –