From f3fd6276c2b78b9c405a04c83bbd3b50b265cf70 Mon Sep 17 00:00:00 2001 From: Laurens Van Houtven Date: Thu, 9 Oct 2008 21:24:41 +0200 Subject: [PATCH] GUI added On branch master Changes to be committed: new file: tspGUI.m --- tspGUI.m | 347 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 tspGUI.m diff --git a/tspGUI.m b/tspGUI.m new file mode 100644 index 0000000..2a14180 --- /dev/null +++ b/tspGUI.m @@ -0,0 +1,347 @@ +function testGUI +% TEST_GUI A simple test GUI, meant to experiment with MATLAB's +% GUI elements and syntax. + + % Initialize and hide the GUI as it is being constructed. + f = figure('Visible','off','Position',[495,325,640,640]); + + % Construct the components. + himport1 = uicontrol('Style','pushbutton',... + 'String','Import Location','Position',[20,580,100,30],... + 'Callback',{@import1button_Callback}); + himport2 = uicontrol('Style','pushbutton',... + 'String','Import Distance','Position',[20,545,100,30],... + 'Callback',{@import2button_Callback}); + cbh = uicontrol('Style','checkbox',... + 'String','Asymmetric','Position',[20,480,100,30],... + 'Value',1,'Callback',{@checkbox_Callback}); + sth0 = uicontrol('Style','text','String','Number of Cities',... + 'Position',[20, 465, 100, 11]); + hpopup1 = uicontrol('Style','popupmenu',... + 'String',{'5','10','15','20','25','30'},... + 'Position',[20,435,100,25],'Callback',{@popup_menu1_Callback}); + hrandom = uicontrol('Style','pushbutton',... + 'String','Random','Position',[20,400,100,30],... + 'Callback',{@randombutton_Callback}); + hcalc = uicontrol('Style','pushbutton',... + 'String','Calculate','Position',[20,340,100,30],... + 'Callback',{@calcbutton_Callback}); + hpopup2 = uicontrol('Style','popupmenu',... + 'String',{'Random','Nearest','Farthest','Enum'},... + 'Position',[20,305,100,25],'Callback',{@popup_menu2_Callback}); + hexport = uicontrol('Style','pushbutton',... + 'String','Export','Position',[20,245,100,30],... + 'Callback',{@exportbutton_Callback}); + hreset = uicontrol('Style','pushbutton',... + 'String','Reset','Position',[20,210,100,30],... + 'Callback',{@resetbutton_Callback}); + ha = axes('Units','pixels','Position',[200,215,400,400]); + + sth1 = uicontrol('Style','text','String','RANDOM',... + 'Position',[10, 175, 70, 11]); + sth2 = uicontrol('Style','text','String','Route:',... + 'Position',[20, 160, 70, 11]); + sth3 = uicontrol('Style','text','String','Distance:',... + 'Position',[20, 145, 70, 11]); + sth4 = uicontrol('Style','text','String','0',... + 'Position',[90, 160, 530, 11]); + sth5 = uicontrol('Style','text','String','0',... + 'Position',[90, 145, 530, 11]); + + sth6 = uicontrol('Style','text','String','NEAREST',... + 'Position',[10, 130, 70, 11]); + sth7 = uicontrol('Style','text','String','Route:',... + 'Position',[20, 115, 70, 11]); + sth8 = uicontrol('Style','text','String','Distance:',... + 'Position',[20, 100, 70, 11]); + sth9 = uicontrol('Style','text','String','0',... + 'Position',[90, 115, 530, 11]); + sth10 = uicontrol('Style','text','String','0',... + 'Position',[90, 100, 530, 11]); + + sth11 = uicontrol('Style','text','String','FARTHEST',... + 'Position',[10, 85, 70, 11]); + sth12 = uicontrol('Style','text','String','Route:',... + 'Position',[20, 70, 70, 11]); + sth13 = uicontrol('Style','text','String','Distance:',... + 'Position',[20, 55, 70, 11]); + sth14 = uicontrol('Style','text','String','0',... + 'Position',[90, 70, 530, 11]); + sth15 = uicontrol('Style','text','String','0',... + 'Position',[90, 55, 530, 11]); + + sth16 = uicontrol('Style','text','String','ENUMS',... + 'Position',[10, 40, 70, 11]); + sth17 = uicontrol('Style','text','String','Route:',... + 'Position',[20, 25, 70, 11]); + sth18 = uicontrol('Style','text','String','Distance:',... + 'Position',[20, 10, 70, 11]); + sth19 = uicontrol('Style','text','String','0',... + 'Position',[90, 25, 530, 11]); + sth20 = uicontrol('Style','text','String','0',... + 'Position',[90, 10, 530, 11]); + + align([himport1,himport2,cbh,hrandom,hcalc,hpopup2,hexport,sth0,... + hpopup1,hreset],'Center','None'); + + % Initialize the data. + coordMatrix = 0; % The coordinates of the cities + distanceMatrix = 0; % The distances between the cities + asymmetric = 1; % Whether the TSP is an asymmetric one or not + plottype = 1; % The current plot type (1=Random,2=Nearest,3=Farthest,4=Enum) + numberOfCities = 5; % Number of cities to be used in the 'Random' function + routeRandom = 0; + distanceRandom = 0; + routeNearest = 0; + distanceNearest = 0; + routeFarthest = 0; + distanceFarthest = 0; + routeEnum = 0; + distanceEnum = 0; + + % Initialize the GUI. + % Change units to normalized so components resize automatically. + set([f,himport1,himport2,cbh,hrandom,hcalc,hpopup2,hexport,ha,... + sth0,hpopup1,hreset],'Units','normalized'); + % Assign the GUI a name to appear in the window title. + set(f,'Name','Travelling Salesman Problem','NumberTitle','off') + % Move the GUI to the center of the screen. + movegui(f,'center') + % Make the GUI visible. + set(f,'Visible','on'); + + % Pop-up menu callback. Read the pop-up menu Value property to + % determine which item is currently displayed and set the number of + % cities to be generated using the 'Random' function to the current + % value. + function popup_menu1_Callback(source,eventdata) + % Determine the selected integer. + str = get(source, 'String'); + val = get(source,'Value'); + % Set numberOFCities to the selected data set. + switch str{val}; + case '5' % User selects 5. + numberOfCities = 5; + case '10' % User selects 10. + numberOfCities = 10; + case '15' % User selects 15. + numberOfCities = 15; + case '20' % User selects 20. + numberOfCities = 20; + case '25' % User selects 25. + numberOfCities = 25; + case '30' % User selects 30. + numberOfCities = 30; + end + end + + % Pop-up menu callback. Read the pop-up menu Value property to + % determine which heuristic plot is currently displayed and make it the + % current plot type. + function popup_menu2_Callback(source,eventdata) + % Determine the selected data set. + str = get(source, 'String'); + val = get(source,'Value'); + % Set current data to the selected data set. + switch str{val}; + case 'Random' % User selects Random. + plottype = 1; % Sets the plot type to Random (=1) + drawAll(routeRandom,coordMatrix) + case 'Nearest' % User selects Nearest. + plottype = 2; % Sets the plottype to Nearest (=2) + drawAll(routeNearest,coordMatrix) + case 'Farthest' % User selects Farthest. + plottype = 3; % Sets the plottype to Farthest (=3) + drawAll(routeFarthest,coordMatrix) + case 'Enum' % User selects Farthest. + plottype = 4; % Sets the plottype to Enumerative (=4) + if size(coordMatrix,1) <= 10 + drawAll(routeEnum,coordMatrix) + end + end + end + + % Push button callbacks. + + function import1button_Callback(source,eventdata) + % Open the import dialog and import a matrix with the locations of + % the cities. + importedMatrix = importLocation; + + % Check if it's a correct location matrix + n = size(importedMatrix,1); + i = [1:n]'; + if importedMatrix(:,1) == i && size(importedMatrix,2) == 3 + % No problems have occured. Clear previous data and set new + % coordMatrix. + resetData; + coordMatrix = importedMatrix; + drawCities(coordMatrix); + else + h = warndlg('This is not a valid location matrix! Try again!',... + 'Incorrect location matrix'); % Show the user a warning dialog + coordMatrix = 0; + end + + end + + function import2button_Callback(source,eventdata) + % Open the import dialog and import a matrix with the distances + % between the cities. + importedMatrix = importDistance; + + % Check if it's a correct distance-matrix + n = size(importedMatrix,1); + i = zeros(n,1); + if n == size(importedMatrix,1) && n == size(importedMatrix,2) && i == diag(importedMatrix) + distanceMatrix = importedMatrix; + asymmetric = 1; + set(cbh,'Value',1); + else + h = warndlg('This is not a valid distance matrix! Try again!',... + 'Incorrect distance matrix'); % Show the user a warning dialog + distanceMatrix = 0; + end + + end + + function randombutton_Callback(source,eventdata) + % Generate a random matrix containing the locations of the cities + % and the corresponding matrix containing the distances between the + % cities. If the 'Asymmetric'-checkbox is checked, this latter matrix + % will also be a random one. + + % Reset the previous routes and distances + resetData; + coordMatrix = 0; + distanceMatrix = 0; + + % Generate the random matrices + coordMatrix = generateRandomCoordMatrix(numberOfCities,100); + if asymmetric == 1 + distanceMatrix = generateRandomDistanceMatrix(coordMatrix,100); + else + distanceMatrix = generateDistanceMatrix(coordMatrix); + end + drawCities(coordMatrix); + end + + function checkbox_Callback(source,eventdata) + % Controls whether asymmetric is checked or not. + if get(source,'Value') == 1 + asymmetric = 1; + else + asymmetric = 0; + end + end + + function calcbutton_Callback(source,eventdata) + % Calculates the optimal route and its distance using three heuristics: + % Random, Nearest Neighbour and Farthest Neighbour. + + % Check for both a location matrix and distance matrix. If any of them + % are not present, display an error message. + passedChecks = 0; + + % Check for location matrix. + if coordMatrix == 0 + if distanceMatrix == 0 + h = warndlg('Please import a location (and distance) matrix or generate random ones!',... + 'No data found'); + else + h = warndlg('Please import a location matrix!',... + 'No location matrix found'); + end + else + if distanceMatrix == 0 + if asymmetric == 1 + h = warndlg('Please import a distance matrix or uncheck ''Asymmetric''!',... + 'No distance matrix found'); + else + distanceMatrix = generateDistanceMatrix(coordMatrix); + passedChecks = 1; + end + else + if asymmetric == 1 + if size(coordMatrix,1)==size(distanceMatrix,1) + passedChecks = 1; + else + h = warndlg('Please import matrices that match!',... + 'Matrices don''t match'); + end + else + distanceMatrix = generateDistanceMatrix(coordMatrix); + passedChecks = 1; + end + end + end + + % Calculate the routes using the different heuristics if the checks + % were passed. + if passedChecks == 1 + [routeRandom,distanceRandom,routeNearest,distanceNearest,... + routeFarthest,distanceFarthest,routeEnum,... + distanceEnum] = calculateHeuristics(distanceMatrix); + + set(sth4,'String',int2str(routeRandom)) + set(sth5,'String',distanceRandom) + + set(sth9,'String',int2str(routeNearest)) + set(sth10,'String',distanceNearest) + + set(sth14,'String',int2str(routeFarthest)) + set(sth15,'String',distanceFarthest) + + if routeEnum == 0 + set(sth19,'String','Too difficult to calculate!') + set(sth20,'String','Too difficult to calculate!') + else + set(sth19,'String',int2str(routeEnum)) + set(sth20,'String',distanceEnum) + end + + % Plot the cities and the route between them + if plottype == 1 + drawAll(routeRandom,coordMatrix); + elseif plottype == 2 + drawAll(routeNearest,coordMatrix); + elseif plottype == 3 + drawAll(routeFarthest,coordMatrix); + else + if size(coordMatrix,1) <= 10 + drawAll(routeEnum,coordMatrix) + end + end + end + + end + + function resetbutton_Callback(source,eventdata) + % Resets the GUI + resetData; + coordMatrix = 0; + distanceMatrix = 0; + end + + function resetData + % Controls whether asymmetric is checked or not. + cla; + routeRandom = 0; + distanceRandom = 0; + routeNearest = 0; + distanceNearest = 0; + routeFarthest = 0; + distanceFarthest = 0; + routeEnum = 0; + distanceEnum = 0; + set(sth4,'String','0'); + set(sth5,'String','0'); + set(sth9,'String','0'); + set(sth10,'String','0'); + set(sth14,'String','0'); + set(sth15,'String','0'); + set(sth19,'String','0'); + set(sth20,'String','0'); + end + +end \ No newline at end of file -- 2.11.4.GIT