A表
id days
553 3
562 6
563 3
554 15
555 12
556 6
557 9
558 4
559 11
560 20
561 19 B表
fromid toid
561 562
553 554
554 555
555 556
556 557
556 558
557 559
559 560
558 561
560 561
562 563 开始节点:553.开始日期:2008-07-03 A表的days表示该ID对应的任务完成需要的天数,
B表的fromid,toid均来自于A表的id
fromid,toid分别表示fromid任务完成了,toid任务才能开始.
开始的节点为553,当然,也会存在多个任务同时开始的情况
求出来的结果应该如下:
id begindates enddates
553 2008-7-3 2008-7-5
562 2008-10-6 2008-10-11
563 2008-10-12 2008-10-14
554 2008-7-6 2008-7-20
555 2008-7-21 2008-8-1
556 2008-8-2 2008-8-7
557 2008-8-8 2008-8-16
558 2008-8-8 2008-8-11
559 2008-8-17 2008-8-27
560 2008-8-28 2008-9-16
561 2008-9-17 2008-10-5
我写的递归函数如下:
$updatelist = array();
//当前任务为其它任务的前置任务,递归更新其它任务的开始时间
function modDate($db, $current_job, $pid, $job_id, &$updatelist){
$sql = "select t.JOB_FLAG, t.FROMID, t.JOBID, p.JOB_DAY from B t,A p where t.PID = :pid and t.FROMID = :job_id and p.JOBID = t.JOBID and p.PID = t.PID and p.PID = :pid";
$st = $db->Execute($sql, array('pid'=>$pid, 'job_id'=>$job_id));
while($row = $st->FetchRow()){
if($row['JOBID'] == $current_job) continue;
if($row['JOB_FLAG'] == '1') continue;
if(!in_array($row['JOBID'], $updatelist)) $updatelist[] = $row['JOBID'];
$drow = $db->GetRow("select max(END_DATE) END_DATE from A t,B p where t.PID = p.PID and t.JOBID = p.FROMID and p.PID = :pid and p.JOBID = :job_id", array('pid'=>$pid,'job_id'=>$row['JOBID']));
//最早开始时间为其所有的前置任务的最迟结束时间
$minus_day = $row['JOB_DAY'] - 1; $max_end_date = $drow['END_DATE'];
$date_list = explode("-",$max_end_date);
$max_end_date = date('Y-m-d', mktime(0, 0, 0, $date_list[1], $date_list[2]+1, $date_list[0])); $nextday = date('Y-m-d', mktime(0, 0, 0,
substr($max_end_date,5,2), substr($max_end_date,8,2) + $minus_day, substr($max_end_date,0,4)));
$db->Execute("update A SET BEGIN_DATE = :begin_date,END_DATE = :end_date where PID = :pid and JOBID = :job_id",array('begin_date'=>$max_end_date,'end_date'=>$nextday,'pid'=>$pid, 'job_id'=>$row['JOBID']));
$db->Execute("update B set JOB_FLAG = '1' where PID = :pid and JOBID = :job_id and FROMID = :fromid",array('pid'=>$pid, 'job_id'=>$row['JOBID'],'fromid'=>$row['FROMID']));
}
if(count($updatelist)>0){
$job_id = array_pop($updatelist);
modDate($db, $current_job, $pid, $job_id, $updatelist);
}
}
id days
553 3
562 6
563 3
554 15
555 12
556 6
557 9
558 4
559 11
560 20
561 19 B表
fromid toid
561 562
553 554
554 555
555 556
556 557
556 558
557 559
559 560
558 561
560 561
562 563 开始节点:553.开始日期:2008-07-03 A表的days表示该ID对应的任务完成需要的天数,
B表的fromid,toid均来自于A表的id
fromid,toid分别表示fromid任务完成了,toid任务才能开始.
开始的节点为553,当然,也会存在多个任务同时开始的情况
求出来的结果应该如下:
id begindates enddates
553 2008-7-3 2008-7-5
562 2008-10-6 2008-10-11
563 2008-10-12 2008-10-14
554 2008-7-6 2008-7-20
555 2008-7-21 2008-8-1
556 2008-8-2 2008-8-7
557 2008-8-8 2008-8-16
558 2008-8-8 2008-8-11
559 2008-8-17 2008-8-27
560 2008-8-28 2008-9-16
561 2008-9-17 2008-10-5
我写的递归函数如下:
$updatelist = array();
//当前任务为其它任务的前置任务,递归更新其它任务的开始时间
function modDate($db, $current_job, $pid, $job_id, &$updatelist){
$sql = "select t.JOB_FLAG, t.FROMID, t.JOBID, p.JOB_DAY from B t,A p where t.PID = :pid and t.FROMID = :job_id and p.JOBID = t.JOBID and p.PID = t.PID and p.PID = :pid";
$st = $db->Execute($sql, array('pid'=>$pid, 'job_id'=>$job_id));
while($row = $st->FetchRow()){
if($row['JOBID'] == $current_job) continue;
if($row['JOB_FLAG'] == '1') continue;
if(!in_array($row['JOBID'], $updatelist)) $updatelist[] = $row['JOBID'];
$drow = $db->GetRow("select max(END_DATE) END_DATE from A t,B p where t.PID = p.PID and t.JOBID = p.FROMID and p.PID = :pid and p.JOBID = :job_id", array('pid'=>$pid,'job_id'=>$row['JOBID']));
//最早开始时间为其所有的前置任务的最迟结束时间
$minus_day = $row['JOB_DAY'] - 1; $max_end_date = $drow['END_DATE'];
$date_list = explode("-",$max_end_date);
$max_end_date = date('Y-m-d', mktime(0, 0, 0, $date_list[1], $date_list[2]+1, $date_list[0])); $nextday = date('Y-m-d', mktime(0, 0, 0,
substr($max_end_date,5,2), substr($max_end_date,8,2) + $minus_day, substr($max_end_date,0,4)));
$db->Execute("update A SET BEGIN_DATE = :begin_date,END_DATE = :end_date where PID = :pid and JOBID = :job_id",array('begin_date'=>$max_end_date,'end_date'=>$nextday,'pid'=>$pid, 'job_id'=>$row['JOBID']));
$db->Execute("update B set JOB_FLAG = '1' where PID = :pid and JOBID = :job_id and FROMID = :fromid",array('pid'=>$pid, 'job_id'=>$row['JOBID'],'fromid'=>$row['FROMID']));
}
if(count($updatelist)>0){
$job_id = array_pop($updatelist);
modDate($db, $current_job, $pid, $job_id, $updatelist);
}
}
<html xmlns:v="urn:schemas-microsoft-com:vml">
<HEAD>
<TITLE>网络图 </TITLE>
</HEAD>
<STYLE>
v\:* { BEHAVIOR: url(#default#VML) }
</STYLE>
</HEAD>
<BODY>
<v:group ID="group1" style="position:relative;WIDTH:1200px;HEIGHT:1200px;" coordsize = "1800,1800">
<v:Rect style="position:absolute;width:120px;height:54px;left:0px;top:0px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A1[553,3] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:1120px;top:160px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A12[562,6] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:800px;top:240px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A13[563,3] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:160px;top:0px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A2[554,15] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:320px;top:0px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A3[555,12] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:480px;top:0px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A4[556,6] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:640px;top:0px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A5[557,9] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:640px;top:80px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A6[558,4] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:800px;top:0px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A7[559,11] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:960px;top:0px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A9[560,20] </v:TextBox>
</v:Rect>
<v:Rect style="position:absolute;width:120px;height:54px;left:1120px;top:0px;" fillcolor='#E8EFF7'>
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
<v:TextBox inset="2pt,2pt,2pt,2pt" style="font-size:10.2pt;">A11[561,19] </v:TextBox>
</v:Rect>
<v:line from="120,27" to="160,27" style="position:absolute;"/> <v:line from="152,22" to="160,27" style="position:absolute;"/>
<v:line from="152,32" to="160,27" style="position:absolute;"/>
<v:line from="280,27" to="320,27" style="position:absolute;"/> <v:line from="312,22" to="320,27" style="position:absolute;"/>
<v:line from="312,32" to="320,27" style="position:absolute;"/>
<v:line from="440,27" to="480,27" style="position:absolute;"/> <v:line from="472,22" to="480,27" style="position:absolute;"/>
<v:line from="472,32" to="480,27" style="position:absolute;"/>
<v:line from="600,27" to="640,27" style="position:absolute;"/> <v:line from="632,22" to="640,27" style="position:absolute;"/>
<v:line from="632,32" to="640,27" style="position:absolute;"/>
<v:line from="545,54" to="545,107" style="position:absolute;"/> <v:line from="545,107" to="640,107" style="position:absolute;"/> <v:line from="632,102" to="640,107" style="position:absolute;"/>
<v:line from="632,112" to="640,107" style="position:absolute;"/>
<v:line from="760,27" to="800,27" style="position:absolute;"/> <v:line from="792,22" to="800,27" style="position:absolute;"/>
<v:line from="792,32" to="800,27" style="position:absolute;"/>
<v:line from="760,102" to="1175,102" style="position:absolute;"/> <v:line from="1175,102" to="1175,54" style="position:absolute;"/> <v:line from="1179,62" to="1175,54" style="position:absolute;"/>
<v:line from="1169,62" to="1175,54" style="position:absolute;"/>
<v:line from="920,27" to="960,27" style="position:absolute;"/> <v:line from="952,22" to="960,27" style="position:absolute;"/>
<v:line from="952,32" to="960,27" style="position:absolute;"/>
<v:line from="1080,27" to="1120,27" style="position:absolute;"/> <v:line from="1112,22" to="1120,27" style="position:absolute;"/>
<v:line from="1112,32" to="1120,27" style="position:absolute;"/>
<v:line from="1180,54" to="1180,160" style="position:absolute;"/> <v:line from="1184,152" to="1180,160" style="position:absolute;"/>
<v:line from="1174,152" to="1180,160" style="position:absolute;"/>
<v:line from="1175,214" to="1175,267" style="position:absolute;"/> <v:line from="1175,267" to="920,267" style="position:absolute;"/> <v:line from="928,272" to="920,267" style="position:absolute;"/>
<v:line from="928,262" to="920,267" style="position:absolute;"/>
</v:group>
</BODY>
</HTML>