分区问题-使用最少的内存查找集合中的元素

时间:2020-03-30 11:16:02

标签: algorithm memory dynamic-programming partition bottom-up

我必须使用动态编程解决经典的分区问题。我有一个正整数数组作为输入,其中 n 是整数的个数,而 s 是这些整数的和,我需要找到两个整数之间的最小差可以使用输入中的元素构造的集合。我还需要输出一个与输入数组大小相同的布尔数组,称为“所有权”,该数组提供元素是否属于第一个或第二个最佳集合的信息。例如,如果所有权数组中的第 th个值为true,则输入数组的第 th个元素属于第一组。

我的程序使用自下而上的方法找到最小的差异。该任务要求程序的内存复杂度为θ s ),因此,我使用的不是像传统方法那样使用大小为n * s的2D数组该数组只有两行。在第一行中,我保留了先前处理过的行,因此我可以根据先前的解决方案来填充第二行。

问题是通过这种内存优化,我不确定应该如何填充所有权数组。

我知道人们可以使用n * s数组中的回溯来检索集合元素。但是,由于任务的限制,我无法使用该方法,而且我不知道如何有效地构造所有权表。

有没有一种方法可以有效地找到哪些元素属于这两个最佳集合中的哪一个,并具有存储复杂度θ s )和时间复杂度的约束O (n * s)自下而上的方法?

我当前在C#中的代码:

 public int SetsMinimum(int[] tab, out bool[] ownership)
 {
    int n = tab.Length;
    int sum = 0;
    foreach (int v in tab) sum += v;
    ownership = new bool[n];
    bool[,] dp = new bool[2, sum + 1];
    int min = sum;
    dp[0, 0] = true;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= sum; j++)
        {
            dp[1,j] = dp[0,j];
            if (j - tab[i - 1]>=0)
            {
                dp[1, j] = dp[0, j - tab[i - 1]];
            }     
        }
        for(int j=0;j<sum;j++)
        {
            if (dp[1, j])
            {
                int cMin = Math.Abs((sum - j) - j);
                if (min>cMin)
                {
                    min = cMin;
                }
            }    
            dp[0, j] = dp[1, j];
        }
    }
    return min;
}

2 个答案:

答案 0 :(得分:0)

您可以编写一个在内存O(s)中运行的函数,该函数运行DP一次并找出最接近的目标和。

您可以编写一个在内存O(s)中运行的函数,该函数运行一次DP,并找出所有权数组中的最后一个值是否必须为true或false才能达到目标总和。

重复运行第二个函数以从头到尾挑选所有权数组的每个成员。

