Graphics commands

AllZero[x_,opts___] := And @@ Thread[Chop[x,opts]==0]

Needs["Splines`"]

Midpoints[c_,x_] := With[{y=(x/(Plus @@ x))},
c (Drop[FoldList[Plus,0,y],1]-(y/2)) - (c/2)] /;  ((c≥Plus @@ x) && !AllZero[x])

Midpoints[c_,x_] := Drop[FoldList[Plus,0,x],1]-(x/2)-(c/2)-((-c+Plus @@ x)/2) /; c<Plus @@ x

Midpoints[c_,{}] := {};
Midpoints[c_,x_] := Table[0,{Length[x]}] /; AllZero[x]

DrawLink[link[C_,xy_ : {.5,0} ,L_ : 1,name_ : "link",opts___]] := 
If[C==0,{},With[{x=xy[[1]],y=xy[[2]]},
Graphics[{
{GrayLevel[.8],Opacity[.5],
Rectangle[{x-L/2,y+C/2},{x+L/2,y-C/2}],
Disk[{x-L/2,y},{.1 L,C/2},{Pi/2,3Pi/2}] ,
Disk[{x+L/2,y},{.1 L,C/2},{-Pi/2,Pi/2}]},
Circle[{x-L/2,y},{.1 L,C/2}] ,
Circle[{x+L/2,y},{.1 L,C/2},{-Pi/2,Pi/2}],
Line[{{x-L/2,y+C/2},{x+L/2,y+C/2}}],
Line[{{x-L/2,y-C/2},{x+L/2,y-C/2}}]
}] ]]

DrawLinkLabel[link[C_,xy_ : {.5,0},L_:1,name_:"link",opts___],load_] := Module [ {label},
labelfunc = Label /. {opts} /. {Label->None};
If[labelfunc===None,{},labelfunc[C,load,xy]]
]

LinkName[link[C_,xy_ : {.5,0}, L_ : 1, name_ : "link",rest___]] := name

LinkCapacity[link[C_,rest___]] := C

LinkLength[link[C_,xy_ : {.5,0},L_:1,rest___]] := L

LinkCoord[link[C_,xy_:{.5,0},rest___]] := xy

FlowName[flow[rate_,waypoints_,name_]] := name

FlowRate[flow[rate_,rest___]] := rate

LinksUsed[flow[rate_,waypoints_,name_]] := Cases[waypoints, _String ]

Waypoints[flow[rate_,waypoints_,rest___]] := waypoints

Second[x_] := x[[2]]

Indicator[True] = 1;
Indicator[False] = 0;

(* Spline from start to link, line through link, spline through midpoint to next link, line through link, spline to end *)
(* Spline from start to link, line through link, spline to end *)

DrawFlow[{point[p1_],uselink[{p2_,len_},mp_],path__}] := {
Spline[{p1,p2+{-len/2-.2,mp},p2+{-len/2,mp}},Bezier],
DrawFlow[{uselink[{p2,len},mp],path}]}

DrawFlow[{uselink[{p1_,len1_},mp1_],uselink[{p2_,len2_},mp2_],path__}] :=
{Line[{p1+{-len1/2,mp1},p1+{len1/2,mp1}}],
Spline[{p1+{len1/2,mp1},p1+{len1/2+.2,mp1},(p1+{len1/2+.2,mp1}+p2+{-len2/2-.2,mp2})/2,p2+{-len2/2-.2,mp2},p2+{-len2/2,mp2}},CompositeBezier],
DrawFlow[{uselink[{p2,len2},mp2],path}]}

DrawFlow[{uselink[{p1_,len_},mp_],point[p2_]}] := {
Line[{p1+{-len/2,mp},p1+{len/2,mp}}],
Spline[{p1+{len/2,mp},p1+{len/2+.2,mp},p2},Bezier]}

