Heute hab ich mal eine Frage:
Gegeben sei eine Tabelle:
test=*# select * from tasks;
id | duration
----+----------
1 | 5.00
2 | 10.00
3 | 4.00
4 | 12.00
5 | 2.00
6 | 8.00
7 | 7.00
8 | 1.00
9 | 3.00
10 | 2.00
11 | 11.00
12 | 12.00
13 | 3.00
14 | 4.00
15 | 5.00
16 | 6.00
17 | 7.00
18 | 8.00
19 | 9.00
20 | 2.00
21 | 1.00
(21 rows)
Ich möchte nun die Tasks anhand der Ausführungsdauer so auf z.B. 3 gleiche Maschinen verteilen, daß diese 3 Maschinen in etwa gleich ausgelastet sind und (mehr oder weniger) zur gleichen Zeit fertig werden.
Hat da jemand eine gute Idee?
Andreas
Hm, Schnellschuss aus dem Bauch raus:
- Summe aller Stunden bilden
- diese durch drei teilen um die ungefähre angepeilte Zeit pro Maschine zu bekommen
- von oben nach unten anfangen die Jobs zuzuteilen bis die angepeilte Zeit voll ist
Wie weit dir das hilft weiß ich nicht aber das wäre jetzt mein erster Lösungsversuch.
cu tb.
Okay. Ich hab es.
Diese Funktion
create or replace function do_tasks(in int, out t text) returns setof text as $$
declare
r record;
m record;
begin
delete from jobs;
insert into jobs (id, duration) select generate_series(1,$1),0;
for r in select id, duration from tasks order by duration desc loop
select into m id, sum(coalesce(duration,0)) from jobs group by id order by sum(duration) asc limit 1;
insert into jobs (id, job, duration) values (m.id, r.id, r.duration);
end loop;
delete from jobs where job is null;
return next ;
end;
$$ language plpgsql;
fülls diese Tabelle:
test=# \d jobs
Table "public.jobs"
Column | Type | Modifiers
----------+---------------+-----------
id | integer |
job | text |
duration | numeric(10,2) |
Tests:
test=*# select * from do_tasks(4);
t
---
(1 row)
test=*# select id, sum(duration) from jobs group by id;
id | sum
----+-------
4 | 31.00
3 | 31.00
2 | 30.00
1 | 30.00
(4 rows)
test=*# select * from do_tasks(7);
t
---
(1 row)
test=*# select id, sum(duration) from jobs group by id;
id | sum
----+-------
7 | 18.00
6 | 17.00
5 | 17.00
4 | 18.00
3 | 18.00
2 | 17.00
1 | 17.00
(7 rows)
Noch etwas hübsch machen, fertig.
Andreas