使用plsql进行回归编程以获得完美匹配

问题描述 投票:-1回答:1

我正在研究一种从一组数字中获得完美匹配的函数(最小值为1,最大值为25)。

我在下面的DDL中提供了创建表的信息,还有我正在使用的insert语句和代码,这些代码目前存在性能问题。

运行以下代码。

如果记录数为20,将在2分钟内运行。

我在这里给出的总记录为33,因此将花费大量时间,不确定是否完成。

任何输入都会有很大的帮助。

CREATE TABLE xx_perfect_combi_test
(
  trx_id  NUMBER
 ,trx_val NUMBER
);

INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051303, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051304, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051305, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051306, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051307, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051308, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051309, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051310, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051311, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051312, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051313, 22);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051314, 22);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051315, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051316, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051317, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051318, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051319, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051320, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051321, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051322, 18);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051323, 17);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051324, 11);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051325, 9);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051326, 8);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051327, 6);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051328, 6);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051329, 4);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051330, 3);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051331, 1);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051332, 1);

COMMIT;

我的程序:

DECLARE
  ln_total_sum       NUMBER := 315;
  ln_orig_diff       NUMBER := ln_total_sum;
  ln_curr_diff       NUMBER;

  lv_trx_ids         VARCHAR2 (4000);
  lv_trx_ids_buff    VARCHAR2 (4000);

  lv_dummy_return    VARCHAR2 (4000);

  FUNCTION perfect_combo (p_curr_sum     IN NUMBER
                         ,p_curr_vals    IN VARCHAR2
                         ,p_rownumber    IN NUMBER)
    RETURN VARCHAR2
  IS
    lv_buf_trx_id    VARCHAR2 (4000);
  BEGIN
    FOR c1 IN (SELECT   *
               FROM (SELECT stg2.*
                           ,ROW_NUMBER () OVER (ORDER BY stg2.trx_val DESC) AS rownumber1
                     FROM xx_perfect_combi_test stg2)
                     WHERE rownumber1 > p_rownumber
                     ORDER BY trx_val DESC) LOOP
      --dbms_output.put_line ('p_curr_sum: ' || p_curr_sum);
      --dbms_output.put_line ('p_curr_vals: ' || p_curr_vals);
      --dbms_output.put_line ('p_rownumber: ' || p_rownumber);
      --dbms_output.put_line ('---------------------------------------------------');

      IF ( (p_curr_sum + c1.trx_val) = ln_total_sum)
      THEN
        lv_buf_trx_id  := p_curr_vals;
        lv_buf_trx_id  := lv_buf_trx_id || c1.trx_id || ';';
        lv_trx_ids     := lv_buf_trx_id;
        RETURN lv_trx_ids;
      ELSIF (p_curr_sum + c1.trx_val) > ln_total_sum
      THEN
        ln_curr_diff  := ln_total_sum - p_curr_sum;

        IF ln_curr_diff < ln_orig_diff
        THEN
          ln_orig_diff     := ln_curr_diff;
          lv_trx_ids_buff  := p_curr_vals;
        END IF;

        CONTINUE;
      ELSIF (p_curr_sum + c1.trx_val) < ln_total_sum
      THEN
        ln_curr_diff     := ln_total_sum - (p_curr_sum + c1.trx_val);

        lv_buf_trx_id    := p_curr_vals;
        lv_buf_trx_id    := lv_buf_trx_id || c1.trx_id || ';';

        IF ln_curr_diff < ln_orig_diff
        THEN
          ln_orig_diff     := ln_curr_diff;
          lv_trx_ids_buff  := lv_buf_trx_id;
        END IF;

        lv_dummy_return  := perfect_combo ( (p_curr_sum + c1.trx_val), lv_buf_trx_id, c1.rownumber1);
      END IF;
    END LOOP;

    RETURN NULL;
  END perfect_combo;
BEGIN
  lv_dummy_return  := perfect_combo (0, NULL, 0);

  DBMS_OUTPUT.put_line ('lv_trx_ids: ' || lv_trx_ids);
  DBMS_OUTPUT.put_line ('lv_trx_ids_buff: ' || lv_trx_ids_buff);
END;
oracle plsql match regression subset-sum
1个回答
0
投票

找到匹配项后,我们必须完全退出函数调用。我创建了一个全局变量,并检查是否找到匹配项,然后从函数调用中完全返回。这样,程序就可以快速完成。

© www.soinside.com 2019 - 2024. All rights reserved.