DrawFlow[{uselink[{p1_,len1_},mp1_],uselink[{p2_,len2_},mp2_]}] := {
Line[{p1+{-len1/2,mp1},p1+{len1/2,mp1}}],
Spline[{p1+{len1/2,mp1},p1+{len1/2+.2,mp1},(p1+{len1/2+.2,mp1}+p2+{-len2/2-.2,mp2})/2,p2+{-len2/2-.2,mp2},p2+{-len2/2,mp2}},CompositeBezier],
Line[{p2+{-len2/2,mp2},p2+{len2/2,mp2}}] }

CleanLine[line_] := Module [ {s,a,b,cleansegment,res,inds},
cleansegment[s_Spline] := Table[s[[3]][x],{x,0,Length[First[s]]-1,1/10}];
cleansegment[Line[{a_,b_}]] := {a,b};
res = Flatten[cleansegment /@ line,1];
inds = Prepend[Select[Range[Length[res]],res[[#]]≠res[[#-1]]&],1];
Line[Part[res,inds]]
]

ShowNetwork[objects_,opts___] := Module [ {links,flows,linknames,linkdefs,flownames,linksused,adjacency,midpoints,GetMidpoints,flowdesc,flowpaths,cols,thicks,plotrange,loads},
links = Cases[objects,_link];
flows = Cases[objects,_flow];
linknames = Thread[Rule[LinkName /@ links,Range@Length@links]];
linkdefs = Thread[Rule[LinkName /@ links,{LinkCoord[#],LinkLength[#]}& /@ links]];
flownames = Thread[Rule[FlowName /@ flows, Range@Length@flows]];
linksused = LinksUsed /@ flows;
adjacency = Function[{linkname},Indicator@MemberQ[#,linkname]& /@ linksused] /@ (First /@ linknames);
(* What are the midpoints at each link? *)
midpoints = Thread[Midpoints[LinkCapacity /@ links,(FlowRate /@ flows #)& /@ adjacency]];
(* For each flow, what is its midpoint at each link it passes through? *)
GetMidpoints[links_List,flownum_] := If[!StringQ[#],#,uselink[#,midpoints[[# /. linknames,flownum]]]]& /@ links;
(* What is the load at each link? *)
loads = (FlowRate /@ flows #)& /@ adjacency;
(* Now, draw *)
flowdesc = MapThread[GetMidpoints,{Waypoints /@ flows, Range@Length@flows}] /. linkdefs;
flowpaths = CleanLine@Flatten@DrawFlow[#] & /@ flowdesc;
cols = FlowColours[Length@flows];
plotrange = PlotRange /. {opts} /. {PlotRange->{{Min[First /@ (LinkCoord /@ links) - (LinkLength /@ links)/2]-1,
Max[First /@ (LinkCoord /@ links) + (LinkLength /@ links)/2]+1},
{Min[Second /@ (LinkCoord /@ links) - (LinkCapacity /@ links)/2-1],
Max[Second /@ (LinkCoord /@ links) + (LinkCapacity /@ links)/2]+1}}};
thicks = Thickness /@ ((FlowRate /@ flows)/(plotrange[[1,2]]-plotrange[[1,1]]));
Show[{Graphics@Transpose[{cols, thicks,flowpaths}],
DrawLink /@ links,
Graphics@MapThread[DrawLinkLabel,{links,loads}]},
PlotRange->plotrange,Sequence @@ FilterRules[{opts},Except[PlotRange]]]
]

FlowColours[n_] := Table[ColorData["Pastel"][i],{i,0,1,1/(n-1)}];

FormatCapacity[x_,suffix_:""] := ToString[NumberForm[x,{3,0},NumberPadding->" ",NumberPoint->""]]<>suffix

FormatWnd[w_,suffix_:""] := ToString[NumberForm[w,{3,2},NumberPadding->" ",NumberPoint->"."]] <>suffix

FormatTime[x_] := ToString[NumberForm[1000 x,{3,0},NumberPadding->" ",NumberPoint->""]]<>" ms"

ShowLoad[C_,loads_,xy_] := Style[Text[NumberForm[100 (Plus @@ loads),{3,1}],xy,{1,0}],"Legend"]

ShowEachLoad[C_,loads_,xy_] := Style[Text[NumberForm[100 #,{3,1}]& /@ Reverse@loads,xy,{-1,0}],"Legend"]

ShowDrop[C_,loads_,xy_] := Style[Text[ToString@NumberForm[100 Max[0,1-C/(Plus @@ loads)],{3,1}]<>"%",xy,{0,0}],"Legend"]

PressedIf[pressed_] = If[pressed,{"DialogBox","Pressed"},"DialogBox"];

4 parallel links

updateMult3[ϵ_][{C1_,C2_,C3_,C4_,RTTa_,RTTb_,RTTc_},{Xa1_,Xa2_,Xb2_,Xb3_,Xc3_,Xc4_}] := Module [ {p,pp,trim,drifta1,drifta2,driftb2,driftb3,driftc3,driftc4,drifts,xx,res},
p[load_,service_] = Max[0,1-service/load];
pp = {p1->p[xa1,C1],p2->p[xa2+xb2,C2],p3->p[xb3+xc3,C3],p4->p[xc4,C4]};
trim[x_] = x+Exp[-5 x]/5;
drifta1 = ((Abs[((trim[xa1])/(xa1+xa2))])^ϵ)(1/(RTTa^2))-((Abs[xa1+xa2])/1)xa1 p1;
drifta2 =((Abs[((trim[xa2])/(xa1+xa2))])^ϵ)(1/(RTTa^2))-((Abs[xa1+xa2])/1)xa2 p2;
driftb2=((Abs[((trim[xb2])/(xb2+xb3))])^ϵ)(1/(RTTb^2))-((Abs[xb2+xb3])/1)xb2 p2;
driftb3=((Abs[((trim[xb3])/(xb2+xb3))])^ϵ)(1/(RTTb^2))-((Abs[xb2+xb3])/1)xb3 p3;
driftc3=((Abs[((trim[xc3])/(xc3+xc4))])^ϵ)(1/(RTTc^2))-((Abs[xc3+xc4])/1)xc3 p3;
driftc4=((Abs[((trim[xc4])/(xc3+xc4))])^ϵ)(1/(RTTc^2))-((Abs[xc3+xc4])/1)xc4 p4;
drifts = {drifta1,drifta2,driftb2,driftb3,driftc3,driftc4} /. pp /.  {xa1->Xa1,xa2->Xa2,xb2->Xb2,xb3->Xb3,xc3->Xc3,xc4->Xc4};
If[AllZero[drifts,(10^(-5))],None,
xx = {xa1->xa1[t],xa2->xa2[t],xb2->xb2[t],xb3->xb3[t],xc3->xc3[t],xc4->xc4[t]};
	res = NDSolve[{
xa1'[t]==(drifta1 /. pp /. xx), xa1[0]==Xa1,
xa2'[t]==(drifta2 /. pp /. xx), xa2[0]==Xa2,
xb2'[t]==(driftb2 /. pp  /. xx), xb2[0]==Xb2,
xb3'[t]==(driftb3 /. pp /. xx), xb3[0]==Xb3,
xc3'[t]==(driftc3 /. pp  /. xx), xc3[0]==Xc3,
xc4'[t]==(driftc4 /. pp /. xx), xc4[0]==Xc4
},
{xa1,xa2,xb2,xb3,xc3,xc4},
{t,0,10}];
{xa1[10],xa2[10],xb2[10],xb3[10],xc3[10],xc4[10]} /. First@res
]
]

displayMult3[{C1_,C2_,C3_,C4_,rest___},{Xa1_,Xa2_,Xb2_,Xb3_,Xc3_,Xc4_}] := (ShowNetwork[{
link[0,{-2,1},1,"srca"],
link[0,{-2,3},1,"srcb"],
link[0,{-2,5},1,"srcc"],
link[0,{3,1},1,"desta",Label->ShowLoad],
link[0,{3,3},1,"destb", Label->ShowLoad],
link[0,{3,5},1,"destc",Label->ShowLoad],
link[C1,{0,0},1,"link1",Label->ShowDrop],
link[C2 ,{0,2},1,"link2",Label->ShowDrop],
link[C3 ,{0,4},1,"link3",Label->ShowDrop],
link[C4 ,{0,6},1,"link4",Label->ShowDrop],
flow[Xa1,{"srca","link1","desta"},"flowa1"],
flow[Xa2,{"srca","link2","desta"},"flowa2"],
flow[Xb2,{"srcb","link2","destb"},"flowb2"],
flow[Xb3,{"srcb","link3","destb"},"flowb3"],
flow[Xc3,{"srcc","link3","destc"},"flowc3"],
flow[Xc4,{"srcc","link4","destc"},"flowc4"]
},PlotRange->{{-2,3},{-1,7}}, ImageSize->Scaled[.35]]
)

{cap1,cap2,cap3,cap4} = {100,100,100,100};
ctrl = {{"cap1",Slider[Dynamic[cap1],{1,200}],Dynamic[FormatCapacity[cap1," pkt/s"]]},
{"cap2",Slider[Dynamic[cap2],{1,200}],Dynamic[FormatCapacity[cap2," pkt/s"]]},
{"cap3",Slider[Dynamic[cap3],{1,200}],Dynamic[FormatCapacity[cap3," pkt/s"]]},
{"cap4",Slider[Dynamic[cap4],{1,200}],Dynamic[FormatCapacity[cap4," pkt/s"]]}} // Reverse// Grid;

Manipulate[
DynamicModule[{X={30,30,30,30,30,30},Xnew},
Dynamic[Refresh[
With[{pars={cap1,cap2,cap3,cap4,.1,.1,.1}},
If[(Xnew=updateMult3[1-ϵ][pars,X])===None,, X=Xnew];
displayMult3[pars/100,X/100]],
TrackedSymbols:>{cap1,cap2,cap3,cap4,ϵ}] ]],
Row[{Spacer[10],Grid[{
{"",Row[{Button["coupled",ϵ=0,Appearance->PressedIf[ϵ==0]],
Button["TCP/2",ϵ=2,Appearance->PressedIf[ϵ==2]]}],""},
{"ϵ=lability",Control[{{ϵ,0,""},0,3,.1}],Dynamic[NumberForm[ϵ,{2,1}]]},
{"(Subscript[C, 1])",Control[{{cap4,100,""},1,200,1}],Dynamic@FormatCapacity[cap4," pkt/s"]},
{"(Subscript[C, 2])",Control[{{cap3,100,""},1,200,1}],Dynamic@FormatCapacity[cap3," pkt/s"]},
{"(Subscript[C, 3])",Control[{{cap2,100,""},1,200,1}],Dynamic@FormatCapacity[cap2," pkt/s"]},
{"(Subscript[C, 4])",Control[{{cap1,100,""},1,200,1}],Dynamic@FormatCapacity[cap1," pkt/s"]}
}, Dividers->{False,{False,False,True}}, Spacings->{1,{1,1,2,1,1}},Alignment->{{Right,Left,Left},Center}] }],
ControlPlacement->Right,
SaveDefinitions->True
]

Demo

Laws 6-node example

updateMultLaws[ϵ_][{C1_,C2_,C3_,C4_,C5_,C6_,RTTa_,RTTb_},{Xa123_,Xa456_,Xb14_,Xb25_,Xb36_}] := Module [ {p,pp,trim,drifta123,drifta456,driftb14,driftb25,driftb36,drifts,xx,res},
p[load_,service_] = Max[0,1-service/load];
pp = {p1->p[xa123+xb14,C1],p2->p[xa123+xb25,C2],p3->p[xa123+xb36,C3],
p4->p[xa456+xb14,C4],p5->p[xa456+xb25,C5],p6->p[xa456+xb36,C6]};
trim[x_] = x+Exp[-5 x]/5;
drifta123 = ((Abs[((trim[xa123])/(xa123+xa456))])^ϵ)(1/(RTTa^2))-((Abs[xa123+xa456])/1)xa123 (p1+p2+p3);
drifta456 = ((Abs[((trim[xa456])/(xa123+xa456))])^ϵ)(1/(RTTa^2))-((Abs[xa123+xa456])/1)xa456(p4+p5+p6);
driftb14 = ((Abs[((trim[xb14])/(xb14+xb25+xb36))])^ϵ)(1/(RTTb^2))-((Abs[xb14+xb25+xb36])/1)xb14(p1+p4);
driftb25 = ((Abs[((trim[xb25])/(xb14+xb25+xb36))])^ϵ)(1/(RTTb^2))-((Abs[xb14+xb25+xb36])/1)xb25(p2+p5);
driftb36=((Abs[((trim[xb36])/(xb14+xb25+xb36))])^ϵ)(1/(RTTb^2))-((Abs[xb14+xb25+xb36])/1)xb36(p3+p6);
drifts = {drifta123,drifta456,driftb14,driftb25,driftb36} /. pp /.  {xa123->Xa123,xa456->Xa456,xb14->Xb14,xb25->Xb25,xb36->Xb36};
If[AllZero[drifts,(10^(-5))],None,
xx = {xa123->xa123[t],xa456->xa456[t],xb14->xb14[t],xb25->xb25[t],xb36->xb36[t]};
	res = NDSolve[{
xa123'[t]==(drifta123 /. pp /. xx), xa123[0]==Xa123,
xa456'[t]==(drifta456 /. pp /. xx), xa456[0]==Xa456,
xb14'[t]==(driftb14 /. pp /. xx), xb14[0]==Xb14,
xb25'[t]==(driftb25 /. pp /. xx), xb25[0]==Xb25,
xb36'[t]==(driftb36 /. pp /. xx), xb36[0]==Xb36
},
{xa123,xa456,xb14,xb25,xb36},
{t,0,10}];
{xa123[10],xa456[10],xb14[10],xb25[10],xb36[10]} /. First@res 
]
]

displayMultLaws[{C1_,C2_,C3_,C4_,C5_,C6_,rest___},{Xa123_,Xa456_,Xb14_,Xb25_,Xb36_}] := ShowNetwork[{
link[0,{-1,0},1,"srca"],
link[0,{-1,3},1,"srcb"],
link[0,{9,3},1,"desta",Label->ShowLoad],
link[0,{9,0},1,"destb",Label->ShowLoad],
link[C1,{1,1},.75,"link1",Label->ShowDrop],
link[C2,{3,2},.75,"link2",Label->ShowDrop],
link[C3,{5,3},.75,"link3",Label->ShowDrop],
link[C4,{3,0},.75,"link4",Label->ShowDrop],
link[C5,{5,1},.75,"link5",Label->ShowDrop],
link[C6,{7,2},.75,"link6",Label->ShowDrop],
flow[Xb14,{"srcb","link1","link4","destb"},"flowb14"],
flow[Xb25,{"srcb","link2","link5","destb"},"flowb25"],
flow[Xb36,{"srcb","link3","link6","destb"},"flowb36"],
flow[Xa456,{"srca","link4","link5","link6","desta"},"flowa456"],flow[Xa123,{"srca","link1","link2","link3","desta"},"flowa123"]
}, PlotRange->{{-1,10},{-1,3.5}}, ImageSize->Scaled[.5]
]

displayAdmissibleLaws[{C1_,C2_,C3_,C4_,C5_,C6_,rest___},{Xa123_,Xa456_,Xb14_,Xb25_,Xb36_}] := Module [ {g1,g2,g3,g4,g5,g6,g7},
g1 = 
RegionPlot[y1≥Min[C1+C4,C2+C5,C3+C6],{y1,0,3},{y2,0,3}];
g2 = RegionPlot[y1≥Min[C1+C5,C1+C6,C2+C4,C2+C6,C3+C4,C3+C5],{y1,0,3},{y2,0,3}];
g3 = RegionPlot[y2≥Min[C1+C2+C3,C4+C5+C6],{y1,0,3},{y2,0,3}];
g4 = RegionPlot[y1+y2≥Min[C1+C2+C6,C1+C3+C5,C2+C3+C4,C4+C5+C3,C4+C6+C2,C5+C6+C1],{y1,0,3},{y2,0,3}];
g5 = RegionPlot[2y1+y2≥Min[C1+C2+2C6,C1+C3+2C5,C2+C3+2C4,C4+C5+2C3,C4+C6+2C2,C5+C6+2C1],{y1,0,3},{y2,0,3}];
g6 = RegionPlot[3y1+2y2≥Min[2C1+2C5+C3+C6,2C2+2C4+C3+C6,2C1+2C6+C2+C5,2C3+2C4+C2+C5,2C3+2C5+C1+C4,2C2+2C6+C1+C4],
{y1,0,3},{y2,0,3}];
g7 = Graphics[{Red,PointSize[.02],Point[{Xa123+Xa456,Xb14+Xb25+Xb36}]}];
Show[{g7,{Graphics[Opacity[.2]],g1,g2,g3,g4,g5,g6}},Axes->True]
]

Manipulate[
DynamicModule[{X={30,30,30,30,30},Xnew},
Dynamic[Refresh[
With[{pars={cap1,cap2,cap3,cap4,cap5,cap6,rtta,rttb}},
If[(Xnew=updateMultLaws[1-ϵ][pars,X])===None,, X=Xnew];
Column[{displayMultLaws[pars/100,X/100],
displayAdmissibleLaws[pars/100,X/100]
}]],
TrackedSymbols:>{cap1,cap2,cap3,cap4,cap5,cap6,rtta,rttb,ϵ}] ]],
Row[{Spacer[10],Grid[{
{"",Row[{Button["coupled",ϵ=0,Appearance->PressedIf[ϵ==0]],
Button["TCP/2",ϵ=2,Appearance->PressedIf[ϵ==2]]}],""},
{"ϵ=lability",Control[{{ϵ,0,""},0,3,.1}],Dynamic[NumberForm[ϵ,{2,1}]]},
{"(Subscript[C, 1])",Control[{{cap1,100,""},1,200,1}],Dynamic@FormatCapacity[cap1," pkt/s"]},
{"(Subscript[C, 2])",Control[{{cap2,100,""},1,200,1}],Dynamic@FormatCapacity[cap2," pkt/s"]},
{"(Subscript[C, 3])",Control[{{cap3,100,""},1,200,1}],Dynamic@FormatCapacity[cap3," pkt/s"]},
{"(Subscript[C, 4])",Control[{{cap4,100,""},1,200,1}],Dynamic@FormatCapacity[cap4," pkt/s"]},
{"(Subscript[C, 5])",Control[{{cap5,100,""},1,200,1}],Dynamic@FormatCapacity[cap5," pkt/s"]},
{"(Subscript[C, 6])",Control[{{cap6,100,""},1,200,1}],Dynamic@FormatCapacity[cap6," pkt/s"]},
{"RTTa",Control[{{rtta,.1,""},.01,.25,.001}],Dynamic@FormatTime[rtta]},
{"RTTb",Control[{{rttb,.1,""},.01,.25,.001}],Dynamic@FormatTime[rttb]}
}, Dividers->{False,{False,False,True}}, Spacings->{1,{1,1,2,1,1,1,1}},Alignment->{{Right,Left,Left},Center}] }],
ControlPlacement->Right,
SaveDefinitions->True
]

Demo