วันพุธที่ 8 เมษายน พ.ศ. 2563

การนิยามปัญหากราฟโดยตรง ติวเตอร์เรียล 17

Tutorial 17 – Directed Graphs Problem Definition 

It is intended to represent a two dimensional truss in matrix notation and develop functions to calculate the following: 1. function to calculate the length of a member given its Id 2. function to calculate the projections along x- and y-axes and angle made by a member with the x-axis 3. function to list the start and end nodes of a specified member 4. function to calculate the total length of all members 5. function to list the members meeting at a node 6. function to calculate the number of members meeting at each joint Data Definition Nodes of a truss have x and y coordinates. Interconnectivity of members is expressed in terms of a connectivity matrix. The connectivity matrix represents the numbers of the nodes connected by a given member. Node Coordinates Node x y 1 0.0 0.0 2 3.0 0.0 3 6.0 0.0 4 1.5 4.0 5 4.5 4.0 Member Connectivity Member Node i Node j 1 1 2 2 2 3 3 4 5 4 1 4 5 2 4 6 2 5 Tutorial 17 – Directed Graphs | 47 1 2 3 4 5 1 2 3 4 5 6 7 3 m 3 m 4 m 7 3 5 This data can be input into two variables, xy and conn, as follows: -->xy = [0 0; 3 0; 6 0; 1.5 4; 4.5 4] -->conn = [1 2; 2 3; 4 5; 1 4; 2 4; 2 5; 3 5] Before attempting to write the functions, let us try out the commands interactively and verify our understanding of the steps. To display the graph of the truss, we must first define the graph data structure with the help of the make_graph() function and then use show_graph() function. -->tail = conn(:,1)'; head = conn(:,2)'; -->[nodes, dummy] = size(xy); -->g = make_graph('Truss', 1, nodes, tail, head); -->g.nodes.graphics.x = xy(:,1)'*100; -->g.nodes.graphics.y = xy(:,2)'*100; -->show_graph(g); The above commands produce the figure shown above. Let us now write the functions to complete the various assigned tasks. Function rows(x) returns the number of rows in a matrix x. function [r] = rows(x) [r,dummy] = size(x); endfunction Function get_nodes(id, conn) returns the numbers of the nodes n1 and n2 at the ends of member with number id. function [n1, n2] = get_nodes(id, conn) n1 = conn(id, 1); // Column 1 of connectivity matrix stores start node n2 = conn(id, 2); // Column 2 of connectivity matrix stores end node endfunction Function len(id, xy, conn) returns the length L of a member. function [L] = len(id, xy, conn) [n1, n2] = get_nodes(id, conn); p1 = xy(n1,:); p2 = xy(n2,:); // Coordinates of nodes n1 and n2 dx = p2 - p1; // Difference of coordinates of n1 and n2 L =sqrt(sum(dx .^2)); // Formula for length from analytical geometry endfunction Tutorial 17 – Directed Graphs | 48 Function projections(id, xy, conn) returns the x and y projections dx and dy of a member as well as the angle theta made by the member with the xaxis. function [dx, dy, theta] = projections(id, xy, conn) [n1, n2]=get_nodes(id, conn); p1 = xy(n1,:); p2 = xy(n2,:); difference = p2 - p1; dx = difference(1); // x-projection is in column 1 of diff dy = difference(2); // y-projection is in column 2 of diff if dx == 0 then theta = %pi/2; else theta = atan(dy/dx); end endfunction Function total_length(xy, conn) returns the total length of all members in a truss. function [tot_L]=total_length(xy, conn) members = rows(conn); for id=1:members L(id)=len(id,xy,conn); end // disp(L); tot_L = sum(L); endfunction Function members_at_node(nodeid, conn) returns the numbers of members meeting at a node. function [memlst] = members_at_node(nodeid, conn) memlst = find( (conn(:,1)==nodeid) | (conn(:,2)==nodeid) ); endfunction Function num_members_at_node(nodeid, conn) returns the number of members meeting at node. function [n] = num_members_at_node(nodeid, conn) memlst = members_at_node(nodeid, conn); n = length(memlst); endfunction Function make_truss(name, xy, conn) prepares the data structure to represent a truss. function [g] = make_truss(name, xy, conn, scale) t = conn(:,1)'; // tail node numbers h = conn(:,2)'; // head node numbers g = make_graph(name, 1, rows(xy), t, h); g.nodes.graphics.x = xy(:,1)' * scale; g.nodes.graphics.y = xy(:,2)' * scale; endfunction Tutorial 17 – Directed Graphs | 49 Using the data previously entered, we can test the above functions as shown below: -->g = make_truss('Truss', xy, conn, 100); -->show_graph(g) The other functions can also be tested as follows: -->tot_len = total_length(xy, conn); disp(tot_len) 26.088007 -->for i = 1:rows(xy) --> n = num_members_at_node(i, conn); --> mem_lst = members_at_node(i, conn); --> disp([n mem_list]) -->end 2. 1. 4. 4. 1. 2. 5. 6. 2. 2 7. 3. 3 4. 5. 3. 6. 7. We can also test the length and projection functions in a single for loop: -->for i = 1:rows(conn) --> L = len(i, xy, conn); --> [dx, dy, theta] = projections(i, xy, conn); --> disp([dx dy theta L]) -->end 3. 0. 0. 3. 3. 0. 0. 3. 3. 0. 0. 3. 1.5 4. 1.2120257 4.2720019 -1.5 4. -1.2120257 4.2720019 1.5 4. 1.2120257 4.2720019 -1.5 4. -1.2120257 4.2720019 The node numbers and member numbers can be displayed on the graph using the View  Options from the main menu of the graphics window. Graph settings can be modified from the Graph  Settings from the main menu. Graph settings that can be changed are node diameter, edge width, border node width, edge colour index etc. T