J2pij1Lmax — различия между версиями
System29a (обсуждение | вклад)  | 
				System29a (обсуждение | вклад)   | 
				||
| Строка 1: | Строка 1: | ||
{{в разработке}}  | {{в разработке}}  | ||
| − | Дано <tex>n</tex> работ <tex>i = 1,...,n</tex> и две машины, обозначенные как A и B. <tex>i</tex>-тая работа состоит из <tex>n_i</tex> операций <tex>O_{ij} (j = 1,..n_i)</tex>, которые должны быть выполнены последовательно и, при этом, если <tex>O_{ij} </tex>операция была совершена на машине <tex>A (B)</tex>, то операция <tex>O_{i,j-1}</tex> должна быть совершена на машине <tex>B (A)</tex>. Таким образом, <tex>i</tex>-тая работа может характеризоваться двумя значениями: количество операций <tex>n_i</tex> и машина, на которой была совершена первая операция. Пусть <tex>r = \  | + | Дано <tex>n</tex> работ <tex>i = 1,...,n</tex> и две машины, обозначенные как A и B. <tex>i</tex>-тая работа состоит из <tex>n_i</tex> операций <tex>O_{ij} (j = 1,..n_i)</tex>, которые должны быть выполнены последовательно и, при этом, если <tex>O_{ij} </tex>операция была совершена на машине <tex>A (B)</tex>, то операция <tex>O_{i,j-1}</tex> должна быть совершена на машине <tex>B (A)</tex>. Таким образом, <tex>i</tex>-тая работа может характеризоваться двумя значениями: количество операций <tex>n_i</tex> и машина, на которой была совершена первая операция. Пусть <tex>r = \sum_{i=1}^n N_i</tex> {{---}} общее количество операций.  | 
| − | Допустим, самым ранним моментом, когда операция может начать выполняться, будет момент времени 0, а верхняя граница момента начала выполнения последней операции обозначим за <tex>t_{max}</tex>. К примеру, мы можем выбрать <tex>t_{max} = r</tex>. Тогда расписание можно представить как два массива <tex>A(t)</tex> и <tex>B(t) (t = 0,...,t_{max})</tex>, где <tex>A(t) = O_{ij}</tex>, если операция <tex>O_ij</tex> должна выполниться на машине <tex>A</tex> в момент времени <tex>t</tex> и <tex>A(t) =</tex><tex>   | + | Допустим, самым ранним моментом, когда операция может начать выполняться, будет момент времени 0, а верхняя граница момента начала выполнения последней операции обозначим за <tex>t_{max}</tex>. К примеру, мы можем выбрать <tex>t_{max} = r</tex>. Тогда расписание можно представить как два массива <tex>A(t)</tex> и <tex>B(t) (t = 0,...,t_{max})</tex>, где <tex>A(t) = O_{ij}</tex>, если операция <tex>O_ij</tex> должна выполниться на машине <tex>A</tex> в момент времени <tex>t</tex> и <tex>A(t) =</tex><tex> \emptyset</tex>, если машина <tex>A</tex> простаивает в этот момент. Будем называть <tex>\emptyset</tex> пустой операцией. И для каждой операции <tex>O_{ij}</tex>, выполняющейся на машине <tex>A</tex> существует <tex>t</tex>, для которого <tex>A(t) = O_{ij}</tex>. Аналогично для <tex>B_i</tex>. Расписание достижимо тогда и только тогда, когда из <tex>A(t) (B(t)) = O_{ij} , 1 < j \le n_i</tex> следует <tex>O_{i,j-1} = B(s) (A(s))</tex> для некоторого <tex>s < t</tex>, и первая операция для каждой работы запланирована на нужной машине. Перестановку всех операций будем называть списком. Для данный списка <tex>L</tex> осуществимое расписание может быть создано следующим способом: планируем выполнять операции в порядке, соответствующим <tex>L</tex>, причем каждую операцию стараемся выполнить как можно раньше. Подобное расписание будем называть соответствующим <tex>L</tex> расписанием.     | 
<tex>С_i</tex> {{---}} время окончания работы <tex>i</tex> в достижимом расписании <tex>y = (A(t), B(t))</tex> можно рассчитать как:  | <tex>С_i</tex> {{---}} время окончания работы <tex>i</tex> в достижимом расписании <tex>y = (A(t), B(t))</tex> можно рассчитать как:  | ||
| − | <tex>C_i = max{t + 1 | A(t)</tex> или <tex>B(t)</tex> {{---}} операция <tex>i</tex>-той работы}  | + | <tex>C_i = max\{t + 1 | A(t)\}</tex> или <tex>B(t)</tex> {{---}} операция <tex>i</tex>-той работы}  | 
Задача заключается в том, что для данного каждой работе <tex>i</tex> дедлайна <tex>d_i \ge 0</tex> мы хотим найти достижимое расписание с наименьшими максимальным временем опоздания:  | Задача заключается в том, что для данного каждой работе <tex>i</tex> дедлайна <tex>d_i \ge 0</tex> мы хотим найти достижимое расписание с наименьшими максимальным временем опоздания:  | ||
| Строка 29: | Строка 29: | ||
Давайте детально рассмотрим алгоритм. <tex>T1</tex> и <tex>T2</tex> обозначают первый период времени <tex>t \ge 0</tex>, когда соответсвующие машины <tex>A</tex> и <tex>B</tex> бездействуют. <tex>LAST(i)</tex> обозначает время окончания последней запланированной операции <tex>i</tex>-той работы. <tex>Z</tex> {{---}} множество работ, где <tex>d_i \ge r</tex>    | Давайте детально рассмотрим алгоритм. <tex>T1</tex> и <tex>T2</tex> обозначают первый период времени <tex>t \ge 0</tex>, когда соответсвующие машины <tex>A</tex> и <tex>B</tex> бездействуют. <tex>LAST(i)</tex> обозначает время окончания последней запланированной операции <tex>i</tex>-той работы. <tex>Z</tex> {{---}} множество работ, где <tex>d_i \ge r</tex>    | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | schedule(O_{ij})  | + |  main()  | 
| − | 	if \mu_{ij} = A then do  | + |    for k: -r + 1 to r - 1 do  | 
| − | + |      L(k) = \emptyset;  | |
| − | + |  		Z := (empty);  | |
| − | + |  	for i:= 1 to n do  | |
| − | + |  		if d_i < r then  | |
| − | + |  			for j := 1 to n_i do  | |
| − | + |  				добавить O_{ij} в L(d_i - n_i + j)  | |
| − | + |  		else  | |
| − | + |  			добавить работу i в Z  | |
| − | + |  	for i := 1 to n do  | |
| − | + |  		LAST(i) := 0;  | |
| − | + |  	T1 := 0;  | |
| − | + |  	T2 := 0;  | |
| − | + |  	for k := -r + 1 to r - 1 do  | |
| − | + |  		while L(k) \ne \emptyset do  | |
| − | + |  			Выбрать задание O_{ij} из L(k)  | |
| − | + |  			L(k) := L(k)\{O_{ij}};  | |
| − | + |  			schedule(O_{ij})    | |
| − | + |  	while z \ne \emptyset do  | |
| + |  		Выбрать работу i из Z  | ||
| + |  			Z := Z\{i};  | ||
| + |  			for j := 1 to n_i  | ||
| + |  				schedule(O_{ij}) 	  | ||
| + | |||
| + | |||
| + |  schedule(O_{ij})  | ||
| + |  	if \mu_{ij} = A then do  | ||
| + |  		if T1 < LAST(i) then do  | ||
| + |  			t := LAST(i)  | ||
| + |  			A(t) := O_{ij}  | ||
| + |  		else  | ||
| + |  			t := T1;  | ||
| + |  			A(t) := O_{ij};  | ||
| + |  			while A(T_1) \ne \emptyset do    | ||
| + |  				T1 := T1 + 1;  | ||
| + |  	else  | ||
| + |  		if T2 < LAST(i) then do  | ||
| + |  			t := LAST(i)  | ||
| + |  			B(t) := O_{ij}  | ||
| + |  		else  | ||
| + |  			t := T2;  | ||
| + |  			A(t) := O_{ij};  | ||
| + |  			while B(T_2) \ne \emptyset do    | ||
| + |  				T2 := T2 + 1;  | ||
| + |  	LAST(i) := t + 1  | ||
Очевидно, что количество шагов алгоритма ограничено <tex>O(r)</tex>  | Очевидно, что количество шагов алгоритма ограничено <tex>O(r)</tex>  | ||
Версия 21:05, 21 июня 2012
Дано работ и две машины, обозначенные как A и B. -тая работа состоит из операций , которые должны быть выполнены последовательно и, при этом, если операция была совершена на машине , то операция должна быть совершена на машине . Таким образом, -тая работа может характеризоваться двумя значениями: количество операций и машина, на которой была совершена первая операция. Пусть — общее количество операций.
Допустим, самым ранним моментом, когда операция может начать выполняться, будет момент времени 0, а верхняя граница момента начала выполнения последней операции обозначим за . К примеру, мы можем выбрать . Тогда расписание можно представить как два массива и , где , если операция должна выполниться на машине в момент времени и , если машина простаивает в этот момент. Будем называть пустой операцией. И для каждой операции , выполняющейся на машине существует , для которого . Аналогично для . Расписание достижимо тогда и только тогда, когда из следует для некоторого , и первая операция для каждой работы запланирована на нужной машине. Перестановку всех операций будем называть списком. Для данный списка осуществимое расписание может быть создано следующим способом: планируем выполнять операции в порядке, соответствующим , причем каждую операцию стараемся выполнить как можно раньше. Подобное расписание будем называть соответствующим расписанием. — время окончания работы в достижимом расписании можно рассчитать как:
или — операция -той работы}
Задача заключается в том, что для данного каждой работе дедлайна мы хотим найти достижимое расписание с наименьшими максимальным временем опоздания:
Следующий алгоритм решает эту задачу:
* Введём для каждой операции величину * Создадим список всех операций , упорядоченный в порядке неубывания значений * Найдем соответствующее списку расписание.
Этот алгоритм может быть реализованным с асимптотикой . Однако, мы будем использовать эвристику с хешами и улучшим асимптотику алгоритма до .
Мы предполагаем, что для и хотя бы для одной работы . Иначе, вычтем из всех минимальное значение по
Так как для всех и справедливо как минимум для одной работы . К тому же, можно предположить, что . Таким образом, работы с , то есть c можно смело игнорировать. Они не влияют на значение улучшаемой функции , так как для некого Можно выполнять эти работы в любом порядке после всех остальных. Для оставшихся операций мы имеем:
Каждую операцию мы кладём в соответствующую корзину , где . На втором шаге мы планируем операции соответственно возрастающему по номеру корзины порядку, где операции из одной корзины могут выполнятся в произвольном порядке.
Давайте детально рассмотрим алгоритм. и обозначают первый период времени , когда соответсвующие машины и бездействуют. обозначает время окончания последней запланированной операции -той работы. — множество работ, где
main()
  for k: -r + 1 to r - 1 do
    L(k) = \emptyset;
		Z := (empty);
	for i:= 1 to n do
		if d_i < r then
			for j := 1 to n_i do
				добавить O_{ij} в L(d_i - n_i + j)
		else
			добавить работу i в Z
	for i := 1 to n do
		LAST(i) := 0;
	T1 := 0;
	T2 := 0;
	for k := -r + 1 to r - 1 do
		while L(k) \ne \emptyset do
			Выбрать задание O_{ij} из L(k)
			L(k) := L(k)\{O_{ij}};
			schedule(O_{ij}) 
	while z \ne \emptyset do
		Выбрать работу i из Z
			Z := Z\{i};
			for j := 1 to n_i
				schedule(O_{ij}) 	
schedule(O_{ij})
	if \mu_{ij} = A then do
		if T1 < LAST(i) then do
			t := LAST(i)
			A(t) := O_{ij}
		else
			t := T1;
			A(t) := O_{ij};
			while A(T_1) \ne \emptyset do 
				T1 := T1 + 1;
	else
		if T2 < LAST(i) then do
			t := LAST(i)
			B(t) := O_{ij}
		else
			t := T2;
			A(t) := O_{ij};
			while B(T_2) \ne \emptyset do 
				T2 := T2 + 1;
	LAST(i) := t + 1
Очевидно, что количество шагов алгоритма ограничено