22. Вычислительные процессы: #298259
В файле содержится информация о совокупности $N$ вычислительных процессов, которые могут выполняться параллельно или последовательно. Будем говорить, что процесс $B$ зависит от процесса $A$, если для выполнения процесса $B$ необходимы результаты выполнения процесса $A$. В этом случае процессы могут выполняться только последовательно.
Информация о процессах представлена в файле в виде таблицы. В первой строке таблицы указан идентификатор процесса (ID), во второй строке таблицы – время его выполнения в миллисекундах, в третьей строке перечислены с разделителем «;» ID процессов, от которых зависит данный процесс. Если процесс является независимым, то в таблице указано значение $0$.
Пример организации данных в файле:
| ID процесса $B$ | Время выполнения процесса $B$ (мс) | ID процесса(ов) $A$ |
|---|---|---|
| $1$ | $4$ | $0$ |
| $2$ | $3$ | $0$ |
| $3$ | $1$ | $1$; $2$ |
| $4$ | $7$ | $3$ |
Определите минимальное время, через которое завершится выполнение всей совокупности процессов, при условии, что все независимые друг от друга процессы могут выполняться параллельно.
Используя данные из файла, составим таблицу, на какой мс может закончиться каждый из процессов. Независимые процессы $9$, $1$, $2$, $11$ и $4$ завершатся на $19$, $23$, $24$, $28$ и $29$ мс соответственно.
Процесс $3$ зависит от $2$, значит завершится на $24+25=49$ мс. Процесс $5$ зависит от $1$, $2$ и $3$: позже всех $3$, поэтому $5$ завершится на $49+26=75$ мс. Процесс $6$ зависит от $2$, $3$ и $4$ — здесь тоже позже всех $3$, значит $6$ завершится на $49+27=76$ мс.
Процесс $7$ зависит от $4$ и $6$, позже заканчивается $6$, поэтому $7$ завершится на $76+25=101$ мс. Процесс $13$ зависит от $4$, $5$, $9$ и $11$: позже всех $5$ (на $75$ мс), значит $13$ завершится на $75+34=109$ мс. Процесс $10$ зависит от $3$, $4$ и $7$ и завершится на $101+16=117$ мс. Процесс $8$ зависит от $3$, $5$, $6$ и $7$: позже всех $7$, поэтому $8$ завершится на $101+21=122$ мс.
Процесс $12$ зависит от $7$, $8$ и $11$: позже всех $8$ (на $122$ мс), значит $12$ завершится на $122+31=153$ мс. От него дальше идут две ветки: процесс $15$ зависит от $12$ и $13$ и завершится на $153+27=180$ мс, процесс $14$ зависит от $8$ и $12$ и завершится на $153+32=185$ мс.
Наконец, процесс $16$ зависит от $14$ и $15$: позже заканчивается $14$, поэтому $16$ завершится на $185+24=209$ мс. А процесс $17$ зависит от $10$, $11$ и $15$: позже всех $15$ (на $180$ мс), значит $17$ завершится на $180+33=213$ мс. Это и есть самое позднее время.
Таким образом, вся совокупность процессов завершится на $213$ мс.
| Время, мс | ID процесса |
|---|---|
| $19$ | $9$ |
| $23$ | $1$ |
| $24$ | $2$ |
| $28$ | $11$ |
| $29$ | $4$ |
| $49$ | $3$ |
| $75$ | $5$ |
| $76$ | $6$ |
| $101$ | $7$ |
| $109$ | $13$ |
| $117$ | $10$ |
| $122$ | $8$ |
| $153$ | $12$ |
| $180$ | $15$ |
| $185$ | $14$ |
| $209$ | $16$ |
| $213$ | $17$ |
Приведём другое решение на языке Python.
import pandas as pd
from functools import lru_cache
df = pd.read_excel('22-23.ods', engine='odf', header=None, skiprows=1)
t, dep = {}, {}
for _, row in df.iterrows():
pid = int(row[0])
t[pid] = int(row[1])
s = str(row[2]).replace(' ', '').strip() # в файле есть пробелы после ';'
dep[pid] = [] if s == '0' else [int(x) for x in s.split(';')]
@lru_cache(None)
def finish(p): # момент завершения процесса p
return t[p] + max([finish(d) for d in dep[p]], default=0)
print(max(finish(p) for p in t)) # 213
Обратите внимание, что последним завершается не процесс с наибольшим номером в цепочке: $16$ заканчивается на $209$ мс, а $17$ — на $213$ мс, хотя стартует раньше. Поэтому и нужен максимум по всем процессам.