From 065f3b6bf9d12f6d66449ada845fc7dbd8cf7325 Mon Sep 17 00:00:00 2001 From: Anne-Liza <a.m.r.m.bruggeman@student.tudelft.nl> Date: Wed, 6 Dec 2017 13:32:59 +0100 Subject: [PATCH] Changed coupling strength definition in mathematical problem generator Former-commit-id: 23e22203dce424fbc37e3afa8eca1d8286550bba --- kadmos/graph/graph_data.py | 61 +++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/kadmos/graph/graph_data.py b/kadmos/graph/graph_data.py index cd5b35726..6debc890c 100644 --- a/kadmos/graph/graph_data.py +++ b/kadmos/graph/graph_data.py @@ -840,7 +840,9 @@ class RepositoryConnectivityGraph(DataGraph): def create_mathematical_problem(self, n_disciplines, coupling_strength, n_global_var=None, n_local_var=None, n_coupling_var=None, n_global_constraints=None, B=None, C=None, D=None, H=None, I=None, J=None, s=None, write_problem_to_textfile=False): - """Function to get a mathematical problem according to the variable complexity problem described in Zhang (2017) + """Function to get a mathematical problem according to the variable complexity problem as described in: + Zhang D., Song B., Wang P. and He Y. 'Performance Evaluation of MDO Architectures within a Variable + Complexity Problem', Mathematical Problems in Engineering, 2017. :param n_disciplines: Number of disciplines :param coupling_strength: percentage of couplings, 0 no couplings, 1 all possible couplings @@ -874,7 +876,7 @@ class RepositoryConnectivityGraph(DataGraph): # Number of coupling variables per discipline if n_coupling_var is None: - n_coupling_var = [random.randint(1, 4) for _ in range(n_disciplines)] + n_coupling_var = [random.randint(1, 5) for _ in range(n_disciplines)] mathematical_problem['n_coupling_var'] = n_coupling_var # Number of global constraints @@ -884,26 +886,43 @@ class RepositoryConnectivityGraph(DataGraph): # Create B-matrix: relation between the coupling variables if B is None: + + # Initiate matrix B = np.zeros((sum(n_coupling_var), sum(n_coupling_var))) - B_diag = [random.randint(1, 5) for _ in range(sum(n_coupling_var))] + + # Calculate the number of couplings based on the coupling strength + n_couplings = int(np.ceil(((sum(n_coupling_var)*n_disciplines) - sum(n_coupling_var)) * coupling_strength)) + + # Get a list with all possible couplings between variables and disciplines + possible_couplings = [] + for discipline in range(n_disciplines): + for coupling_var in range(sum(n_coupling_var)): + # An output variable of a discipline cannot be an input to the same discipline + if sum(n_coupling_var[:discipline]) <= coupling_var < sum(n_coupling_var[:discipline + 1]): + continue + possible_couplings.append([coupling_var, discipline]) + + # Choose random couplings from all possible couplings + couplings = random.sample(range(len(possible_couplings)), n_couplings) + + # Fill the B-matrix with the chosen couplings + for coupling in couplings: + discipline = possible_couplings[coupling][1] + for variable in range(n_coupling_var[discipline]): + B[sum(n_coupling_var[:discipline]) + variable][possible_couplings[coupling][0]] = random.choice( + range(-5, 0)+range(1, 6)) # Zero is not allowed + + # To get a converging problem the B-matrix must be diagonally dominant + B_diag = np.sum(abs(B), axis=1) + B_diag = [entry + random.randint(1, 10) for entry in B_diag] i, j = np.indices(B.shape) B[i == j] = B_diag - n_couplings = int( - np.ceil((sum(n_coupling_var) ** 2 - sum(i ** 2 for i in n_coupling_var)) * coupling_strength)) - discipline_matrix = np.zeros((sum(n_coupling_var), sum(n_coupling_var))) - for discipline in range(n_disciplines): - discipline_matrix[sum(n_coupling_var[:discipline]):sum(n_coupling_var[:discipline + 1]), - sum(n_coupling_var[:discipline]):sum(n_coupling_var[:discipline + 1])] = 1 - z1, z2 = np.where(discipline_matrix == 0) - couplings = random.sample(range(len(z1)), n_couplings) - coupling_values = [random.randint(1, 5) for _ in range(n_couplings)] - for index, coupling in enumerate(couplings): - B[z1[coupling]][z2[coupling]] = coupling_values[index] + mathematical_problem['B-matrix'] = B # Create C-matrix: relation between global design variables and coupling variables if C is None: - C = np.array([[float(random.randint(0, 5)) for _ in range(n_global_var)] for _ in + C = np.array([[float(random.randint(-5, 5)) for _ in range(n_global_var)] for _ in range(sum(n_coupling_var))]) mathematical_problem['C-matrix'] = C @@ -914,24 +933,24 @@ class RepositoryConnectivityGraph(DataGraph): for local_var in range(n_local_var[discipline]): for coupling_var in range(n_coupling_var[discipline]): D[sum(n_coupling_var[:discipline]) + coupling_var][sum(n_local_var[:discipline]) + local_var] =\ - random.randint(1, 5) + random.choice(range(-5, 0)+range(1, 6)) # Zero is not allowed mathematical_problem['D-matrix'] = D # Create H-matrix: relation between global design variables and global constraints if H is None: - H = np.array([[float(random.randint(0, 5)) for _ in range(n_global_var)] for _ in + H = np.array([[float(random.randint(-5, 5)) for _ in range(n_global_var)] for _ in range(n_global_constraints)]) mathematical_problem['H-matrix'] = H # Create I-matrix: relation between local design variables and global constraints if I is None: - I = np.array([[float(random.randint(0, 5)) for _ in range(sum(n_local_var))] for _ in + I = np.array([[float(random.randint(-5, 5)) for _ in range(sum(n_local_var))] for _ in range(n_global_constraints)]) mathematical_problem['I-matrix'] = I # Create J-matrix: relation between coupling variables and global constraints if J is None: - J = np.array([[float(random.randint(0, 5)) for _ in range(sum(n_coupling_var))] for _ in + J = np.array([[float(random.randint(-5, 5)) for _ in range(sum(n_coupling_var))] for _ in range(n_global_constraints)]) mathematical_problem['J-matrix'] = J @@ -964,7 +983,9 @@ class RepositoryConnectivityGraph(DataGraph): sum(n_local_var[:local_var_disc]) + local_var] assert all( v == 0 for v in values), 'Local variable x{0}{1} cannot be an input to discipline ' \ - 'D{2}'.format(local_var_disc + 1, local_var + 1, discipline + 1) + 'D{2}, only to discipline D{0}'.format(local_var_disc + 1, + local_var + 1, + discipline + 1) # All function nodes are defined for discipline in range(n_disciplines): -- GitLab