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++) {
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]);
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) {
214 bound += std::min(l_len, r_len);
217 if (cur_pos + bound <= inc_pos) {
226 if (bd[
RL] != bd[
IRL]) {
227 return left[bd[
L] + bd[
LL]];
230 if (left[bd[
L] + i] <
min) {
231 min = left[bd[
L] + i];
235 std::swap(left[bd[
L] + idx], left[bd[
L] + bd[
LL] - 1]);
244 for (
int i = 0; i <
len; i++) {
245 if (arr[start_idx + i] < min_v) {
246 min_v = arr[start_idx + i];
255 int current_matching_size,
259 int min_size = INT_MAX;
260 int min_tie_breaker = INT_MAX;
263 for (i = bd_pos - 1, bd = &domains[i][
L]; i >= 0 && bd[
P] == current_matching_size;
264 i--, bd = &domains[i][
L])
266 if (connected && current_matching_size > 0 && !bd[
ADJ]) {
270 if (
len < min_size) {
275 else if (
len == min_size) {
277 if (tie_breaker < min_tie_breaker) {
278 min_tie_breaker = tie_breaker;
283 if (best != INT_MAX && best != bd_pos - 1) {
285 for (i = 0; i <
BDS; i++) {
286 tmp[i] = domains[best][i];
288 for (i = 0; i <
BDS; i++) {
289 domains[best][i] = domains[bd_pos - 1][i];
291 for (i = 0; i <
BDS; i++) {
292 domains[bd_pos - 1][i] = tmp[i];
301 for (
uint8_t i = 0; i < bd[
RL] + 1; i++) {
302 if ((right[bd[
R] + i] > bd[
W] || bd[
W] ==
UINT8_MAX) && right[bd[
R] + i] <
min) {
303 min = right[bd[
R] + i];
319 bool *r_search_abandoned)
321 int min = std::min(n0, n1);
330 for (
int i = 0; i < n0; i++) {
333 for (
int i = 0; i < n1; i++) {
338 int iteration_count = 0;
341 if (iteration_count++ > 10000000) {
346 *r_search_abandoned =
true;
350 bd = &domains[bd_pos - 1][
L];
351 if (
calc_bound(domains, bd_pos, bd[
P]) + bd[
P] <= *inc_pos ||
352 (bd[
LL] == 0 && bd[
RL] == bd[
IRL]))
357 const bool connected =
false;
361 w = right[bd[
R] + bd[
W]];
362 right[bd[
R] + bd[
W]] = right[bd[
R] + bd[
RL]];
363 right[bd[
R] + bd[
RL]] =
w;
369 domains, &bd_pos, bd[
P] + 1, left, right,
v,
w, *inc_pos, adjmat0, adjmat1);
383 int *solution_length)
385 if (g0->
n != g1->
n) {
388 for (
int i = 0; i < g0->
n; i++) {
392 for (
int j = 0; j < g0->
n; j++) {
400 *solution_length = g0->
n;
407 int *solution_length,
408 bool *r_search_abandoned)
414 int n0 = g0_input->
n;
415 int n1 = g1_input->
n;
417 int min_size = std::min(n0, n1);
427 solution, &sol_len, g0->
adjmat, n0, g1->
adjmat, n1, r_search_abandoned);
428 *solution_length = sol_len;
430 bool result = (sol_len == n0);
432 for (
int i = 0; i < sol_len; i++) {
433 solution[i][0] = g0->
label[solution[i][0]];
434 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_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
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 int partition(uint8_t *arr, int start, int len, const uint8_t *adjrow)
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)