主頁 > .NET開發 > 如何優化此演算法以重復查找和更新陣列的最小值?

如何優化此演算法以重復查找和更新陣列的最小值?

2022-03-07 00:19:16 .NET開發

輸入說明

我輸入的第一行包含兩個數字:?? 和 ??,分別表示集裝箱(2 ≤ ?? ≤ 20,000)數量和交貨數量(不超過100,000

在下面的 ?? 行中有成對的數字:?? 和 ??,其中 ?? 是交付的貨車數量(不超過20,000),?? 是每輛貨車中的礫石數量(不超過20,000)。

所有交貨的貨車總數不超過1,000,000.
在任何輸入容器中都不會包含超過1,000,000,000礫石的情況。

問題陳述

貨車一次清空一個,均勻地放入兩個連續的容器中。這些是確定選擇哪兩個相鄰容器的規則(其中containers[]表示n當前容器大小的串列):

  1. 在所有與 的對(containers[i], containers[i 1])0 <= i < n - 1,選擇最小化的對min(containers[i], containers[i 1])
  2. 如果有平局,則在平局對中選擇最小化的對max(containers[i], containers[i 1])(即最小化對中第二小的元素)
  3. 如果仍有平局,則在平局對中選擇(containers[i], containers[i 1])索引最小i的對。

礫石均勻地分布在這對中。如果貨車中的礫石數量為奇數,則 ID 較小的容器獲得剩余(1 個卵石)。

起初,所有容器都是空的。

例如:

lista = [0, 4, 3, 2, 0, 5, 4, 0, 3, 4, 2, 0]

My first smallest value in that list is 0 so there are 6 possibilities for different pairs

0,4 with indices 0 and 1  
0,2 with indices 3 and 4  
0,5 with indices 4 and 5  
4,0 with indices 6 and 7  
2,0 with indices 10 and 11  

My second smallest value in this 6 possibilities is 2 so I have two options

0,2 with indices 3 and 4  
2,0 with indices 10 and 11  

Indexes 3 and 4 are less than 10 and 11 so we will be dropping the wagons into containers with indexes [3, 4]

In the output:
Each of the ?? lines of output data should contain a single number - the number of pebbles in a container. The order of listing should be the same as the order of the identifiers.

Example
For the example input shown below:

6 4  
4 3  
1 2  
2 14  
4 3 

the correct answer is:

6  
10  
12  
7  
11  
8  

Explanation of the example

  1. In the first delivery:

    • The first wagon can be unloaded into pairs of containers (1, 2), (2, 3), (3, 4), (4, 5), (5, 6).
      We choose the first one and the values ??of the filling are (2 1 0 0 0 0).
    • Second wagon can be put into pairs of containers (3, 4), (4, 5), (5, 6).
      We choose the first one and the filling values ??are (2 1 2 1 0 0).
    • The third wagon can be put into a pair of containers (5, 6), which will give us the values ??of the fills (2 1 2 1 2 1).
    • The fourth wagon may be discharged into par containers (1, 2), (2, 3), (3, 4), (4, 5), (5, 6). We choose the first one and the filling values is (4 2 2 1 2 1).
  2. The second delivery changes the capacity of the containers as follows: (4 2 3 2 2 1).

  3. In the third delivery:

    • The first wagon may be unloaded only into a pair of containers (5, 6), and then the values ??for the fills are (4 2 3 2 9 8).
    • The second car can be unloaded into pairs (2, 3) or (3, 4). We choose the first one and the fill values ??are (4 9 10 2 9 8).
  4. 最后一次交貨更改填充物如下:

    • (4 9 10 4 10 8),
    • (6 10 10 4 10 8),
    • (6 10 12 5 10 8),
    • (6 10 12 7 11 8)

下面是我的程式代碼(它可以作業,但是,它不是大數字的最佳選擇)

n, d = map(int, input().split())

containers = []
for _ in range(n):
    containers.append(0)

for _ in range(d):
    wagons, gravel = map(int, input().split()) # w, z
    half_gravel = int(gravel/2)
    greater_half = int(gravel/2)  gravel%2
    for _ in range(wagons):
    
        i = min(range(len(containers) - 1),
        key=lambda i: sorted(containers[i : i 2]))

        containers[i]  = greater_half
        containers[i 1]  = half_gravel

for i in containers:
    print(i)

提前感謝您在優化程式方面的幫助

uj5u.com熱心網友回復:

您可以通過使用最小堆(即優先級佇列)更有效地解決這個問題,例如Python 標準庫中提供的那個。堆的主要目的是有效地跟蹤集合的最小元素,洗掉該最小值并添加新元素,這準確地反映了您的問題。

目前,該行:

i = min(range(len(containers) - 1),
        key=lambda i: sorted(containers[i : i 2]))

在你最里面的回圈中是一個O(n)成本操作,每次遍歷所有容器。您可以O(log n)通過保留 3 元組的最小堆來提高成本,這相當于:

min_heap = (min(containers[i:i 2]), max(containers[i:i 2]), i)
            for i in range(n-1)

這些 3 元組中的最小值,使用標準的字典順序,給出下一個容器來接收礫石。重要的是,我們不需要在回圈中實際重建這個堆,只需更新它

這里有一個微妙之處:一個容器一次可以是這兩個 3 元組的成員,所以如果我們更新一個容器對并將其 3 元組推回堆上,就會有一個過期的 3 - 最小堆中的元組,其值小于應有的值。這很好:我們可以實作一個減少鍵函式(使用這個堆相當困難),或者,只使用延遲更新

對于“延遲更新”,當從堆中彈出時,我們檢查堆的“報告的最小值”是否已過期,將其洗掉,然后重新插入更新版本。使用攤銷分析,因為會發生這種額外的堆操作成本每輛貨車最多累積一次,該演算法的運行時間仍然是
O(n total_wagons * log(n)).

Python代碼:

n, d = map(int, input().split())
containers = [0]*n

# Heap elements will be: (min(pair), max(pair), i) for pair = container[i:i 2]
min_heap = [(0, 0, i) for i in range(n-1)]

for _ in range(d):
    wagons, gravel = map(int, input().split())  # w, z
    half_gravel = gravel // 2
    greater_half = (gravel // 2)   gravel % 2
    for _ in range(wagons):

        # Find minimum element
        while True:
            smaller, larger, index = heapq.heappop(min_heap)
            # Check if entry is out of date
            actual_pair = sorted([containers[index], containers[index 1]])
            if actual_pair != [smaller, larger]:
                heapq.heappush(min_heap, (actual_pair[0], actual_pair[1], index))
            else:
                break

        containers[index]  = greater_half
        containers[index   1]  = half_gravel

        new_smaller, new_larger = sorted([containers[index], containers[index 1]])
        # This may cause index 1 entry to be out of date, which is OK.
        heapq.heappush(min_heap, (new_smaller, new_larger, index))

for i in containers:
    print(i)

注意:這種惰性更新策略通常用于避免需要減少鍵,并且在 Dijstra 演算法中更常用。但是,僅當佇列中的元素的存盤值可能小于其真實值時,它才有效,反之則不行。

The while True: loop looks a bit strange, but it's used because there may be up (in theory) O(n) out-of-date elements in the heap, so we need to keep popping, checking, and updating if the reported minimum is out-of-date.

How can we tell the number of elements in the heap doesn't change between wagons? At the start of every iteration of that loop, there has been no net change in the number of elements. In each iteration, we perform a pop at the start. Then, either we:

  • Find an out-of-date element, perform a push and continue (net 0),
  • Break (net -1 elements).

So after the while True loop, we are always at net -1 elements. After the loop, we always perform a push, bringing us back to no net change in heap size.

uj5u.com熱心網友回復:

我贊同@kcsquared 的方法,但會發布一個在所有方面都不那么“聰明”的變體,因此更可能是顯而易見的 ;-) 輸出與您在給出的單個測驗用例中的期望相匹配。

編輯:正如評論中指出的那樣,這并不總能解決上述問題。不過,我將把答案放在這里,因為它在其他方面具有指導意義。

from heapq import heapreplace

containers = [0] * n
h = [(0, i) for i in range(n)]

for wagons, gravel in [(4, 3),
                       (1, 2),
                       (2, 14),
                       (4, 3),
                      ]:
    half_gravel = gravel // 2
    greater_half = gravel - half_gravel
    for _ in range(wagons):
        while True:
            val, i = h[0]
            if val != containers[i]:
                heapreplace(h, (containers[i], i))
            else:
                break
        if i == len(containers) - 1:
            i -= 1
        elif i and containers[i-1] <= containers[i 1]:
            i -= 1
        containers[i]  = greater_half
        containers[i 1]  = half_gravel

for i in containers:
    print(i)
assert containers == [6, 10, 12, 7, 11, 8]

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

標籤:Python 算法

上一篇:找到最大的連續子陣列,使得子陣列中元素的函式小于給定值

下一篇:當負數位于陣列的右端時,選擇排序演算法不起作用

標籤雲
其他(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)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more