38 for (
int i = 0;
i <
n;
i++) {
51 for (
int i = 0;
i <
n;
i++) {
68void GraphISO::calculate_degrees()
const
74 for (
int v = 0;
v <
n;
v++) {
76 for (
int w = 0;
w <
n;
w++) {
95 return g->degree[
i] <
g->degree[j];
103 int *vv =
static_cast<int *
>(
MEM_mallocN(
n *
sizeof *vv, __func__));
104 for (
int i = 0;
i <
n;
i++) {
110 std::sort(vv, vv +
n, compare_obj);
113 for (
int i = 0;
i <
n;
i++) {
114 for (
int j = 0; j <
n; j++) {
118 for (
int i = 0;
i <
n;
i++) {
121 subg->calculate_degrees();
129 if (cur_pos > *inc_pos) {
131 for (
int i = 0;
i < cur_pos;
i++) {
132 inc[
i][
L] = cur[
i][
L];
133 inc[
i][
R] = cur[
i][
R];
147 domains[*bd_pos][
L] = left_i;
148 domains[*bd_pos][
R] = right_i;
149 domains[*bd_pos][
LL] = left_len;
150 domains[*bd_pos][
RL] = right_len;
151 domains[*bd_pos][
ADJ] = is_adjacent;
152 domains[*bd_pos][
P] = cur_pos;
154 domains[*bd_pos][
IRL] = right_len;
161 for (
int i = bd_pos - 1;
i >= 0 && domains[
i][
P] == cur_pos;
i--) {
162 bound += std::min(domains[
i][
LL], domains[
i][
IRL]);
167static int partition(uint8_t *arr,
int start,
int len,
const uint8_t *adjrow)
170 for (
int j = 0; j <
len; j++) {
171 if (adjrow[arr[start + j]]) {
172 std::swap(arr[start +
i], arr[start + j]);
191 int bd_backup = *bd_pos;
194 for (
i = *bd_pos - 1, bd = &domains[
i][
L];
i >= 0 && bd[
P] == cur_pos - 1;
195 i--, bd = &domains[
i][
L])
201 if (bd[
LL] - l_len && bd[
RL] - r_len) {
210 bound += std::min(bd[
LL] - l_len, bd[
RL] - r_len);
212 if (l_len && r_len) {
213 add_bidomain(domains, bd_pos, bd[
L], bd[
R], l_len, r_len,
true, uint8_t(cur_pos));
214 bound += std::min(l_len, r_len);
217 if (cur_pos + bound <= inc_pos) {
226 if (bd[
RL] != bd[
IRL]) {
229 for (uint8_t
i = 0;
i < bd[
LL];
i++) {
244 for (
int i = 0;
i <
len;
i++) {
245 min_v = std::min(arr[start_idx +
i], min_v);
253 int current_matching_size,
257 int min_size = INT_MAX;
258 int min_tie_breaker = INT_MAX;
261 for (
i = bd_pos - 1, bd = &domains[
i][
L];
i >= 0 && bd[
P] == current_matching_size;
262 i--, bd = &domains[
i][
L])
264 if (connected && current_matching_size > 0 && !bd[
ADJ]) {
268 if (
len < min_size) {
273 else if (
len == min_size) {
275 if (tie_breaker < min_tie_breaker) {
276 min_tie_breaker = tie_breaker;
281 if (best != INT_MAX && best != bd_pos - 1) {
283 for (
i = 0;
i <
BDS;
i++) {
284 tmp[
i] = domains[best][
i];
286 for (
i = 0;
i <
BDS;
i++) {
287 domains[best][
i] = domains[bd_pos - 1][
i];
289 for (
i = 0;
i <
BDS;
i++) {
290 domains[bd_pos - 1][
i] = tmp[
i];
299 for (uint8_t
i = 0;
i < bd[
RL] + 1;
i++) {
301 min = right[bd[
R] +
i];
317 bool *r_search_abandoned)
319 int min = std::min(n0, n1);
321 uint8_t (*cur)[2] = (uint8_t (*)[2])
MEM_mallocN(
min *
sizeof(*cur), __func__);
324 uint8_t *right =
static_cast<uint8_t *
>(
MEM_mallocN(n1 *
sizeof *right, __func__));
328 for (
int i = 0;
i < n0;
i++) {
331 for (
int i = 0;
i < n1;
i++) {
336 int iteration_count = 0;
339 if (iteration_count++ > 10000000) {
344 *r_search_abandoned =
true;
348 bd = &domains[bd_pos - 1][
L];
349 if (
calc_bound(domains, bd_pos, bd[
P]) + bd[
P] <= *inc_pos ||
350 (bd[
LL] == 0 && bd[
RL] == bd[
IRL]))
355 const bool connected =
false;
359 w = right[bd[
R] + bd[
W]];
360 right[bd[
R] + bd[
W]] = right[bd[
R] + bd[
RL]];
361 right[bd[
R] + bd[
RL]] =
w;
367 domains, &bd_pos, bd[
P] + 1,
left, right,
v,
w, *inc_pos, adjmat0, adjmat1);
381 int *solution_length)
383 if (g0->
n != g1->
n) {
386 for (
int i = 0;
i < g0->
n;
i++) {
390 for (
int j = 0; j < g0->
n; j++) {
398 *solution_length = g0->
n;
405 int *solution_length,
406 bool *r_search_abandoned)
412 int n0 = g0_input->
n;
413 int n1 = g1_input->
n;
415 int min_size = std::min(n0, n1);
425 solution, &sol_len, g0->
adjmat, n0, g1->
adjmat, n1, r_search_abandoned);
426 *solution_length = sol_len;
428 bool result = (sol_len == n0);
430 for (
int i = 0;
i < sol_len;
i++) {
431 solution[
i][0] = g0->
label[solution[
i][0]];
432 solution[
i][1] = g1->
label[solution[
i][1]];
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
GraphISO_DegreeCompare(const GraphISO *g)
bool operator()(int i, int j) const
void add_edge(int v, int w)
GraphISO * sort_vertices_by_degree() const
void * MEM_mallocN(size_t len, const char *str)
void * MEM_callocN(size_t len, const char *str)
void MEM_freeN(void *vmemh)
static void generate_next_domains(uint8_t domains[][BDS], int *bd_pos, int cur_pos, uint8_t *left, uint8_t *right, uint8_t v, uint8_t w, int inc_pos, uint8_t **adjmat0, uint8_t **adjmat1)
static uint8_t select_next_w(const uint8_t *right, uint8_t *bd)
static bool check_automorphism(const GraphISO *g0, const GraphISO *g1, int solution[][2], int *solution_length)
static uint8_t select_next_v(uint8_t *left, uint8_t *bd)
static void update_incumbent(uint8_t cur[][2], int inc[][2], int cur_pos, int *inc_pos)
bool ED_uvedit_clipboard_maximum_common_subgraph(GraphISO *g0_input, GraphISO *g1_input, int solution[][2], int *solution_length, bool *r_search_abandoned)
static void select_bidomain(uint8_t domains[][BDS], int bd_pos, const uint8_t *left, int current_matching_size, bool connected)
static int calc_bound(const uint8_t domains[][BDS], int bd_pos, int cur_pos)
static void maximum_common_subgraph_internal(int incumbent[][2], int *inc_pos, uint8_t **adjmat0, int n0, uint8_t **adjmat1, int n1, bool *r_search_abandoned)
static void add_bidomain(uint8_t domains[][BDS], int *bd_pos, uint8_t left_i, uint8_t right_i, uint8_t left_len, uint8_t right_len, uint8_t is_adjacent, uint8_t cur_pos)
static uint8_t find_min_value(const uint8_t *arr, uint8_t start_idx, uint8_t len)