主頁 > 軟體工程 > 最小增量數,以便所有元素都有一個公約數

最小增量數,以便所有元素都有一個公約數

2021-11-03 12:31:54 軟體工程

我最近在一次采訪中遇到了這個問題:

給定一組數字X = [X_1, X_2, ...., X_n],其中X_i <= 500for 1 <= i <= n增加集合中的數字(僅正增量),以便集合中的每個元素都有一個公約數 >=2,并且所有增量的總和最小。

例如,如果X = [5, 7, 7, 7, 7]新集合是X = [7, 7, 7, 7, 7]因為您可以將 2 添加到 X_1。X = [6, 8, 8, 8, 8]有一個公分母 2 但不正確,因為我們要加 6(在 4 個 7 的每一個上加 2 到 5 和 1)。

我有一個看似有效的解決方案(因為它通過了所有測驗用例),它回圈遍歷 <500 的素數,并為每個X_iinX找到大于 X_i 的素數的最接近倍數。

function closest_multiple(x, y)
    return ceil(x/y)*y

min_increment = inf
for each prime_number < 500:
    total_increment = 0
    for each element X_i in X:
        total_increment  = closest_multiple(X_i, prime_number) - X_i
    min_increment = min(min_increment, total_increment)

return min_increment

它在技術上是 O(n) 但有沒有更好的方法來解決這個問題?有人建議我使用動態編程,但我不確定它如何適合這里。

uj5u.com熱心網友回復:

常量有界條目案例

X_i受常數限制時,漸近達到的最佳時間是O(n),因為讀取所有輸入至少需要那么長時間。有一些實際改進:

  1. 過濾掉重復項,這樣您就可以使用(元素,頻率)對的串列。
  2. 提前停止回圈。
  3. 的更快計算closest_multiple(x, p) - x這稍微依賴于硬體/語言,但單個整數模運算幾乎肯定比 int -> float cast、float 除法、ceiling() 呼叫和對相同數量的乘法更快。
freq_counts <- Initialize-Counter(X) // List of (element, freq) pairs
min_increment = inf

for each prime_number < 500:
    total_increment = 0
    for each pair X_i, freq in freq_counts:
        total_increment  = (prime_number - (X_i % prime_number)) * freq
        if total_increment >= min_increment: break
    min_increment = min(min_increment, total_increment)

return min_increment

大型條目案例

對于統一選擇的隨機資料,答案幾乎總是使用“2”作為除數,而更大的質數除數幾乎是不可能的。但是,讓我們解決最壞的情況。

在這里,讓 max(X) = M,所以我們的輸入大小是O(n (log M))位。我們想要一個在該輸入大小中是次指數的解決方案,因此不可能找到低于 M(甚至 sqrt(M))的所有質數。我們正在尋找任何能夠為我們提供min-total-increment 的素數我們將把這樣的素數稱為min-prime找到這樣的素數后,我們可以得到線性時間內的最小總增量。我們將使用分解方法以及兩個觀察結果。

  • 觀察 1:答案總是至多n,因為素數 2 除以所需的增量X_i至多為 1。

  • 觀察 2:我們試圖找到除我們的大部分條目X_i之外的質數或比X_i稍大的數X_iConsecutive-Product-Divisors[i]是除以任何一個的所有素數的集合X_i or X_i 1,我將其縮寫為CPD[i]這正是除 的所有素數的集合X_i * (1 X_i)

  • (觀察 2 續)如果U是我們答案的已知上限(此處最多為 n),并且p是 X 的最小素數,則p必須除以我們的 CPD 條目中的一個X_iX_i 1至少N - U/2一個。使用 CPD 陣列上的頻率計數來查找所有這些素數。

一旦您有了候選素數串列(保證所有最小素數都在此串列中),您就可以使用您的演算法單獨測驗每個素數。由于數字 k 最多可以有O(log k)不同的素數除數,這給出了O(n log M)可能的不同素數,這些素數可以整除
[X_1*(1 X_1), X_2*(1 X_2), ... X_n*(1 X_n)]構成我們候選串列的至少一半的數字您可以通過一些更仔細的分析來降低這個界限,但它可能不會強烈影響整個演算法的漸近運行時間。


大型條目的更優化復雜性