这将占用内存O(s)和时间O(s * n^2)。 (因为您运行n DP,所以与通常的DP方法占用内存O(s * n)和时间O(s * n)相对。

答案 1 :(得分:0)

我昨天找到了解决方案:

  1. 初始化另一个# plot(nom) for nomogram nom <- structure(list(n.fjernet = structure(list(n.fjernet = c(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133), Xbeta = c(`1` = -0.0114560716414661, `2` = -0.0171841074621991, `3` = -0.0229121432829322, `4` = -0.0286401791036652, `5` = -0.0343682149243983, `6` = -0.0400962507451313, `7` = -0.0458242865658644, `8` = -0.0515523223865974, `9` = -0.0572803582073305, `10` = -0.0630083940280635, `11` = -0.0687364298487966, `12` = -0.0744644656695296, `13` = -0.0801925014902627, `14` = -0.0859205373109957, `15` = -0.0916485731317288, `16` = -0.0973766089524618, `17` = -0.103104644773195, `18` = -0.108832680593928, `19` = -0.114560716414661, `20` = -0.120288752235394, `21` = -0.126016788056127, `22` = -0.13174482387686, `23` = -0.137472859697593, `24` = -0.143200895518326, `25` = -0.148928931339059, `26` = -0.154656967159792, `27` = -0.160385002980525, `28` = -0.166113038801258, `29` = -0.171841074621991, `30` = -0.177569110442725, `31` = -0.183297146263458, `32` = -0.189025182084191, `33` = -0.194753217904924, `34` = -0.200481253725657, `35` = -0.20620928954639, `36` = -0.211937325367123, `37` = -0.217665361187856, `38` = -0.223393397008589, `39` = -0.229121432829322, `40` = -0.234849468650055, `41` = -0.240577504470788, `42` = -0.246305540291521, `43` = -0.252033576112254, `44` = -0.257761611932987, `45` = -0.26348964775372, `46` = -0.269217683574453, `47` = -0.274945719395186, `48` = -0.280673755215919, `49` = -0.286401791036652, `50` = -0.292129826857386, `51` = -0.297857862678119, `52` = -0.303585898498852, `53` = -0.309313934319585, `54` = -0.315041970140318, `55` = -0.320770005961051, `56` = -0.326498041781784, `57` = -0.332226077602517, `58` = -0.33795411342325, `59` = -0.343682149243983, `60` = -0.349410185064716, `61` = -0.355138220885449, `62` = -0.360866256706182, `63` = -0.366594292526915, `64` = -0.372322328347648, `65` = -0.378050364168381, `66` = -0.383778399989114, `67` = -0.389506435809847, `68` = -0.39523447163058, `69` = -0.400962507451313, `70` = -0.406690543272047, `71` = -0.41241857909278, `72` = -0.418146614913513, `73` = -0.423874650734246, `74` = -0.429602686554979, `75` = -0.435330722375712, `76` = -0.441058758196445, `77` = -0.446786794017178, `78` = -0.452514829837911, `79` = -0.458242865658644, `80` = -0.463970901479377, `81` = -0.46969893730011, `82` = -0.475426973120843, `83` = -0.481155008941576, `84` = -0.486883044762309, `85` = -0.492611080583042, `86` = -0.498339116403775, `87` = -0.504067152224508, `88` = -0.509795188045241, `89` = -0.515523223865974, `90` = -0.521251259686707, `91` = -0.526979295507441, `92` = -0.532707331328174, `93` = -0.538435367148907, `94` = -0.54416340296964, `95` = -0.549891438790373, `96` = -0.555619474611106, `97` = -0.561347510431839, `98` = -0.567075546252572, `99` = -0.572803582073305, `100` = -0.578531617894038, `101` = -0.584259653714771, `102` = -0.589987689535504, `103` = -0.595715725356237, `104` = -0.60144376117697, `105` = -0.607171796997703, `106` = -0.612899832818436, `107` = -0.618627868639169, `108` = -0.624355904459902, `109` = -0.630083940280635, `110` = -0.635811976101369, `111` = -0.641540011922102, `112` = -0.647268047742835, `113` = -0.652996083563568, `114` = -0.658724119384301, `115` = -0.664452155205034, `116` = -0.670180191025767, `117` = -0.6759082268465, `118` = -0.681636262667233, `119` = -0.687364298487966, `120` = -0.693092334308699, `121` = -0.698820370129432, `122` = -0.704548405950165, `123` = -0.710276441770898, `124` = -0.716004477591631, `125` = -0.721732513412364, `126` = -0.727460549233097, `127` = -0.73318858505383, `128` = -0.738916620874563, `129` = -0.744644656695296, `130` = -0.750372692516029, `131` = -0.756100728336763, `132` = -0.761828764157496), points = c(`1` = 27.84103949255, `2` = 27.6285124735229, `3` = 27.4159854544958, `4` = 27.2034584354687, `5` = 26.9909314164416, `6` = 26.7784043974145, `7` = 26.5658773783874, `8` = 26.3533503593603, `9` = 26.1408233403332, `10` = 25.9282963213061, `11` = 25.715769302279, `12` = 25.5032422832519, `13` = 25.2907152642248, `14` = 25.0781882451977, `15` = 24.8656612261706, `16` = 24.6531342071435, `17` = 24.4406071881164, `18` = 24.2280801690893, `19` = 24.0155531500622, `20` = 23.8030261310351, `21` = 23.590499112008, `22` = 23.3779720929809, `23` = 23.1654450739538, `24` = 22.9529180549267, `25` = 22.7403910358996, `26` = 22.5278640168725, `27` = 22.3153369978454, `28` = 22.1028099788183, `29` = 21.8902829597912, `30` = 21.6777559407641, `31` = 21.465228921737, `32` = 21.2527019027099, `33` = 21.0401748836828, `34` = 20.8276478646557, `35` = 20.6151208456286, `36` = 20.4025938266015, `37` = 20.1900668075744, `38` = 19.9775397885473, `39` = 19.7650127695202, `40` = 19.5524857504931, `41` = 19.339958731466, `42` = 19.1274317124389, `43` = 18.9149046934118, `44` = 18.7023776743847, `45` = 18.4898506553576, `46` = 18.2773236363305, `47` = 18.0647966173034, `48` = 17.8522695982763, `49` = 17.6397425792492, `50` = 17.4272155602221, `51` = 17.214688541195, `52` = 17.0021615221679, `53` = 16.7896345031408, `54` = 16.5771074841137, `55` = 16.3645804650866, `56` = 16.1520534460595, `57` = 15.9395264270324, `58` = 15.7269994080053, `59` = 15.5144723889782, `60` = 15.3019453699511, `61` = 15.089418350924, `62` = 14.8768913318969, `63` = 14.6643643128698, `64` = 14.4518372938427, `65` = 14.2393102748156, `66` = 14.0267832557885, `67` = 13.8142562367614, `68` = 13.6017292177343, `69` = 13.3892021987072, `70` = 13.1766751796801, `71` = 12.964148160653, `72` = 12.7516211416259, `73` = 12.5390941225988, `74` = 12.3265671035717, `75` = 12.1140400845446, `76` = 11.9015130655175, `77` = 11.6889860464904, `78` = 11.4764590274633, `79` = 11.2639320084362, `80` = 11.0514049894091, `81` = 10.838877970382, `82` = 10.6263509513549, `83` = 10.4138239323278, `84` = 10.2012969133007, `85` = 9.98876989427365, `86` = 9.77624287524655, `87` = 9.56371585621945, `88` = 9.35118883719235, `89` = 9.13866181816525, `90` = 8.92613479913816, `91` = 8.71360778011105, `92` = 8.50108076108396, `93` = 8.28855374205686, `94` = 8.07602672302976, `95` = 7.86349970400266, `96` = 7.65097268497556, `97` = 7.43844566594846, `98` = 7.22591864692136, `99` = 7.01339162789426, `100` = 6.80086460886717, `101` = 6.58833758984007, `102` = 6.37581057081297, `103` = 6.16328355178587, `104` = 5.95075653275877, `105` = 5.73822951373167, `106` = 5.52570249470457, `107` = 5.31317547567747, `108` = 5.10064845665037, `109` = 4.88812143762328, `110` = 4.67559441859617, `111` = 4.46306739956908, `112` = 4.25054038054198, `113` = 4.03801336151488, `114` = 3.82548634248778, `115` = 3.61295932346068, `116` = 3.40043230443358, `117` = 3.18790528540648, `118` = 2.97537826637939, `119` = 2.76285124735228, `120` = 2.55032422832519, `121` = 2.33779720929809, `122` = 2.12527019027099, `123` = 1.91274317124389, `124` = 1.70021615221679, `125` = 1.48768913318969, `126` = 1.27516211416259, `127` = 1.06263509513549, `128` = 0.850108076108397, `129` = 0.637581057081296, `130` = 0.425054038054198, `131` = 0.212527019027097, `132` = 0)), info = list(nfun = 3L, predictor = "n.fjernet", effect.name = "n.fjernet", type = "main")), n.sygdom = structure(list(n.sygdom = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40), Xbeta = c(`133` = 0, `134` = 0.32236136668714, `135` = 0.648650531337351, `136` = 0.909274081797897, `137` = 1.09719119915252, `138` = 1.2269431700224, `139` = 1.31307128102872, `140` = 1.37011681879267, `141` = 1.41262106993544, `142` = 1.452701773308, `143` = 1.49278247668057, `144` = 1.53286318005315, `145` = 1.57294388342572, `146` = 1.61302458679829, `147` = 1.65310529017085, `148` = 1.69318599354344, `149` = 1.733266696916, `150` = 1.77334740028855, `151` = 1.81342810366113, `152` = 1.8535088070337, `153` = 1.89358951040629, `154` = 1.93367021377884, `155` = 1.97375091715141, `156` = 2.01383162052397, `157` = 2.05391232389658, `158` = 2.09399302726916, `159` = 2.13407373064171, `160` = 2.17415443401433, `161` = 2.21423513738691, `162` = 2.25431584075947, `163` = 2.29439654413205, `164` = 2.33447724750454, `165` = 2.37455795087723, `166` = 2.41463865424957, `167` = 2.45471935762221, `168` = 2.49480006099482, `169` = 2.53488076436739, `170` = 2.57496146774009, `171` = 2.61504217111266, `172` = 2.65512287448523, `173` = 2.69520357785787 ), points = c(`133` = 0, `134` = 11.9605572408505, `135` = 24.0668473679043, `136` = 33.7367495824038, `137` = 40.7090287415156, `138` = 45.5232094563172, `139` = 48.7188163378863, `140` = 50.8353739973004, `141` = 52.412407045637, `142` = 53.8995193254604, `143` = 55.3866316052841, `144` = 56.8737438851078, `145` = 58.3608561649314, `146` = 59.8479684447552, `147` = 61.3350807245785, `148` = 62.8221930044026, `149` = 64.309305284226, `150` = 65.7964175640487, `151` = 67.283529843873, `152` = 68.7706421236966, `153` = 70.257754403521, `154` = 71.7448666833438, `155` = 73.2319789631674, `156` = 74.7190912429907, `157` = 76.2062035228159, `158` = 77.6933158026398, `159` = 79.1804280824625, `160` = 80.6675403622881, `161` = 82.1546526421122, `162` = 83.6417649219352, `163` = 85.1288772017594, `164` = 86.6159894815798, `165` = 88.103101761408, `166` = 89.5902140412232, `167` = 91.0773263210494, `168` = 92.5644386008743, `169` = 94.0515508806979, `170` = 95.5386631605266, `171` = 97.0257754403502, `172` = 98.5128877201739, `173` = 100)), info = list(nfun = 3L, predictor = "n.sygdom", effect.name = "n.sygdom", type = "main")), ecs = structure(list(ecs = c("No", "Yes"), Xbeta = c(`174` = 0, `175` = 0.352802098746005), points = c(`174` = 0, `175` = 13.0899981598574 )), info = list(nfun = 3L, predictor = "ecs", effect.name = "ecs", type = "main")), contra.pos = structure(list(contra.pos = c("Ipsi.", "Contra."), Xbeta = c(`176` = 0, `177` = -0.149053853083395 ), points = c(`176` = 5.53033745977221, `177` = 0)), info = list( nfun = 3L, predictor = "contra.pos", effect.name = "contra.pos", type = "main")), total.points = list(x = c(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140)), lp = list( x = c(8.59901355289166, 27.1504878870641, 45.7019622212365, 64.253436555409, 82.8049108895814, 101.356385223754, 119.907859557926, 138.459333892099), x.real = c(-1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5)), `Probability of 1 year survival` = list( x = c(132.923978485611, 122.154519662532, 112.023605643525, 101.668496222993, 90.3441422980089, 77.0166169199793, 59.6149679036176, 31.771904926561), x.real = c(0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9), fat = c("0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9"), which = c(FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE )), `Probability of 3 years survival` = list(x = c(111.455658509363, 98.1672795067317, 87.3978451509886, 77.2669361851509, 66.9118109221416, 55.5874579746061, 42.2599719337723, 24.8583283615229), x.real = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8), fat = c("0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8"), which = c(FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)), `Probability of 5 years survival` = list(x = c(96.3366217164868, 83.0483098712202, 72.2788509036931, 62.1479468853665, 51.7928216700398, 40.468478298201, 27.1409533137375, 9.73931852863156), x.real = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8), fat = c("0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8"), which = c(FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE))), info = list( fun = list(function (x) surv(12, x), function (x) surv(36, x), function (x) surv(60, x)), lp = TRUE, lp.at = c(-1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5), discrete = c(n.fjernet = FALSE, n.sygdom = FALSE, ecs = TRUE, contra.pos = TRUE, studie = TRUE), funlabel = c("Probability of 1 year survival", "Probability of 3 years survival", "Probability of 5 years survival" ), fun.at = NULL, fun.lp.at = NULL, Abbrev = list(), minlength = 4, conf.int = FALSE, R = structure(c(-0.761828764157496, -0.0114560716414661, 0, 2.69520357785787, 0, 0.352802098746005, -0.149053853083395, 0), .Dim = c(2L, 4L), .Dimnames = list(NULL, c("n.fjernet", "n.sygdom", "ecs", "contra.pos"))), sc = 37.1029486683449, maxscale = 100, Intercept = -1.23176092093802, nint = 10, space.used = c(main = 4, ia = 0)), class = "nomogram") 元素数组,并用零填充。
  2. 在dp数组上进行迭代时,将第一个元素的先前数组索引保存到允许实现每个和的位置。例如,对于$item_name = json_decode($_POST['cart'], true)[0]["_data"]["item_name"]; $array_of_items_in_cart = json_decode($_POST['cart'], true); $first_item_in_cart = array_of_items_in_cart[0]; $name_of_first_item_in_cart = first_item_in_cart["_data"]["item_name"]; $first_item_discount = first_item_in_cart["_discount"]; ,当您使用第二个元素时,可以达到7的总和,而第一个元素可以获得sum+1的总和。
  3. 获得最小差异后,选择{4,3,2}4的最佳集合和之一。
  4. 跳转到索引数组中求和,将所有权数组在索引数组中指向的索引中设置为true,然后从总和中减去元素。重复直到您的总和为零。

此方法将仅选择必要的元素来构建集合和之一,并且将在 O (n * s)时间内起作用,因为可以在自下而上的方法中填充索引数组。