這個解決方案的復雜性很難用簡短的形式寫出來,因為瓶頸是分解n最大尺寸的數字M,加上對最大尺寸數字的O(n^2 log M)算術(即加法、減法、乘法、模)運算M這并不意味著運行時未知:如果您選擇任何整數分解演算法和大整數算術演算法,您可以準確地推匯出運行時。不幸的是,由于因式分解,上述演算法最著名的運行時間是超多項式(但次指數)

How can we do better? I did find a more complicated solution, based on Greatest Common Divisors (GCD) and dynamic-programming-like that runs in polynomial time (although likely much slower on non-astronomical-size inputs) since it doesn't rely on factoring.

The solution relies on the fact that at least one of the following two statements is true:

  1. The number 2 is a min-prime for X, or
  2. For at least one value of i, 1 <= i <= n there is an optimal solution where X_i remains unincremented, i.e. where one of the divisors of X_i produces a min-total-increment.

GCD-Based polynomial time algorithm

We can test 2 and all small primes quickly for their minimum costs. In fact, we'll test all primes p, p <= n, which we can do in polynomial time, and factor out these primes from X_i and its first n increments. This leads us to the following algorithm:

// Given: input list X = [X_1, X_2, ... X_n].
// Subroutine compute-min-cost(list A, int p) is 
// just the inner loop of the above algorithm.

min_increment = inf;
for each prime p <= n:
    min_increment = min(min_increment, compute-min-cost(X, p));

// Initialize empty, 2-D, n x (n 1) list Y[n][n 1], of offset X-values
for all 1 <= i <= n:
    for all 0 <= j <= n:
        Y[i][j] <- X[i]   j;

for each prime p <= n:  // Factor out all small prime divisors from Y
    for each Y[i][j]:
        while Y[i][j] % p == 0:
            Y[i][j] /= p;

for all 1 <= i <= n: // Loop 1
    // Y[i][0] is the test 'unincremented' entry
    // Initialize empty hash-tables 'costs' and 'new_costs'
    // Keys of hash-tables are GCDs,
    // Values are a running sum of increment-costs for that GCD

    costs[Y[i][0]] = 0;
    for all 1 <= k <= n: // Loop 2
        if i == k: continue;
        clear all entries from new_costs  // or reinitialize to empty
        for all 0 <= j < n: // Loop 3
            for each Key in costs: // Loop 4
                g = GCD(Key, Y[k][j]);
                if g == 1: continue;
                if g is not a key in new_costs:
                    new_costs[g] = j   costs[Key];
                else:
                    new_costs[g] = min(new_costs[g], j   costs[Key]);
        
        swap(costs, new_costs);
    if costs is not empty:
        min_increment = min(min_increment, smallest Value in costs);

return min_increment;

The correctness of this solution follows from the previous two observations, and the (unproven, but straightforward) fact that there is a list [X_1 r_1, X_2 r_2, ... , X_n r_n] (with 0 <= r_i <= n for all i) whose GCD is a divisor with minimum increment cost.

The runtime of this solution is trickier: GCDs can easily be computed in O(log^2(M)) time, and the list of all primes up to n can be computed in low poly(n) time. From the loop structure of the algorithm, to prove a polynomial bound on the whole algorithm, it suffices to show that the maximum size of our 'costs' hash-table is polynomial in log M. This is where the 'factoring-out' of small primes comes into play. After iteration k of loop 2, the entries in costs are (Key, Value) pairs, where each Key is the GCD of k 1 elements:
our initial Y[i][0], and [Y[1][j_1], Y[2][j_2], ... Y[k][j_k]] for some 0 <= j_l < n. The Value for this Key is the minimum increment sum needed for this divisor (i.e. sum of the j_l) over all possible choices of j_l.

There are at most O(log M) unique prime divisors of Y[i][0]. Each such prime divides at most one key in our 'costs' table at any time: Since we've factored out all prime divisors below n, any remaining prime divisor p can divide at most one of the n consecutive numbers in any Y[j] = [X_j, 1 X_j, ... n-1 X_j]. This means the overall algorithm is polynomial, and has a runtime below O(n^4 log^3(M)).

From here, the open questions are whether a simpler algorithm exists, and how much better than this bound can you achieve. You can definitely optimize this algorithm (including using the early-stopping and frequency counts from before). It's also likely that better bounds on counting large-and-distinct-prime-divisors for consecutive numbers shows this solution is already better than that stated runtime, but a simplification of this solution would be very interesting.

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/346030.html

標籤:数学 动态规划

上一篇:求和藥劑

下一篇:AJAX成功/錯誤功能不起作用

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more