From: marko Date: Thu, 19 Jul 2007 02:33:14 +0000 (+0000) Subject: Manual indentation and whitespace cleanup. X-Git-Url: https://git.entuzijast.net/?a=commitdiff_plain;h=e93e985662c3a2af794436930c748a432dc5a2ed;p=imunes.git Manual indentation and whitespace cleanup. Bug found by: Submitted by: Reviewed by: Approved by: Obtained from: --- diff --git a/README b/README index ab7e9b1..03c4e99 100755 --- a/README +++ b/README @@ -37,7 +37,7 @@ System requirements netperf-2.2.4 3) Fetch, compile and install the following additional utilities: - + - vimage management utility, - ng_pipe, - ngctl diff --git a/annotations.tcl b/annotations.tcl index 2c1cff4..2c91f50 100644 --- a/annotations.tcl +++ b/annotations.tcl @@ -125,7 +125,7 @@ proc popupOvalDialog { c target modify color label lcolor } { set cancelcmd "destroy $wi; destroyNewoval $c" set applytext "Add oval" } - + frame $wi.butt -borderwidth 6 button $wi.butt.apply -text $applytext -command "$applycmd" button $wi.butt.cancel -text "Cancel" -command $cancelcmd @@ -186,7 +186,7 @@ proc popupOvalApply { c wi target} { lappend $object "color $color" lappend $object "label {$caption}" lappend $object "labelcolor $labelcolor" - + # draw it drawOval $object @@ -590,7 +590,7 @@ proc selectmarkEnter {c x y} { if { $x > [expr $x2-($x2-$x1)/8.0]} { set r 1 } if { $y < [expr $y1+($y2-$y1)/8.0]} { set u 1 } if { $y > [expr $y2-($y2-$y1)/8.0]} { set d 1 } - + if {$l==1} { if {$u==1} { $c config -cursor top_left_corner @@ -700,7 +700,7 @@ proc textConfig { c target } { if { [lsearch $effects bold ] != -1} {set textBold 1} if { [lsearch $effects italic ] != -1} {set textItalic 1} if { [lsearch $effects underline ] != -1} {set textUnderline 1} - + if { $fontfamily == "" } { set fontfamily $defTextFontFamily } @@ -783,7 +783,7 @@ proc textConfig { c target } { set applycmd "textConfigApply $c $wi $target " set cancelcmd "destroy $wi" - + button $wi.action.apply -text "Apply" -command "$applycmd" button $wi.action.cancel -text "Cancel" -command "$cancelcmd" bind $wi "$cancelcmd" diff --git a/exec.tcl b/exec.tcl index 76bae8c..66937e5 100755 --- a/exec.tcl +++ b/exec.tcl @@ -1,4 +1,4 @@ -# $Id: exec.tcl,v 1.49 2007/07/19 01:17:05 marko Exp $ +# $Id: exec.tcl,v 1.50 2007/07/19 02:33:14 marko Exp $ # Copyright 2004, 2005 University of Zagreb, Croatia. All rights reserved. # @@ -778,8 +778,8 @@ proc execSetLinkParams { eid link } { nexec ngctl msg $lname: setcfg \ "{ bandwidth=$bandwidth delay=$delay \ - upstream={ BER=$ber duplicate=$dup } \ - downstream={ BER=$ber duplicate=$dup } }" + upstream={ BER=$ber duplicate=$dup } \ + downstream={ BER=$ber duplicate=$dup } }" } #****f* exec.tcl/cleanupCfg diff --git a/filemgmt.tcl b/filemgmt.tcl index 06ea728..87c4538 100755 --- a/filemgmt.tcl +++ b/filemgmt.tcl @@ -1,4 +1,4 @@ -# $Id: filemgmt.tcl,v 1.9 2007/07/19 01:17:05 marko Exp $ +# $Id: filemgmt.tcl,v 1.10 2007/07/19 02:33:14 marko Exp $ # # Copyright 2004, 2005 University of Zagreb, Croatia. All rights reserved. # @@ -81,10 +81,12 @@ set currentFile "" -set fileTypes {{"IMUNES network configuration" {.imn} } - { "All files" {*}}} +set fileTypes { + { "IMUNES network configuration" {.imn} } + { "All files" {*} } +} + - #****f* filemgmt.tcl/newFile # NAME # newFile -- new file diff --git a/gpgui.tcl b/gpgui.tcl index a665ef4..ff3e86a 100644 --- a/gpgui.tcl +++ b/gpgui.tcl @@ -118,55 +118,52 @@ proc dialog { } { # * wi -- parent window id #**** proc displayAllNodeWeights {wi} { - #package require BWidget - global node_list; - - set nw .pop - toplevel $nw - wm transient $nw . - wm resizable $nw 0 0 - wm title $nw "Node weights" - #weights settings - labelframe $nw.more -pady 4 -padx 4 -text "Node Weights" - frame $nw.more.weights + #package require BWidget + global node_list; + + set nw .pop + toplevel $nw + wm transient $nw . + wm resizable $nw 0 0 + wm title $nw "Node weights" + #weights settings + labelframe $nw.more -pady 4 -padx 4 -text "Node Weights" + frame $nw.more.weights - set i 1; - set j 1; - #weights from the file - foreach node $node_list { - #read for each node its weight - set wgt [getNodeWeight $node]; + set i 1; + set j 1; + #weights from the file + foreach node $node_list { + #read for each node its weight + set wgt [getNodeWeight $node]; - label $nw.more.weights.$node -text "$node" -anchor w - spinbox $nw.more.weights.w$node -bg white -width 3 \ - -validate focus -invcmd "focusAndFlash %W" - $nw.more.weights.w$node insert 0 $wgt; - $nw.more.weights.w$node configure \ - -vcmd {checkIntRange %P 0 100} \ - -from 0 -to 100 -increment 1 + label $nw.more.weights.$node -text "$node" -anchor w + spinbox $nw.more.weights.w$node -bg white -width 3 \ + -validate focus -invcmd "focusAndFlash %W" + $nw.more.weights.w$node insert 0 $wgt; + $nw.more.weights.w$node configure \ + -vcmd {checkIntRange %P 0 100} \ + -from 0 -to 100 -increment 1 - grid $nw.more.weights.$node -row $i -column $j - grid $nw.more.weights.w$node -row $i -column [expr {int($j+1)}]; + grid $nw.more.weights.$node -row $i -column $j + grid $nw.more.weights.w$node -row $i -column [expr {int($j+1)}]; - incr i; - if {[expr {$i % 10}] == 0} then { - set j [expr {$j + 2}]; - set i 1; + incr i; + if {[expr {$i % 10}] == 0} then { + set j [expr {$j + 2}]; + set i 1; + } } - } - pack $nw.more.weights -side top -anchor w - pack $nw.more -side top -anchor w -fill x + pack $nw.more.weights -side top -anchor w + pack $nw.more -side top -anchor w -fill x - #buttons Apply & Cancel - frame $nw.button -borderwidth 6 - button $nw.button.apply -text "Apply" -command \ - "applyNodeWeights $nw" - focus $nw.button.apply - button $nw.button.cancel -text "Cancel" -command \ - "destroy $nw" - pack $nw.button.cancel $nw.button.apply -side right - pack $nw.button -side bottom - + #buttons Apply & Cancel + frame $nw.button -borderwidth 6 + button $nw.button.apply -text "Apply" -command "applyNodeWeights $nw" + focus $nw.button.apply + button $nw.button.cancel -text "Cancel" -command "destroy $nw" + pack $nw.button.cancel $nw.button.apply -side right + pack $nw.button -side bottom } @@ -182,71 +179,70 @@ proc displayAllNodeWeights {wi} { # * wi -- parent window id #**** proc displayAllLinkWeights {wi} { - # package require BWidget - global link_list; - - set lw .pop - toplevel $lw - wm transient $lw . - wm resizable $lw 0 0 - wm title $lw "Link weights" - #weights settings - labelframe $lw.more -pady 4 -padx 4 -text "Link Weights" - frame $lw.more.weights + # package require BWidget + global link_list; + + set lw .pop + toplevel $lw + wm transient $lw . + wm resizable $lw 0 0 + wm title $lw "Link weights" + #weights settings + labelframe $lw.more -pady 4 -padx 4 -text "Link Weights" + frame $lw.more.weights - set i 1; - set j 1; - foreach link $link_list { - - label $lw.more.weights.$link -text "$link" -anchor w - #bandwidth - label $lw.more.weights.bl$link -text "Bandwidth:" -anchor w - spinbox $lw.more.weights.b$link -bg white -width 9 \ - -validate focus -invcmd "focusAndFlash %W" - $lw.more.weights.b$link insert 0 [getLinkBandwidth $link] - $lw.more.weights.b$link configure \ - -vcmd {checkIntRange %P 0 100000000} \ - -from 0 -to 100000000 -increment 1000 - #delay - label $lw.more.weights.dl$link -text "Delay:" -anchor w - spinbox $lw.more.weights.d$link -bg white -width 9 \ - -validate focus -invcmd "focusAndFlash %W" - $lw.more.weights.d$link insert 0 [getLinkDelay $link] - $lw.more.weights.d$link configure \ - -vcmd {checkIntRange %P 0 100000000} \ - -from 0 -to 100000000 -increment 5 - #BER - label $lw.more.weights.rl$link -text "BER (1/N):" -anchor w - spinbox $lw.more.weights.r$link -bg white -width 9 \ - -validate focus -invcmd "focusAndFlash %W" - $lw.more.weights.r$link insert 0 [getLinkBER $link] - $lw.more.weights.r$link configure \ - -vcmd {checkIntRange %P 0 10000000000000} \ - -from 0 -to 10000000000000 -increment 1000 + set i 1; + set j 1; + foreach link $link_list { + + label $lw.more.weights.$link -text "$link" -anchor w + #bandwidth + label $lw.more.weights.bl$link -text "Bandwidth:" -anchor w + spinbox $lw.more.weights.b$link -bg white -width 9 \ + -validate focus -invcmd "focusAndFlash %W" + $lw.more.weights.b$link insert 0 [getLinkBandwidth $link] + $lw.more.weights.b$link configure \ + -vcmd {checkIntRange %P 0 100000000} \ + -from 0 -to 100000000 -increment 1000 + #delay + label $lw.more.weights.dl$link -text "Delay:" -anchor w + spinbox $lw.more.weights.d$link -bg white -width 9 \ + -validate focus -invcmd "focusAndFlash %W" + $lw.more.weights.d$link insert 0 [getLinkDelay $link] + $lw.more.weights.d$link configure \ + -vcmd {checkIntRange %P 0 100000000} \ + -from 0 -to 100000000 -increment 5 + #BER + label $lw.more.weights.rl$link -text "BER (1/N):" -anchor w + spinbox $lw.more.weights.r$link -bg white -width 9 \ + -validate focus -invcmd "focusAndFlash %W" + $lw.more.weights.r$link insert 0 [getLinkBER $link] + $lw.more.weights.r$link configure \ + -vcmd {checkIntRange %P 0 10000000000000} \ + -from 0 -to 10000000000000 -increment 1000 - grid $lw.more.weights.$link -row $i -column 1; - grid $lw.more.weights.bl$link -row $i -column 2; - grid $lw.more.weights.b$link -row $i -column 3; - grid $lw.more.weights.dl$link -row $i -column 4; - grid $lw.more.weights.d$link -row $i -column 5; - grid $lw.more.weights.rl$link -row $i -column 6; - grid $lw.more.weights.r$link -row $i -column 7; + grid $lw.more.weights.$link -row $i -column 1; + grid $lw.more.weights.bl$link -row $i -column 2; + grid $lw.more.weights.b$link -row $i -column 3; + grid $lw.more.weights.dl$link -row $i -column 4; + grid $lw.more.weights.d$link -row $i -column 5; + grid $lw.more.weights.rl$link -row $i -column 6; + grid $lw.more.weights.r$link -row $i -column 7; - incr i; - } - pack $lw.more.weights -side top -anchor w - pack $lw.more -side top -anchor w -fill x + incr i; + } + pack $lw.more.weights -side top -anchor w + pack $lw.more -side top -anchor w -fill x - #buttons Apply & Cancel - frame $lw.button -borderwidth 6 - button $lw.button.apply -text "Apply" -command \ - "applyLinkWeights $lw" - focus $lw.button.apply - button $lw.button.cancel -text "Cancel" -command \ - "destroy $lw" - pack $lw.button.cancel $lw.button.apply -side right - pack $lw.button -side bottom - + #buttons Apply & Cancel + frame $lw.button -borderwidth 6 + button $lw.button.apply -text "Apply" -command \ + "applyLinkWeights $lw" + focus $lw.button.apply + button $lw.button.cancel -text "Cancel" -command \ + "destroy $lw" + pack $lw.button.cancel $lw.button.apply -side right + pack $lw.button -side bottom } #****f* gpgui.tcl/readNodeWeights @@ -259,24 +255,24 @@ proc displayAllLinkWeights {wi} { # in array. #**** proc readNodeWeights {} { - global node_weights; + global node_weights; - #get the weight settings out of the file - set file [openWeightFile "r"]; + #get the weight settings out of the file + set file [openWeightFile "r"]; - set n [gets $file line]; - - set i 0; - while {[gets $file line] >= 0} { - set node_weights($i) $line; - incr i; - } - close $file; + set n [gets $file line]; + + set i 0; + while {[gets $file line] >= 0} { + set node_weights($i) $line; + incr i; + } + close $file; - if {$i != 6} then { - puts stdout "Bad file $file."; - return; - } + if {$i != 6} then { + puts stdout "Bad file $file."; + return; + } } #****f* gpgui.tcl/openWeightFile @@ -292,13 +288,13 @@ proc readNodeWeights {} { # RESULT # * fileId -- file id #**** -proc openWeightFile { op } { - global WEIGHT_FILE; - if {[catch {open $WEIGHT_FILE $op} fileId]} then { - puts stdout "graph_partitioning: Cannot open $WEIGHT_FILE."; - return; - } - return $fileId; +proc openWeightFile { op } { + global WEIGHT_FILE; + if {[catch {open $WEIGHT_FILE $op} fileId]} then { + puts stdout "graph_partitioning: Cannot open $WEIGHT_FILE."; + return; + } + return $fileId; } #****f* gpgui.tcl/applyNodeWeights @@ -313,12 +309,12 @@ proc openWeightFile { op } { # * nw -- window id #**** proc applyNodeWeights {nw} { - global node_list; + global node_list; - foreach node $node_list { - writeWeightToNode $node [$nw.more.weights.w$node get]; - } - destroy $nw; + foreach node $node_list { + writeWeightToNode $node [$nw.more.weights.w$node get]; + } + destroy $nw; } #****f* gpgui.tcl/applyLinkWeights @@ -333,14 +329,14 @@ proc applyNodeWeights {nw} { # * lw -- window id #**** proc applyLinkWeights {lw} { - global link_list; - - foreach link $link_list { - setLinkBandwidth $link [$lw.more.weights.b$link get]; - setLinkDelay $link [$lw.more.weights.d$link get]; - setLinkBER $link [$lw.more.weights.r$link get]; - } - destroy $lw; + global link_list; + + foreach link $link_list { + setLinkBandwidth $link [$lw.more.weights.b$link get]; + setLinkDelay $link [$lw.more.weights.d$link get]; + setLinkBER $link [$lw.more.weights.r$link get]; + } + destroy $lw; } #****f* gpgui.tcl/writeWeightToNode @@ -355,14 +351,14 @@ proc applyLinkWeights {lw} { # * weight -- weight of the node #**** proc writeWeightToNode {node weight} { - global $node; - - set p [lsearch [set $node] "weight *"]; - if { $p >= 0 } { - set $node [lreplace [set $node] $p $p "weight $weight"]; - } else { - set $node [linsert [set $node] end "weight $weight"]; - } + global $node; + + set p [lsearch [set $node] "weight *"]; + if { $p >= 0 } { + set $node [lreplace [set $node] $p $p "weight $weight"]; + } else { + set $node [linsert [set $node] end "weight $weight"]; + } } @@ -382,37 +378,37 @@ proc writeWeightToNode {node weight} { # * wgt -- weight of the node #**** proc getNodeWeight {node} { - global $node; - global node_weights; - - set wgt [lindex [lsearch -inline [set $node] "weight *"] 1]; + global $node; + global node_weights; - if {$wgt == ""} then { - switch -exact -- [nodeType $node] { - pc { - set wgt $node_weights(0); - } - host { - set wgt $node_weights(1); - } - router { - set wgt $node_weights(2); - } - lanswitch { - set wgt $node_weights(3); - } - hub { - set wgt $node_weights(4); - } - rj45 { - set wgt $node_weights(5); - } - default { - set wgt 0; - } - } + set wgt [lindex [lsearch -inline [set $node] "weight *"] 1]; + + if {$wgt == ""} then { + switch -exact -- [nodeType $node] { + pc { + set wgt $node_weights(0); + } + host { + set wgt $node_weights(1); + } + router { + set wgt $node_weights(2); + } + lanswitch { + set wgt $node_weights(3); + } + hub { + set wgt $node_weights(4); + } + rj45 { + set wgt $node_weights(5); + } + default { + set wgt 0; + } + } } - return $wgt; + return $wgt; } #****f* gpgui.tcl/changeDefaultWeights @@ -459,10 +455,10 @@ proc popupApply { wi } { set partNum [$wi.pnum.e.p get] foreach node $node_list { - #read for each node its weight - set wgt [getNodeWeight $node]; - #write it to the node_list - writeWeightToNode $node $wgt + #read for each node its weight + set wgt [getNodeWeight $node]; + #write it to the node_list + writeWeightToNode $node $wgt } destroy $wi @@ -481,7 +477,7 @@ proc popupApply { wi } { # * message -- message to be writen #**** proc displayErrorMessage { message } { - tk_dialog .dialog1 "Graph partitioning" $message info 0 Dismiss; + tk_dialog .dialog1 "Graph partitioning" $message info 0 Dismiss; } #****f* gpgui.tcl/getLinkWeight @@ -497,25 +493,25 @@ proc displayErrorMessage { message } { # * weight -- weight of the link #**** proc getLinkWeight {link} { - set bndw [getLinkBandwidth $link]; - set dly [getLinkDelay $link]; - set ber [getLinkBER $link]; - set dup [getLinkDup $link]; - set weight [expr {$bndw}]; + set bndw [getLinkBandwidth $link]; + set dly [getLinkDelay $link]; + set ber [getLinkBER $link]; + set dup [getLinkDup $link]; + set weight [expr {$bndw}]; - return $weight; + return $weight; } proc test_partitioning {partNum} { - # foreach n {2 4 8 16 32 64 128 256 512} { - # if {$n > $partNum} then { - # break; - # } - # for {set i 0} {$i < 3} {incr i} { - # puts "i=$i, n=$n"; - graphPartition $partNum; - # } - #} +# foreach n {2 4 8 16 32 64 128 256 512} { +# if {$n > $partNum} then { +# break; +# } +# for {set i 0} {$i < 3} {incr i} { +# puts "i=$i, n=$n"; + graphPartition $partNum; +# } +# } } diff --git a/graph_partitioning.tcl b/graph_partitioning.tcl index 570ba6b..af56106 100644 --- a/graph_partitioning.tcl +++ b/graph_partitioning.tcl @@ -41,52 +41,52 @@ # * node_weight -- array of node weights #**** proc writePartitions {node_weight} { - global nparts; - global node_list; - global link_list; - global split_list; - global finalpartition; + global nparts; + global node_list; + global link_list; + global split_list; + global finalpartition; - upvar $node_weight nweight; + upvar $node_weight nweight; - #counts how many nodes are in each partition - array set nr_nodes_partition {}; - #sum up the weight of each partition - array set weight_partition {}; + #counts how many nodes are in each partition + array set nr_nodes_partition {}; + #sum up the weight of each partition + array set weight_partition {}; - for {set i 0} {$i<$nparts} {incr i} { - set nr_nodes_partition($i) 0; - set weight_partition($i) 0; - } - - set i 0; - foreach node $node_list { - #write to node its partition - setPartition $node $finalpartition($i); - incr nr_nodes_partition($finalpartition($i)) 1; - incr weight_partition($finalpartition($i)) $nweight($i); - incr i; - } - - #disconnect for algorithm connected nodes - foreach split $split_list { - set node1 [lindex $split 0]; - set node2 [lindex $split 1]; - set linkToSplit [linkByPeers $node1 $node2]; - splitGUILink $linkToSplit ; - } - - set outstr ""; - for {set i 0} {$i < $nparts} {incr i} { - set outstr "p$i: $nr_nodes_partition($i) vertices with weight $weight_partition($i)"; - #puts [format %s $outstr]; - } + for {set i 0} {$i<$nparts} {incr i} { + set nr_nodes_partition($i) 0; + set weight_partition($i) 0; + } + + set i 0; + foreach node $node_list { + #write to node its partition + setPartition $node $finalpartition($i); + incr nr_nodes_partition($finalpartition($i)) 1; + incr weight_partition($finalpartition($i)) $nweight($i); + incr i; + } + + #disconnect for algorithm connected nodes + foreach split $split_list { + set node1 [lindex $split 0]; + set node2 [lindex $split 1]; + set linkToSplit [linkByPeers $node1 $node2]; + splitGUILink $linkToSplit ; + } + + set outstr ""; + for {set i 0} {$i < $nparts} {incr i} { + set outstr "p$i: $nr_nodes_partition($i) vertices with weight $weight_partition($i)"; + #puts [format %s $outstr]; + } - redrawAll; - updateUndoLog; - tk_dialog .dialog1 "Graph partitioning output" "Done.\n" info 0 Dismiss; + redrawAll; + updateUndoLog; + tk_dialog .dialog1 "Graph partitioning output" "Done.\n" info 0 Dismiss; } - + #****f* graph_partitioning.tcl/setPartition # NAME # setPartition -- set partition @@ -101,14 +101,14 @@ proc writePartitions {node_weight} { # * partition -- partition of the node #**** proc setPartition { node partition } { - global $node; - - set p [lsearch [set $node] "partition *"]; - if { $p >= 0 } { - set $node [lreplace [set $node] $p $p "partition p$partition"]; - } else { - set $node [linsert [set $node] end "partition p$partition"]; - } + global $node; + + set p [lsearch [set $node] "partition *"]; + if { $p >= 0 } { + set $node [lreplace [set $node] $p $p "partition p$partition"]; + } else { + set $node [linsert [set $node] end "partition p$partition"]; + } } #****f* graph_partitioning.tcl/getNodePartition @@ -125,9 +125,9 @@ proc setPartition { node partition } { # * part -- the node's partition #**** proc getNodePartition { node } { - global $node; - set part [lindex [lsearch -inline [set $node] "partition *"] 1]; - return $part; + global $node; + set part [lindex [lsearch -inline [set $node] "partition *"] 1]; + return $part; } #****f* graph_partitioning.tcl/debug @@ -141,12 +141,12 @@ proc getNodePartition { node } { # * message -- a messege to be printed #**** proc debug { message } { - global debug; - if ![info exists debug(enabled)] { - #do nothing - return; - } - puts stderr $message; + global debug; + if ![info exists debug(enabled)] { + #do nothing + return; + } + puts stderr $message; } #****f* graph_partitioning.tcl/graphPartition @@ -161,57 +161,50 @@ proc debug { message } { # * partNum -- number of partitions #**** proc graphPartition {partNum} { - global node_list; - global link_list; - global finalpartition; - - global nparts; - global tpwgts; - global max_nweight; - - array set node_weight {}; - array set edge_weight {}; - array set node_neighbour {}; - array set edge_array {}; - array set tpwgts {}; - array set node_map {}; - - puts ""; - #puts " Starting graph partitioning..."; - #puts "+------------------------------------------------+"; - #puts ""; - - set start [clock clicks -milliseconds]; - - #initialise the arrays for the algorithm - set nparts $partNum; - initNodes node_weight; - set nvertices [array size node_weight]; - initNeighbours node_neighbour edge_array edge_weight; + global node_list link_list finalpartition + + global nparts tpwgts max_nweight + + array set node_weight {}; + array set edge_weight {}; + array set node_neighbour {}; + array set edge_array {}; + array set tpwgts {}; + array set node_map {}; + + puts ""; + #puts " Starting graph partitioning..."; + #puts "+------------------------------------------------+"; + #puts ""; - if {$nparts > $nvertices} then { - debug "Number of vertices should be greater then number of partitions."; - displayErrorMessage "Number of vertices should be greater then number of partitions."; - return; - } elseif {$nparts < 2} { - debug "Number of partition should be greater then 1."; - displayErrorMessage "Number of partition should be greater then 1."; - return; - } - - #calculate tpwgts array - for {set i 0} {$i < $nparts} {incr i} { - set tpwgts($i) [expr {1.0 / (1.0 * $nparts)}]; - } + set start [clock clicks -milliseconds]; + + #initialise the arrays for the algorithm + set nparts $partNum; + initNodes node_weight; + set nvertices [array size node_weight]; + initNeighbours node_neighbour edge_array edge_weight; - set t [time { - recursiveBisection $nvertices node_weight node_neighbour edge_array edge_weight tpwgts $nparts 0 node_map; - } 1]; - set microsec [lindex $t 0]; - puts "total time: [expr {$microsec * 0.000001}] sec"; + if {$nparts > $nvertices} then { + debug "Number of vertices should be greater then number of partitions."; + displayErrorMessage "Number of vertices should be greater then number of partitions."; + return; + } elseif {$nparts < 2} { + debug "Number of partition should be greater then 1."; + displayErrorMessage "Number of partition should be greater then 1."; + return; + } + + #calculate tpwgts array + for {set i 0} {$i < $nparts} {incr i} { + set tpwgts($i) [expr {1.0 / (1.0 * $nparts)}]; + } + set t [time { recursiveBisection $nvertices node_weight node_neighbour edge_array edge_weight tpwgts $nparts 0 node_map; } 1]; + set microsec [lindex $t 0]; + puts "total time: [expr {$microsec * 0.000001}] sec"; - #compute cut + #compute cut set cut 0; for {set i 0} {$i < $nvertices} {incr i} { set id($i) 0; @@ -221,34 +214,37 @@ proc graphPartition {partNum} { # calculates the sum of the edge weights of the adjacent vertices of i if {[info exists node_neighbour($i)]} then { - foreach ngb $node_neighbour($i) { + foreach ngb $node_neighbour($i) { if {$curr_partition == $finalpartition($ngb)} then { - # vertice in the same partition - incr id($i) 1;#$edge_weight([getEdgeBetween $i $ngb edge_array]); + # vertice in the same partition + incr id($i) 1; + #$edge_weight([getEdgeBetween $i $ngb edge_array]); } else { - # vertice in a different partition - incr ed($i) 1;#$edge_weight([getEdgeBetween $i $ngb edge_array]); + # vertice in a different partition + incr ed($i) 1; + #$edge_weight([getEdgeBetween $i $ngb edge_array]); };#if-else - };#foreach + };#foreach - if {$ed($i) > 0 || [llength $node_neighbour($i)] == 0} then { ;#vanjski node, ili nema susjeda - incr cut $ed($i); - } + if {$ed($i) > 0 || [llength $node_neighbour($i)] == 0} then { + #vanjski node, ili nema susjeda + incr cut $ed($i); + } + } } - } - set cut [expr {$cut / 2}]; - puts "end cut: $cut"; + set cut [expr {$cut / 2}]; + puts "end cut: $cut"; - #save the partitions - writePartitions node_weight; + #save the partitions + writePartitions node_weight; - set end [clock clicks -milliseconds]; - puts [format "total elapsed time: %.6f s" [expr {($end - $start) * 0.001}]]; + set end [clock clicks -milliseconds]; + puts [format "total elapsed time: %.6f s" [expr {($end - $start) * 0.001}]]; - puts ""; - puts " Done graph partitioning."; - puts "+------------------------------------------------+"; - puts ""; + puts ""; + puts " Done graph partitioning."; + puts "+------------------------------------------------+"; + puts ""; } #****f* graph_partitioning.tcl/initNodes @@ -262,20 +258,20 @@ proc graphPartition {partNum} { # * node_weight -- empty array of node weights #**** proc initNodes {node_weight} { - global node_list; - upvar $node_weight nweight; + global node_list; + upvar $node_weight nweight; - set i 0; - foreach node $node_list { - #if the node is pseudo, remove it - if {[nodeType $node] == "pseudo"} then { - mergePseudoLink $node - } else { - #seve node's weight into array - set nweight($i) [getNodeWeight $node]; - incr i; - } - } + set i 0; + foreach node $node_list { + #if the node is pseudo, remove it + if {[nodeType $node] == "pseudo"} then { + mergePseudoLink $node + } else { + #seve node's weight into array + set nweight($i) [getNodeWeight $node]; + incr i; + } + } } #****f* graph_partitioning.tcl/mergePseudoLink @@ -289,28 +285,28 @@ proc initNodes {node_weight} { # * pnode -- pseudo node id #**** proc mergePseudoLink { pnode } { - global node_list; - global split_list; + global node_list; + global split_list; - foreach n $node_list { - #get the links connecting the both pseudo node's - set l1 [linkByPeers $pnode $n]; - if {$l1 != ""} then { - set l2 [getLinkMirror $l1]; - #set peers1 [linkPeers $l1]; - set peers2 [linkPeers $l2]; - - #get it's not-pseudo peers - #set n1 [lindex $peers1 0]; - set n2 [lindex $peers2 0]; - - mergeLink $l1; - if {[lsearch $split_list "$n $n2"] < 0 && [lsearch $split_list "$n2 $n"] < 0} then { - lappend split_list "$n $n2"; - break; - } + foreach n $node_list { + #get the links connecting the both pseudo node's + set l1 [linkByPeers $pnode $n]; + if {$l1 != ""} then { + set l2 [getLinkMirror $l1]; + #set peers1 [linkPeers $l1]; + set peers2 [linkPeers $l2]; + + #get it's not-pseudo peers + #set n1 [lindex $peers1 0]; + set n2 [lindex $peers2 0]; + + mergeLink $l1; + if {[lsearch $split_list "$n $n2"] < 0 && [lsearch $split_list "$n2 $n"] < 0} then { + lappend split_list "$n $n2"; + break; + } + } } - } } #****f* graph_partitioning.tcl/initNeighbours @@ -326,30 +322,29 @@ proc mergePseudoLink { pnode } { # * edge_weight -- empty array #**** proc initNeighbours {node_neighbour edge_array edge_weight} { - global node_list; - global link_list; - - upvar $edge_array earray; - upvar $node_neighbour nneighbour; - upvar $edge_weight eweight; - - for {set i 0} {$i < [llength $link_list]} {incr i} { - #take the edge one after the other - set edge [lindex $link_list $i]; - #read nodes incident to edge - set peers [linkPeers $edge]; - set node1 [lindex $peers 0]; - set node2 [lindex $peers 1]; - #read node's index in the node_list - set idx_n1 [lsearch $node_list $node1]; - set idx_n2 [lsearch $node_list $node2]; - #node1 is adjacent to node2 - lappend nneighbour($idx_n1) $idx_n2; - lappend nneighbour($idx_n2) $idx_n1; - set earray($i) "$idx_n1 $idx_n2"; - #calculate the link weight - set eweight($i) [expr {[getLinkWeight $edge] / 100000}]; #!!!!!!s - } + global node_list link_list + + upvar $edge_array earray; + upvar $node_neighbour nneighbour; + upvar $edge_weight eweight; + + for {set i 0} {$i < [llength $link_list]} {incr i} { + #take the edge one after the other + set edge [lindex $link_list $i]; + #read nodes incident to edge + set peers [linkPeers $edge]; + set node1 [lindex $peers 0]; + set node2 [lindex $peers 1]; + #read node's index in the node_list + set idx_n1 [lsearch $node_list $node1]; + set idx_n2 [lsearch $node_list $node2]; + #node1 is adjacent to node2 + lappend nneighbour($idx_n1) $idx_n2; + lappend nneighbour($idx_n2) $idx_n1; + set earray($i) "$idx_n1 $idx_n2"; + #calculate the link weight + set eweight($i) [expr {[getLinkWeight $edge] / 100000}]; #!!!!!!s + } } #****f* graph_partitioning.tcl/recursiveBisection @@ -374,50 +369,50 @@ proc initNeighbours {node_neighbour edge_array edge_weight} { # * up_map -- #**** proc recursiveBisection {nvertices node_weight node_neighbour edge_array edge_weight tpart_wgts new_parts part_nr up_map} { - global part_mincut; - global finalpartition; - global part_partition; - - upvar $node_weight nweight; - upvar $node_neighbour nneighbour; - upvar $edge_array earray; - upvar $edge_weight eweight; - upvar $tpart_wgts tpwgts; - upvar $up_map upmap; - - array set tpwgts2 {}; - - set nparts $new_parts; - set cut 0; - debug "recursiveBisection!!!!"; - debug "RB: nparts=$nparts"; - - #calculate for each partition its wished weight - set tvwgt [sum_array $nvertices nweight]; - set sum_tpwgt [sum_array [expr {$nparts / 2}] tpwgts]; - set tpwgts2(0) [expr {int ( ceil($tvwgt * $sum_tpwgt))}]; - set tp2 [expr {ceil($sum_tpwgt * $tvwgt)}]; - set tpwgts2(1) [expr {int($tvwgt - $tpwgts2(0))}]; - debug "RB: tvwgt=$tvwgt, tpwgts2(0)=$tpwgts2(0), tpwgts2(1)=$tpwgts2(1), sum_tpwgt=$sum_tpwgt"; - - #start partitioning - coarseGraph $nvertices nweight nneighbour earray eweight tpwgts2; - #minimal cut - set cut $part_mincut; + global part_mincut; + global finalpartition; + global part_partition; + + upvar $node_weight nweight; + upvar $node_neighbour nneighbour; + upvar $edge_array earray; + upvar $edge_weight eweight; + upvar $tpart_wgts tpwgts; + upvar $up_map upmap; + + array set tpwgts2 {}; + + set nparts $new_parts; + set cut 0; + debug "recursiveBisection!!!!"; + debug "RB: nparts=$nparts"; + + #calculate for each partition its wished weight + set tvwgt [sum_array $nvertices nweight]; + set sum_tpwgt [sum_array [expr {$nparts / 2}] tpwgts]; + set tpwgts2(0) [expr {int ( ceil($tvwgt * $sum_tpwgt))}]; + set tp2 [expr {ceil($sum_tpwgt * $tvwgt)}]; + set tpwgts2(1) [expr {int($tvwgt - $tpwgts2(0))}]; + debug "RB: tvwgt=$tvwgt, tpwgts2(0)=$tpwgts2(0), tpwgts2(1)=$tpwgts2(1), sum_tpwgt=$sum_tpwgt"; + + #start partitioning + coarseGraph $nvertices nweight nneighbour earray eweight tpwgts2; + #minimal cut + set cut $part_mincut; - #calculate for each vertex its right partition by adding to "0" and "1" partition a number - for {set i 0} {$i < $nvertices} {incr i} { - if {[array size upmap] > 0} { - set finalpartition($upmap($i)) [expr {$part_partition($i) + $part_nr}]; - } else { - set finalpartition($i) [expr {$part_partition($i) + $part_nr}]; + #calculate for each vertex its right partition by adding to "0" and "1" partition a number + for {set i 0} {$i < $nvertices} {incr i} { + if {[array size upmap] > 0} { + set finalpartition($upmap($i)) [expr {$part_partition($i) + $part_nr}]; + } else { + set finalpartition($i) [expr {$part_partition($i) + $part_nr}]; + } } - } - #when partition in more then 2 parts, divide the graph in 2 halfs (subgraph "0" and subgraph "1") - if {$nparts > 2} then { - array set snode_neighbour {}; - array set snode_weight {}; + #when partition in more then 2 parts, divide the graph in 2 halfs (subgraph "0" and subgraph "1") + if {$nparts > 2} then { + array set snode_neighbour {}; + array set snode_weight {}; array set sedge_array {}; array set sedge_weight {}; array set snode_map {}; @@ -439,7 +434,7 @@ proc recursiveBisection {nvertices node_weight node_neighbour edge_array edge_we array set sedge_weight0 {}; array set snode_map0 {}; - array set snode_neighbour1 {}; + array set snode_neighbour1 {}; array set snode_weight1 {}; array set sedge_array1 {}; array set sedge_weight1 {}; @@ -448,64 +443,64 @@ proc recursiveBisection {nvertices node_weight node_neighbour edge_array edge_we #save the node characteristics from both subgraphs in two different arrays for {set i 0} {$i < $sn_vtxs(0)} {incr i} { - if {[info exists snode_neighbour(0,$i)]} then { - set snode_neighbour0($i) $snode_neighbour(0,$i); - } - if {[array size upmap] > 0} then { - set snode_map0($i) $upmap($snode_map_help(0,$i)); - } else { - set snode_map0($i) $snode_map_help(0,$i); - } - debug "snode_map0($i)=$snode_map0($i)"; - set snode_weight0($i) $snode_weight(0,$i); + if {[info exists snode_neighbour(0,$i)]} then { + set snode_neighbour0($i) $snode_neighbour(0,$i); + } + if {[array size upmap] > 0} then { + set snode_map0($i) $upmap($snode_map_help(0,$i)); + } else { + set snode_map0($i) $snode_map_help(0,$i); + } + debug "snode_map0($i)=$snode_map0($i)"; + set snode_weight0($i) $snode_weight(0,$i); } - for {set i 0} {$i < $sn_vtxs(1)} {incr i} { - if {[info exists snode_neighbour(1,$i)]} then { - set snode_neighbour1($i) $snode_neighbour(1,$i); - } - if {[array size upmap] > 0} then { - set snode_map1($i) $upmap($snode_map_help(1,$i)); - } else { - set snode_map1($i) $snode_map_help(1,$i); - } - debug "snode_map1($i)=$snode_map1($i)"; - set snode_weight1($i) $snode_weight(1,$i); + for {set i 0} {$i < $sn_vtxs(1)} {incr i} { + if {[info exists snode_neighbour(1,$i)]} then { + set snode_neighbour1($i) $snode_neighbour(1,$i); + } + if {[array size upmap] > 0} then { + set snode_map1($i) $upmap($snode_map_help(1,$i)); + } else { + set snode_map1($i) $snode_map_help(1,$i); + } + debug "snode_map1($i)=$snode_map1($i)"; + set snode_weight1($i) $snode_weight(1,$i); } #save the link characteristics from both subgraphs in two different arrays for {set i 0} {$i < $sn_edges(0)} {incr i} { - set sedge_array0($i) $sedge_array(0,$i); - set sedge_weight0($i) $sedge_weight(0,$i); + set sedge_array0($i) $sedge_array(0,$i); + set sedge_weight0($i) $sedge_weight(0,$i); } for {set i 0} {$i < $sn_edges(1)} {incr i} { - set sedge_array1($i) $sedge_array(1,$i); - set sedge_weight1($i) $sedge_weight(1,$i); + set sedge_array1($i) $sedge_array(1,$i); + set sedge_weight1($i) $sedge_weight(1,$i); } - } + } - #update the tpwgts (partition's ratio of the graph) - mult_array 0 [expr {int($nparts / 2)}] tpwgts [expr {1 / $sum_tpwgt}]; - mult_array [expr {int($nparts / 2)}] $nparts tpwgts [expr {1.0 / (1.0 - $sum_tpwgt)}]; - set max [expr {int($nparts - $nparts / 2)}]; + #update the tpwgts (partition's ratio of the graph) + mult_array 0 [expr {int($nparts / 2)}] tpwgts [expr {1 / $sum_tpwgt}]; + mult_array [expr {int($nparts / 2)}] $nparts tpwgts [expr {1.0 / (1.0 - $sum_tpwgt)}]; + set max [expr {int($nparts - $nparts / 2)}]; - for {set i 0} {$i < $max} {incr i} { - set new_tpwgts($i) $tpwgts([expr {$i + int($nparts / 2)}]); + for {set i 0} {$i < $max} {incr i} { + set new_tpwgts($i) $tpwgts([expr {$i + int($nparts / 2)}]); debug " new_tpwgts($i)=$new_tpwgts($i)"; - } - - #call recursive itself - if {$nparts > 3} then { - #partition the first subgraph - recursiveBisection $sn_vtxs(0) snode_weight0 snode_neighbour0 sedge_array0 sedge_weight0 tpwgts [expr {int($nparts / 2)}] $part_nr snode_map0; - #partition the second subgraph - recursiveBisection $sn_vtxs(1) snode_weight1 snode_neighbour1 sedge_array1 sedge_weight1 new_tpwgts [expr {int($nparts - $nparts / 2)}] [expr {int($part_nr + $nparts / 2)} ] snode_map1; - } elseif {$nparts == 3} then { - #partition the second subgraph - recursiveBisection $sn_vtxs(1) snode_weight1 snode_neighbour1 sedge_array1 sedge_weight1 new_tpwgts [expr {int($nparts - $nparts / 2)}] [expr {int($part_nr + $nparts / 2)}] snode_map1; - } + } + + #call recursive itself + if {$nparts > 3} then { + #partition the first subgraph + recursiveBisection $sn_vtxs(0) snode_weight0 snode_neighbour0 sedge_array0 sedge_weight0 tpwgts [expr {int($nparts / 2)}] $part_nr snode_map0; + #partition the second subgraph + recursiveBisection $sn_vtxs(1) snode_weight1 snode_neighbour1 sedge_array1 sedge_weight1 new_tpwgts [expr {int($nparts - $nparts / 2)}] [expr {int($part_nr + $nparts / 2)} ] snode_map1; + } elseif {$nparts == 3} then { + #partition the second subgraph + recursiveBisection $sn_vtxs(1) snode_weight1 snode_neighbour1 sedge_array1 sedge_weight1 new_tpwgts [expr {int($nparts - $nparts / 2)}] [expr {int($part_nr + $nparts / 2)}] snode_map1; + } } #****f* graph_partitioning.tcl/coarseGraph @@ -526,148 +521,148 @@ proc recursiveBisection {nvertices node_weight node_neighbour edge_array edge_we # * tpwgts2 -- array of each partition size of the graph #**** proc coarseGraph {nvertices node_weight node_neighbour edge_array edge_weight tpwgts2} { - global nparts; - global max_nweight; - global COARSEN_TO; + global nparts; + global max_nweight; + global COARSEN_TO; - upvar $node_weight nweight; - upvar $node_neighbour nneighbour; - upvar $edge_array earray; - upvar $edge_weight eweight; - upvar $tpwgts2 tpwgts; + upvar $node_weight nweight; + upvar $node_neighbour nneighbour; + upvar $edge_array earray; + upvar $edge_weight eweight; + upvar $tpwgts2 tpwgts; - debug "MatchRm... $nvertices"; + debug "MatchRm... $nvertices"; - array set cnweight {}; - array set nmap {}; - array set nmatch {}; + array set cnweight {}; + array set nmap {}; + array set nmatch {}; - set matched ""; - set cnvertices 0; - - #permute the nodes - set permList [makePermList $nvertices ]; - #array with random permuted nodes - array set permArray $permList; - set sum_nweight [sum_array $nvertices nweight]; - set max_nweight [expr {1.5 * $sum_nweight / 20}]; - - #match the vertices - for {set i 0} {[llength $matched] < $nvertices} {incr i} { + set matched ""; + set cnvertices 0; + + #permute the nodes + set permList [makePermList $nvertices ]; + #array with random permuted nodes + array set permArray $permList; + set sum_nweight [sum_array $nvertices nweight]; + set max_nweight [expr {1.5 * $sum_nweight / 20}]; + + #match the vertices + for {set i 0} {[llength $matched] < $nvertices} {incr i} { set unmatched_node $permArray($i); - if {[lsearch $matched $unmatched_node] == -1} then { - lappend matched $unmatched_node; - set matched_ngb 0; - set max_eweight 0; - debug "matched=$matched"; - - #node has an unmatched, passend neighbor, and is matched with it -if {$nvertices > $COARSEN_TO && [info exists nneighbour($unmatched_node)]} then { - foreach ngb $nneighbour($unmatched_node) { - if {[lsearch $matched $ngb] == -1 && [expr {$nweight($i) + $nweight($ngb)}] < $max_nweight && $max_eweight < $eweight([getEdgeBetween $unmatched_node $ngb earray])} then { - set matched_ngb 1; - lappend matched $ngb; - set max_eweight $eweight([getEdgeBetween $unmatched_node $ngb earray]); - set nmatch($unmatched_node) $ngb; - set nmatch($ngb) $unmatched_node; - set nmap($unmatched_node) $cnvertices; #potrebno za uncoarse - set nmap($ngb) $cnvertices; #potrebno za uncoarse - set cnweight($cnvertices) [expr {$nweight($unmatched_node) + $nweight($ngb)}]; - + if {[lsearch $matched $unmatched_node] == -1} then { + lappend matched $unmatched_node; + set matched_ngb 0; + set max_eweight 0; + debug "matched=$matched"; + + #node has an unmatched, passend neighbor, and is matched with it + if {$nvertices > $COARSEN_TO && [info exists nneighbour($unmatched_node)]} then { + foreach ngb $nneighbour($unmatched_node) { + if {[lsearch $matched $ngb] == -1 && [expr {$nweight($i) + $nweight($ngb)}] < $max_nweight && $max_eweight < $eweight([getEdgeBetween $unmatched_node $ngb earray])} then { + set matched_ngb 1; + lappend matched $ngb; + set max_eweight $eweight([getEdgeBetween $unmatched_node $ngb earray]); + set nmatch($unmatched_node) $ngb; + set nmatch($ngb) $unmatched_node; + set nmap($unmatched_node) $cnvertices; #potrebno za uncoarse + set nmap($ngb) $cnvertices; #potrebno za uncoarse + set cnweight($cnvertices) [expr {$nweight($unmatched_node) + $nweight($ngb)}]; + } + } + } + #node is matched with itself + if {$matched_ngb == 0} then { + set nmatch($unmatched_node) $unmatched_node; + set nmap($unmatched_node) $cnvertices; + set cnweight($cnvertices) $nweight($unmatched_node); + } + debug "nmap($unmatched_node)=$nmap($unmatched_node),$unmatched_node,$nmatch($unmatched_node) "; + incr cnvertices; } - } -} - #node is matched with itself - if {$matched_ngb == 0} then { - set nmatch($unmatched_node) $unmatched_node; - set nmap($unmatched_node) $cnvertices; - set cnweight($cnvertices) $nweight($unmatched_node); - } - debug "nmap($unmatched_node)=$nmap($unmatched_node),$unmatched_node,$nmatch($unmatched_node) "; - incr cnvertices; } - } - array set cnneighbour {}; - set used_nodes ""; - set cngb 0; + array set cnneighbour {}; + set used_nodes ""; + set cngb 0; - #coarse graph - for {set i 0} {[llength $used_nodes] < $cnvertices} {incr i} { - set parent1 $i; - set parent2 $nmatch($i); - set cnode $nmap($parent1); - - if {[lsearch $used_nodes $cnode] > -1} { - continue; - } - lappend used_nodes $cnode; - - #save all neighbours from the 2 parent nodes to their coarse node - set temp_ngb_list ""; -if {[info exists nneighbour($parent1)] && [info exists nneighbour($parent2)]} then { - # take all neighbours from "parent"-nodes - set all_neighbours [concat $nneighbour($parent1) $nneighbour($parent2)]; - foreach ngb $all_neighbours { - set ngb_map $nmap($ngb); + #coarse graph + for {set i 0} {[llength $used_nodes] < $cnvertices} {incr i} { + set parent1 $i; + set parent2 $nmatch($i); + set cnode $nmap($parent1); + + if {[lsearch $used_nodes $cnode] > -1} { + continue; + } + lappend used_nodes $cnode; + + #save all neighbours from the 2 parent nodes to their coarse node + set temp_ngb_list ""; + if {[info exists nneighbour($parent1)] && [info exists nneighbour($parent2)]} then { + # take all neighbours from "parent"-nodes + set all_neighbours [concat $nneighbour($parent1) $nneighbour($parent2)]; + foreach ngb $all_neighbours { + set ngb_map $nmap($ngb); #don't save duplicates - if {$ngb_map == $cnode} then { + if {$ngb_map == $cnode} then { continue; } - if {[lsearch $temp_ngb_list $ngb_map] == -1} then { - lappend temp_ngb_list $ngb_map; - } - } + if {[lsearch $temp_ngb_list $ngb_map] == -1} then { + lappend temp_ngb_list $ngb_map; + } + } - set cnneighbour($cnode) $temp_ngb_list; + set cnneighbour($cnode) $temp_ngb_list; + } } - } -############## EDGES ############### + ############## EDGES ############### - array set cearray {}; - set cnum_edges 0; + array set cearray {}; + set cnum_edges 0; - #coarse edges - for {set i 0} {$i < [array size earray]} {incr i} { - set twin 0; - set node1 [lindex $earray($i) 0]; - set node2 [lindex $earray($i) 1]; + #coarse edges + for {set i 0} {$i < [array size earray]} {incr i} { + set twin 0; + set node1 [lindex $earray($i) 0]; + set node2 [lindex $earray($i) 1]; - set cnode1 $nmap($node1); - set cnode2 $nmap($node2); + set cnode1 $nmap($node1); + set cnode2 $nmap($node2); - if {$cnode1 == $cnode2} then { ;#edge between two coarsed nodes disappears - } else { - #check if the link already exists in coarsed graph - for {set j 0} {$j < [array size cearray]} {incr j} { - if {$cearray($j) == "$cnode1 $cnode2" || $cearray($j) == "$cnode2 $cnode1"} then { - set twin 1; - #add the edge weight to the weight of coarsed edge - incr ceweight($j) $eweight($i); - break; + if {$cnode1 == $cnode2} then { + #edge between two coarsed nodes disappears + } else { + #check if the link already exists in coarsed graph + for {set j 0} {$j < [array size cearray]} {incr j} { + if {$cearray($j) == "$cnode1 $cnode2" || $cearray($j) == "$cnode2 $cnode1"} then { + set twin 1; + #add the edge weight to the weight of coarsed edge + incr ceweight($j) $eweight($i); + break; + } + } + #if its no double edge, make a new edge in coarsed graph + if {$twin == 0} then { + set cearray($cnum_edges) "$cnode1 $cnode2"; + set ceweight($cnum_edges) $eweight($i); + incr cnum_edges; + } } - } - #if its no double edge, make a new edge in coarsed graph - if {$twin == 0} then { - set cearray($cnum_edges) "$cnode1 $cnode2"; - set ceweight($cnum_edges) $eweight($i); - incr cnum_edges; - } } - } - #repeat coarsening - if {$cnvertices > $COARSEN_TO && $nvertices > $cnvertices} { - coarseGraph $cnvertices cnweight cnneighbour cearray ceweight tpwgts; - } else { - #enough coarsed, partition the coarsest graph - makePartitions $cnvertices cnweight cnneighbour cearray ceweight tpwgts; - } + #repeat coarsening + if {$cnvertices > $COARSEN_TO && $nvertices > $cnvertices} { + coarseGraph $cnvertices cnweight cnneighbour cearray ceweight tpwgts; + } else { + #enough coarsed, partition the coarsest graph + makePartitions $cnvertices cnweight cnneighbour cearray ceweight tpwgts + } debug "match Over !!!"; - + #balance, refine and uncoarse the graph balance $cnvertices cnneighbour cnweight cearray ceweight tpwgts 4; FMRefinement $cnvertices cnneighbour cnweight cearray ceweight tpwgts 4; @@ -690,56 +685,56 @@ if {[info exists nneighbour($parent1)] && [info exists nneighbour($parent2)]} th # * tpwgts2 -- array of each partition size of the graph #**** proc makePartitions {nvertices node_weight node_neighbour edge_array edge_weight tpwgts2} { - global COARSEN_TO; - global part_pwgts; - global part_partition; - global part_boundary; - global part_id; - global part_ed; - global part_mincut; + global COARSEN_TO; + global part_pwgts; + global part_partition; + global part_boundary; + global part_id; + global part_ed; + global part_mincut; - upvar $node_weight nweight; - upvar $node_neighbour nneighbour; - upvar $edge_array earray; - upvar $edge_weight eweight; - upvar $tpwgts2 tpwgts; - - #the sum of weight of all neighbours - array set wsum_ngbs {}; - array set bestpartition {}; - array set part_partition {}; - array set visited {}; - array set part_ed {}; - array set part_id {}; + upvar $node_weight nweight; + upvar $node_neighbour nneighbour; + upvar $edge_array earray; + upvar $edge_weight eweight; + upvar $tpwgts2 tpwgts; + + #the sum of weight of all neighbours + array set wsum_ngbs {}; + array set bestpartition {}; + array set part_partition {}; + array set visited {}; + array set part_ed {}; + array set part_id {}; - set part_mincut 0; + set part_mincut 0; - #calculate the sum of all edge-weights in graph - set wsum 1; - for {set i 0} {$i < $nvertices} {incr i} { + #calculate the sum of all edge-weights in graph + set wsum 1; + for {set i 0} {$i < $nvertices} {incr i} { if {[info exists nneighbour($i)]} then { - foreach ngb $nneighbour($i) { + foreach ngb $nneighbour($i) { set e [getEdgeBetween $i $ngb earray]; incr wsum $eweight($e); - } + } } set bestpartitions($i) -1; - } - set bestcut $wsum; + } + set bestcut $wsum; - if {$nvertices <= $COARSEN_TO} then { - set nbfs 4; - } else { - set nbfs 9; - } + if {$nvertices <= $COARSEN_TO} then { + set nbfs 4; + } else { + set nbfs 9; + } while {$nbfs > 1} { incr nbfs -1; set part_boundary ""; # set all vertices to partition 1, and for all vertices to not visited for {set i 0} {$i < $nvertices} {incr i} { - set part_partition($i) 1; - set visited($i) 0; + set part_partition($i) 1; + set visited($i) 0; } set part_pwgts(0) 0; @@ -752,132 +747,132 @@ proc makePartitions {nvertices node_weight node_neighbour edge_array edge_weight set visited($start_node) 1; while {1} { - #graph is disconnected - if {[llength $queue] == 0} { - set more_left 0; - for {set n 0} {$n < $nvertices} {incr n} { - if {$visited($n) == 0} then { - set queue $n; - set visited($n) 1; - set more_left 1; - break; - } - } - if {$more_left == 0} then { - debug "no more left!"; - break; - } + #graph is disconnected + if {[llength $queue] == 0} { + set more_left 0; + for {set n 0} {$n < $nvertices} {incr n} { + if {$visited($n) == 0} then { + set queue $n; + set visited($n) 1; + set more_left 1; + break; + } + } + if {$more_left == 0} then { + debug "no more left!"; + break; + } } - # take the first node from queue - set i [lindex $queue 0]; - set queue [lreplace $queue 0 0]; + # take the first node from queue + set i [lindex $queue 0]; + set queue [lreplace $queue 0 0]; - if {$part_pwgts(0) > 0 && [expr {$part_pwgts(1) - $nweight($i)}] < $tpwgts(1)} then { - debug "preveliko, dalje..."; - continue; - } - #change partition of i from 1 to 0 - set part_partition($i) 0; + if {$part_pwgts(0) > 0 && [expr {$part_pwgts(1) - $nweight($i)}] < $tpwgts(1)} then { + debug "preveliko, dalje..."; + continue; + } + #change partition of i from 1 to 0 + set part_partition($i) 0; - #update the partitions weight - set part_pwgts(0) [expr {$part_pwgts(0) + $nweight($i)}]; - set part_pwgts(1) [expr {$part_pwgts(1) - $nweight($i)}]; + #update the partitions weight + set part_pwgts(0) [expr {$part_pwgts(0) + $nweight($i)}]; + set part_pwgts(1) [expr {$part_pwgts(1) - $nweight($i)}]; - #partition is bigger than it should be - if {$part_pwgts(1) <= $tpwgts(1)} then { - debug "tpwgts(1)=$tpwgts(1)"; - break; - } + #partition is bigger than it should be + if {$part_pwgts(1) <= $tpwgts(1)} then { + debug "tpwgts(1)=$tpwgts(1)"; + break; + } - #search for the not visited neighbors, and attach them to the queue - if {[info exists nneighbour($i)]} then { - foreach ngb $nneighbour($i) { - if {$visited($ngb) == 0} { - set visited($ngb) 1; - lappend queue $ngb; - };#if - };#foreach - } - - };#while + #search for the not visited neighbors, and attach them to the queue + if {[info exists nneighbour($i)]} then { + foreach ngb $nneighbour($i) { + if {$visited($ngb) == 0} { + set visited($ngb) 1; + lappend queue $ngb; + };#if + };#foreach + } + + };#while - array set pwgts2 {}; - set pwgts2(0) 0; - set pwgts2(1) 0; + array set pwgts2 {}; + set pwgts2(0) 0; + set pwgts2(1) 0; - #calculate ID and ED for each vertex - for {set i 0} {$i < $nvertices} {incr i} { - set part_id($i) 0; - set part_ed($i) 0; + #calculate ID and ED for each vertex + for {set i 0} {$i < $nvertices} {incr i} { + set part_id($i) 0; + set part_ed($i) 0; - set curr_partition $part_partition($i); - incr pwgts2($curr_partition) $nweight($i); + set curr_partition $part_partition($i); + incr pwgts2($curr_partition) $nweight($i); - # calculates the sum of the edge weights of the adjacent vertices of i - if {[info exists nneighbour($i)]} then { - foreach ngb $nneighbour($i) { - if {$curr_partition == $part_partition($ngb)} then { + # calculates the sum of the edge weights of the adjacent vertices of i + if {[info exists nneighbour($i)]} then { + foreach ngb $nneighbour($i) { + if {$curr_partition == $part_partition($ngb)} then { # vertice in the same partition incr part_id($i) $eweight([getEdgeBetween $i $ngb earray]); - } else { + } else { # vertice in a different partition incr part_ed($i) $eweight([getEdgeBetween $i $ngb earray]); - };#if-else - };#foreach + };#if-else + };#foreach - if {$part_ed($i) > 0 || [llength $nneighbour($i)] == 0} then { ;#vanjski node, ili nema susjeda - incr part_mincut $part_ed($i); - lappend part_boundary $i; - } - } - } + if {$part_ed($i) > 0 || [llength $nneighbour($i)] == 0} then { + #vanjski node, ili nema susjeda + incr part_mincut $part_ed($i); + lappend part_boundary $i; + } + } + } - set part_mincut [expr {$part_mincut / 2}]; - set sum 0; - debug "init part: part_mincut=$part_mincut"; - for {set k 0} {$k < $nvertices} {incr k} { - incr sum $nweight($k); - } + set part_mincut [expr {$part_mincut / 2}]; + set sum 0; + debug "init part: part_mincut=$part_mincut"; + for {set k 0} {$k < $nvertices} {incr k} { + incr sum $nweight($k); + } - if {$pwgts2(0) + $pwgts2(1) != $sum} { + if {$pwgts2(0) + $pwgts2(1) != $sum} { error "refine: partition weigth wrong!"; - } + } - #balance the graph - balance $nvertices nneighbour nweight earray eweight tpwgts 4; - # edge - based FM refinement - FMRefinement $nvertices nneighbour nweight earray eweight tpwgts 4; + #balance the graph + balance $nvertices nneighbour nweight earray eweight tpwgts 4; + # edge - based FM refinement + FMRefinement $nvertices nneighbour nweight earray eweight tpwgts 4; - #save the partitions if better then current saved - if {$bestcut > $part_mincut} then { - set bestcut $part_mincut; - set bestboundary $part_boundary; - set bestpwgts(0) $part_pwgts(0); - set bestpwgts(1) $part_pwgts(1); - for {set i 0} {$i < $nvertices} {incr i} { + #save the partitions if better then current saved + if {$bestcut > $part_mincut} then { + set bestcut $part_mincut; + set bestboundary $part_boundary; + set bestpwgts(0) $part_pwgts(0); + set bestpwgts(1) $part_pwgts(1); + for {set i 0} {$i < $nvertices} {incr i} { set bestpartitions($i) $part_partition($i); #save the best partitions set bestid($i) $part_id($i); set bested($i) $part_ed($i); - } - if {$part_mincut == 0} then { + } + if {$part_mincut == 0} then { break; + } } - } - } - - #save to globals the best found partitions - set part_mincut $bestcut; - set part_boundary $bestboundary; - set part_pwgts(0) $bestpwgts(0); - set part_pwgts(1) $bestpwgts(1); - for {set i 0} {$i < $nvertices} {incr i} { + + #save to globals the best found partitions + set part_mincut $bestcut; + set part_boundary $bestboundary; + set part_pwgts(0) $bestpwgts(0); + set part_pwgts(1) $bestpwgts(1); + for {set i 0} {$i < $nvertices} {incr i} { set part_partition($i) $bestpartitions($i); set part_id($i) $bestid($i); set part_ed($i) $bested($i); - } + } } #****f* graph_partitioning.tcl/balance @@ -900,134 +895,135 @@ proc makePartitions {nvertices node_weight node_neighbour edge_array edge_weight # * npasses -- number of swap tries #**** proc balance {nvertices node_neighbour node_weight edge_array edge_weight tpart_wgts npasses} { - global part_pwgts; - global part_partition; - global part_boundary; - global part_id; - global part_ed; - global part_mincut; + global part_pwgts; + global part_partition; + global part_boundary; + global part_id; + global part_ed; + global part_mincut; - upvar $node_neighbour nneighbour; - upvar $node_weight nweight; - upvar $edge_array earray; - upvar $edge_weight eweight; - upvar $tpart_wgts tpwgts; - - - set move_from -1; - set move_to -1; - - #there is no boundary nodes - if {[llength $part_boundary] == 0} then { - return; - } - - # chose the the bigger partition to move from - if {($tpwgts(0) - $part_pwgts(0)) < ($tpwgts(1) - $part_pwgts(1))} then { - set move_from 0; - set move_to 1; - } else { - set move_from 1; - set move_to 0; - } - - #prority queue - array set queue {}; - - #put all boundary nodes from move_from partition into queue - for {set i 0} {$i < [llength $part_boundary]} {incr i} { - set b [lindex $part_boundary $i]; - if {$part_partition($b) == $move_from} then { - set b_gain [expr {$part_ed($b) - $part_id($b)}]; - push queue($move_from) "$b $b_gain"; + upvar $node_neighbour nneighbour; + upvar $node_weight nweight; + upvar $edge_array earray; + upvar $edge_weight eweight; + upvar $tpart_wgts tpwgts; + + set move_from -1; + set move_to -1; + + #there is no boundary nodes + if {[llength $part_boundary] == 0} then { + return; } - } - # set all vertices free to move - for {set i 0} {$i < $nvertices} {incr i} { - set moved($i) -1; - } + # chose the the bigger partition to move from + if {($tpwgts(0) - $part_pwgts(0)) < ($tpwgts(1) - $part_pwgts(1))} then { + set move_from 0; + set move_to 1; + } else { + set move_from 1; + set move_to 0; + } + #prority queue + array set queue {}; - for {set pass 0} {$pass < $npasses} {incr pass} { - # doesn't exists, if nodes are not connected - if {![info exists queue($move_from)]} then { - break; + #put all boundary nodes from move_from partition into queue + for {set i 0} {$i < [llength $part_boundary]} {incr i} { + set b [lindex $part_boundary $i]; + if {$part_partition($b) == $move_from} then { + set b_gain [expr {$part_ed($b) - $part_id($b)}]; + push queue($move_from) "$b $b_gain"; + } } - # chose the node with the highest gain - set hi_gain [pop queue($move_from)]; - if {$hi_gain == ""} { - debug "queue($move_from) empty."; - break; + # set all vertices free to move + for {set i 0} {$i < $nvertices} {incr i} { + set moved($i) -1; } + + + for {set pass 0} {$pass < $npasses} {incr pass} { + # doesn't exists, if nodes are not connected + if {![info exists queue($move_from)]} then { + break; + } + + # chose the node with the highest gain + set hi_gain [pop queue($move_from)]; + if {$hi_gain == ""} { + debug "queue($move_from) empty."; + break; + } - #if the size of the partition, in which the node should be moved is to small - #dont move it - if {$part_pwgts($move_to) + $nweight($hi_gain) > $tpwgts($move_to)} then { - break; - } + #if the size of the partition, in which the node should be moved + #is to small, dont move it + if {$part_pwgts($move_to) + $nweight($hi_gain) > $tpwgts($move_to)} then { + break; + } - #update partitions weight - incr part_pwgts($move_from) [expr {-$nweight($hi_gain)}]; - incr part_pwgts($move_to) $nweight($hi_gain); + #update partitions weight + incr part_pwgts($move_from) [expr {-$nweight($hi_gain)}]; + incr part_pwgts($move_to) $nweight($hi_gain); - set part_partition($hi_gain) $move_to; + set part_partition($hi_gain) $move_to; - #all the "extern" links are now "intern", and umgekehrt - set tmp $part_ed($hi_gain); - set part_ed($hi_gain) $part_id($hi_gain); - set part_id($hi_gain) $tmp; - - #if it's no more boundary node - if {$part_ed($hi_gain) == 0} then { - #remove it from the bndy list - set bndy [lreplace $part_boundary [lsearch $part_boundary $hi_gain] [lsearch $part_boundary $hi_gain]]; - } + #all the "extern" links are now "intern", and umgekehrt + set tmp $part_ed($hi_gain); + set part_ed($hi_gain) $part_id($hi_gain); + set part_id($hi_gain) $tmp; + + #if it's no more boundary node + if {$part_ed($hi_gain) == 0} then { + #remove it from the bndy list + set bndy [lreplace $part_boundary [lsearch $part_boundary $hi_gain] [lsearch $part_boundary $hi_gain]]; + } - #update part_id, part_ed values - # go throught all neighbours of node "hi_gain" - if {[info exists nneighbour($hi_gain)]} then { - foreach ngb $nneighbour($hi_gain) { - set is_bnd_node $part_ed($ngb); #if the value is > 0, it is a boundary node - set edgeBetween [getEdgeBetween $hi_gain $ngb earray]; - if {$part_partition($ngb) == $move_to} then { - incr part_id($ngb) $eweight($edgeBetween); - incr part_ed($ngb) -$eweight($edgeBetween); - } else { - incr part_ed($ngb) $eweight($edgeBetween); - incr part_id($ngb) -$eweight($edgeBetween); - } + #update part_id, part_ed values + # go throught all neighbours of node "hi_gain" + if {[info exists nneighbour($hi_gain)]} then { + foreach ngb $nneighbour($hi_gain) { + set is_bnd_node $part_ed($ngb); #if the value is > 0, it is a boundary node + set edgeBetween [getEdgeBetween $hi_gain $ngb earray]; + if {$part_partition($ngb) == $move_to} then { + incr part_id($ngb) $eweight($edgeBetween); + incr part_ed($ngb) -$eweight($edgeBetween); + } else { + incr part_ed($ngb) $eweight($edgeBetween); + incr part_id($ngb) -$eweight($edgeBetween); + } - if {$is_bnd_node > 0} then { - #node "ngb" is no longer an boundary node - if {$part_ed($ngb) == 0} then { - #remove it from the boundary list - set part_boundary [lreplace $part_boundary [lsearch $part_boundary $ngb] [lsearch $part_boundary $ngb]]; - if {$moved($ngb) == -1 && ($part_partition($ngb)==$move_from)} then { - #if not moved -> remove it from the queue - removeFromQueue queue($part_partition($ngb)) $ngb; - } - } else { - #if it wasn't been moved, update it in queue - if {$moved($ngb) == -1 && ($part_partition($ngb) == $move_from)} then { - removeFromQueue queue($part_partition($ngb)) $ngb; - set new_gain [expr {$part_ed($ngb) - $part_id($ngb)}]; - push queue($part_partition($ngb)) "$ngb $new_gain"; - } + if {$is_bnd_node > 0} then { + #node "ngb" is no longer an boundary node + if {$part_ed($ngb) == 0} then { + #remove it from the boundary list + set part_boundary [lreplace $part_boundary [lsearch $part_boundary $ngb] [lsearch $part_boundary $ngb]]; + if {$moved($ngb) == -1 && ($part_partition($ngb)==$move_from)} then { + #if not moved -> remove it from the queue + removeFromQueue queue($part_partition($ngb)) $ngb; + } + } else { + #if it wasn't been moved, update it in queue + if {$moved($ngb) == -1 && ($part_partition($ngb) == $move_from)} then { + removeFromQueue queue($part_partition($ngb)) $ngb; + set new_gain [expr {$part_ed($ngb) - $part_id($ngb)}]; + push queue($part_partition($ngb)) "$ngb $new_gain"; + } + } + } else { + #puts "not boundary node: $ngb"; + if {$part_ed($ngb) > 0} then { + #new boundary node + lappend part_boundary $ngb; + #add it to the queue + if {$moved($ngb) == -1} then { + push queue($part_partition($ngb)) "$ngb [expr {$part_ed($ngb) - $part_id($ngb)}]"; + } + } + } } - } else { ;#puts "not boundary node: $ngb"; - if {$part_ed($ngb) > 0} then { ;#new boundary node - lappend part_boundary $ngb; - #add it to the queue - if {$moved($ngb) == -1} then { - push queue($part_partition($ngb)) "$ngb [expr {$part_ed($ngb) - $part_id($ngb)}]"; - } - } } - } - } - } + } } #****f* graph_partitioning.tcl/FMRefinement @@ -1047,207 +1043,208 @@ proc balance {nvertices node_neighbour node_weight edge_array edge_weight tpart_ # * npasses -- number of swap tries #**** proc FMRefinement {nvertices node_neighbour node_weight edge_array edge_weight tpart_wgt npasses} { - global part_pwgts; - global part_partition; - global part_boundary; - global part_id; - global part_ed; - global part_mincut; + global part_pwgts; + global part_partition; + global part_boundary; + global part_id; + global part_ed; + global part_mincut; - upvar $node_weight nweight; - upvar $node_neighbour nneighbour; - upvar $edge_array earray; - upvar $edge_weight eweight; - upvar $tpart_wgt tpwgts; - - - array set queue {}; - array set bak_id {}; - array set bak_ed {}; - array set bak_part {}; - array set bak_pwgts {}; - - set bak_bndy -1; - set orig_diff [expr {abs ($tpwgts(0) - $part_pwgts(0))}]; - set avg1 [expr {($part_pwgts(0) + $part_pwgts(1)) / 20}]; - set avg2 [expr {2 * ($part_pwgts(0) + $part_pwgts(1)) / $nvertices}]; - if {$avg1 < $avg2} then { - set avg_pwgt $avg1; - } else { - set avg_pwgt $avg2; - } + upvar $node_weight nweight; + upvar $node_neighbour nneighbour; + upvar $edge_array earray; + upvar $edge_weight eweight; + upvar $tpart_wgt tpwgts; + + array set queue {}; + array set bak_id {}; + array set bak_ed {}; + array set bak_part {}; + array set bak_pwgts {}; + + set bak_bndy -1; + set orig_diff [expr {abs ($tpwgts(0) - $part_pwgts(0))}]; + set avg1 [expr {($part_pwgts(0) + $part_pwgts(1)) / 20}]; + set avg2 [expr {2 * ($part_pwgts(0) + $part_pwgts(1)) / $nvertices}]; + if {$avg1 < $avg2} then { + set avg_pwgt $avg1; + } else { + set avg_pwgt $avg2; + } - set swap_limit [expr {int(0.01 * $nvertices)}]; - if {$swap_limit < 15} then { - set swap_limit 15; - } + set swap_limit [expr {int(0.01 * $nvertices)}]; + if {$swap_limit < 15} then { + set swap_limit 15; + } - #pamti najbolju kombinaciju - set bak_bndy $part_boundary; - for {set i 0} {$i < $nvertices} {incr i} { - set bak_part($i) $part_partition($i); - set bak_id($i) $part_id($i); - set bak_ed($i) $part_ed($i); - } - set bak_pwgts(0) $part_pwgts(0); - set bak_pwgts(1) $part_pwgts(1); + #pamti najbolju kombinaciju + set bak_bndy $part_boundary; + for {set i 0} {$i < $nvertices} {incr i} { + set bak_part($i) $part_partition($i); + set bak_id($i) $part_id($i); + set bak_ed($i) $part_ed($i); + } + set bak_pwgts(0) $part_pwgts(0); + set bak_pwgts(1) $part_pwgts(1); - # set all vertices free to move - for {set i 0} {$i < $nvertices} {incr i} { - set moved($i) -1; - } + # set all vertices free to move + for {set i 0} {$i < $nvertices} {incr i} { + set moved($i) -1; + } - for {set pass 0} {$pass < $npasses} {incr pass} { - #set all variables to their's initial values - set bndy $part_boundary; - set newcut $part_mincut; - set mincut $part_mincut; - set min_diff [expr {abs ($tpwgts(0) - $part_pwgts(0))}]; + for {set pass 0} {$pass < $npasses} {incr pass} { + #set all variables to their's initial values + set bndy $part_boundary; + set newcut $part_mincut; + set mincut $part_mincut; + set min_diff [expr {abs ($tpwgts(0) - $part_pwgts(0))}]; - for {set i 0} {$i < 2} {incr i} { - set pwgts($i) $part_pwgts($i); - set queue($i) ""; - } + for {set i 0} {$i < 2} {incr i} { + set pwgts($i) $part_pwgts($i); + set queue($i) ""; + } - for {set i 0} {$i < $nvertices} {incr i} { - set part($i) $part_partition($i); - set id($i) $part_id($i); - set ed($i) $part_ed($i); - } - - # insert boundary nodes in the priority queue - set permList [makePermArray bndy]; - array set permArray $permList; - set mincutorder -1; + for {set i 0} {$i < $nvertices} {incr i} { + set part($i) $part_partition($i); + set id($i) $part_id($i); + set ed($i) $part_ed($i); + } - for {set i 0} {$i < [array size permArray]} {incr i} { - set node $permArray($i); - #calculate the node's gain - set node_gain [expr {$ed($node) - $id($node)}]; - # push in the queue 0 or 1 (depends in which partition node is) the node and its gain - push queue($part($node)) "$node $node_gain"; - };#foreach + # insert boundary nodes in the priority queue + set permList [makePermArray bndy]; + array set permArray $permList; + set mincutorder -1; + + for {set i 0} {$i < [array size permArray]} {incr i} { + set node $permArray($i); + #calculate the node's gain + set node_gain [expr {$ed($node) - $id($node)}]; + # push in the queue 0 or 1 (depends in which partition node is) the node and its gain + push queue($part($node)) "$node $node_gain"; + };#foreach - # chose the best-gain move - for {set nswaps 0} {$nswaps < $nvertices} {incr nswaps} { - debug "nswaps=$nswaps"; - # chose the node from the bigger partition to move to the smaller - if {($tpwgts(0) - $pwgts(0)) < ($tpwgts(1) - $pwgts(1))} then { - set move_from 0; - set move_to 1; - } else { - set move_from 1; - set move_to 0; - } + # chose the best-gain move + for {set nswaps 0} {$nswaps < $nvertices} {incr nswaps} { + debug "nswaps=$nswaps"; + # chose the node from the bigger partition to move to the smaller + if {($tpwgts(0) - $pwgts(0)) < ($tpwgts(1) - $pwgts(1))} then { + set move_from 0; + set move_to 1; + } else { + set move_from 1; + set move_to 0; + } - # chose the node with the highest gain - set hi_gain [pop queue($move_from)]; - if {$hi_gain == ""} { + # chose the node with the highest gain + set hi_gain [pop queue($move_from)]; + if {$hi_gain == ""} { break; - } + } - # update the cut and partitions weight - set newcut [expr {$newcut - $ed($hi_gain) + $id($hi_gain)}]; - incr pwgts($move_from) [expr {-$nweight($hi_gain)}]; - incr pwgts($move_to) $nweight($hi_gain); + # update the cut and partitions weight + set newcut [expr {$newcut - $ed($hi_gain) + $id($hi_gain)}]; + incr pwgts($move_from) [expr {-$nweight($hi_gain)}]; + incr pwgts($move_to) $nweight($hi_gain); - #check if the new cut better is than the old one - set new_diff [expr {abs ($tpwgts(0) - $pwgts(0))}]; - if {($newcut < $mincut) && ($new_diff <= $orig_diff + $avg_pwgt) || + #check if the new cut better is than the old one + set new_diff [expr {abs ($tpwgts(0) - $pwgts(0))}]; + if {($newcut < $mincut) && ($new_diff <= $orig_diff + $avg_pwgt) || ($newcut == $mincut) && ($new_diff < $min_diff)} then { set mincutorder $nswaps; set mincut $newcut; set min_diff $new_diff; - } elseif {$nswaps - $mincutorder > $swap_limit} { + } elseif {$nswaps - $mincutorder > $swap_limit} { incr newcut [expr {$ed($hi_gain) - $id($hi_gain)}]; incr pwgts($move_to) [expr {-$nweight($hi_gain)}]; incr pwgts($move_from) $nweight($hi_gain); break; - } + } - #move node to the other partion - set part($hi_gain) $move_to; - set moved($hi_gain) $nswaps; - set swaps($nswaps) $hi_gain; - - #all the "extern" links are now "intern", and reverse - set tmp $ed($hi_gain); - set ed($hi_gain) $id($hi_gain); - set id($hi_gain) $tmp; - - #if it's no more boundary node - if {$ed($hi_gain) == 0} then { + #move node to the other partion + set part($hi_gain) $move_to; + set moved($hi_gain) $nswaps; + set swaps($nswaps) $hi_gain; + + #all the "extern" links are now "intern", and reverse + set tmp $ed($hi_gain); + set ed($hi_gain) $id($hi_gain); + set id($hi_gain) $tmp; + + #if it's no more boundary node + if {$ed($hi_gain) == 0} then { #remove it from the bndy list set bndy [lreplace $bndy [lsearch $bndy $hi_gain] [lsearch $bndy $hi_gain]]; - } + } - #update ID, ED values - # go throught all neighbours of node "hi_gain" - if {[info exists nneighbour($hi_gain)]} then { + #update ID, ED values + # go throught all neighbours of node "hi_gain" + if {[info exists nneighbour($hi_gain)]} then { foreach ngb $nneighbour($hi_gain) { - set is_bnd_node $ed($ngb); #if the value is > 0, it is a boundary node - set edgeBetween [getEdgeBetween $hi_gain $ngb earray]; - if {$part($ngb) == $move_to} then { + set is_bnd_node $ed($ngb); #if the value is > 0, it is a boundary node + set edgeBetween [getEdgeBetween $hi_gain $ngb earray]; + if {$part($ngb) == $move_to} then { incr id($ngb) $eweight($edgeBetween); incr ed($ngb) -$eweight($edgeBetween); - } else { + } else { incr ed($ngb) $eweight($edgeBetween); incr id($ngb) -$eweight($edgeBetween); - } - if {$is_bnd_node > 0} then { - #node "ngb" is no longer an boundary node + } + if {$is_bnd_node > 0} then { + #node "ngb" is no longer an boundary node if {$ed($ngb) == 0} then { - #remove it from the boundary list - set bndy [lreplace $bndy [lsearch $bndy $ngb] [lsearch $bndy $ngb]]; - if {$moved($ngb) == -1} then { - #if not moved -> remove it from the queue - removeFromQueue queue($part($ngb)) $ngb; - } + #remove it from the boundary list + set bndy [lreplace $bndy [lsearch $bndy $ngb] [lsearch $bndy $ngb]]; + if {$moved($ngb) == -1} then { + #if not moved -> remove it from the queue + removeFromQueue queue($part($ngb)) $ngb; + } } else { - #if it wasn't been moved, update it in queue - if {$moved($ngb) == -1} then { - removeFromQueue queue($part($ngb)) $ngb; + #if it wasn't been moved, update it in queue + if {$moved($ngb) == -1} then { + removeFromQueue queue($part($ngb)) $ngb; set new_gain [expr {$ed($ngb) - $id($ngb)}]; push queue($part($ngb)) "$ngb $new_gain"; + } } - } - } else { ;#puts "not boundary node: $ngb"; + } else { + #puts "not boundary node: $ngb"; if {$ed($ngb) > 0} then { ;#new boundary node - lappend bndy $ngb; - #add it to the queue - if {$moved($ngb) == -1} then { - push queue($part($ngb)) "$ngb [expr {$ed($ngb) - $id($ngb)}]"; - } + lappend bndy $ngb; + #add it to the queue + if {$moved($ngb) == -1} then { + push queue($part($ngb)) "$ngb [expr {$ed($ngb) - $id($ngb)}]"; + } } + } } + } + + if {$mincutorder > -1} then { + set mincutorder -1; + set mincut $newcut; + set bak_bndy $bndy; + for {set j 0} {$j < $nvertices} {incr j} { + set bak_id($j) $id($j); + set bak_ed($j) $ed($j); + set bak_part($j) $part($j); } - } - if {$mincutorder > -1} then { - set mincutorder -1; - set mincut $newcut; - set bak_bndy $bndy; - for {set j 0} {$j < $nvertices} {incr j} { - set bak_id($j) $id($j); - set bak_ed($j) $ed($j); - set bak_part($j) $part($j); - } - set bak_pwgts(0) $pwgts(0); - set bak_pwgts(1) $pwgts(1); - } - };#inner loop - };#outer loop - - #save the best partitions - set part_mincut $mincut; - set part_boundary $bak_bndy; - for {set i 0} {$i < $nvertices} {incr i} { - set part_partition($i) $bak_part($i); - set part_id($i) $bak_id($i); - set part_ed($i) $bak_ed($i); - } - set part_pwgts(0) $bak_pwgts(0); - set part_pwgts(1) $bak_pwgts(1); + set bak_pwgts(0) $pwgts(0); + set bak_pwgts(1) $pwgts(1); + } + };#inner loop + };#outer loop + + #save the best partitions + set part_mincut $mincut; + set part_boundary $bak_bndy; + for {set i 0} {$i < $nvertices} {incr i} { + set part_partition($i) $bak_part($i); + set part_id($i) $bak_id($i); + set part_ed($i) $bak_ed($i); + } + set part_pwgts(0) $bak_pwgts(0); + set part_pwgts(1) $bak_pwgts(1); } #****f* graph_partitioning.tcl/project2waypartition @@ -1268,63 +1265,63 @@ proc FMRefinement {nvertices node_neighbour node_weight edge_array edge_weight t # * cnvw -- array of node weights in coarse graph #**** proc project2waypartition {nvertices edge_array edge_weight node_neighbour node_map node_weight cnv cnvw} { - global part_pwgts; - global part_mincut; - global part_partition; - global part_id; - global part_ed; - global part_boundary; + global part_pwgts; + global part_mincut; + global part_partition; + global part_id; + global part_ed; + global part_boundary; - upvar $cnvw cnw; - upvar $node_weight nweight; - upvar $edge_array earray; - upvar $edge_weight eweight; - upvar $node_neighbour nneighbour; - upvar $node_map nmap; - - array set part_ed {}; - array set part_id {}; - set part_boundary ""; - array set pwgts2 {}; + upvar $cnvw cnw; + upvar $node_weight nweight; + upvar $edge_array earray; + upvar $edge_weight eweight; + upvar $node_neighbour nneighbour; + upvar $node_map nmap; + + array set part_ed {}; + array set part_id {}; + set part_boundary ""; + array set pwgts2 {}; - #sum the weight of nodes in finer graph - set n 0; set p 0; - for {set i 0} {$i < $nvertices} {incr i} { - incr n $nweight($i); - } - #sum the weight of nodes in coarsed graph - for {set i 0} {$i < $cnv} {incr i} { - incr p $cnw($i); - } - - #get partition for each vertex in finer graph - for {set i 0} {$i < $nvertices} {incr i} { - set cnode $nmap($i); #get the node in coarsed graph which corresponse to the node in finer graph - set partition($i) $part_partition($cnode); #get it's partition too - set part_ed($i) 0; - set part_id($i) 0; - set pwgts2(0) 0; - set pwgts2(1) 0; -} + #sum the weight of nodes in finer graph + set n 0; set p 0; + for {set i 0} {$i < $nvertices} {incr i} { + incr n $nweight($i); + } + #sum the weight of nodes in coarsed graph + for {set i 0} {$i < $cnv} {incr i} { + incr p $cnw($i); + } - #calculate ID and ED - for {set i 0} {$i < $nvertices} {incr i} { + #get partition for each vertex in finer graph + for {set i 0} {$i < $nvertices} {incr i} { + set cnode $nmap($i); #get the node in coarsed graph which corresponse to the node in finer graph + set partition($i) $part_partition($cnode); #get it's partition too + set part_ed($i) 0; + set part_id($i) 0; + set pwgts2(0) 0; + set pwgts2(1) 0; + } + + #calculate ID and ED + for {set i 0} {$i < $nvertices} {incr i} { if {![info exists nneighbour($i)] || [llength $nneighbour($i)] == 0} then { - lappend part_boundary $i; + lappend part_boundary $i; } else { - foreach ngb $nneighbour($i) { - if {$partition($ngb) == $partition($i)} then { - incr part_id($i) $eweight([getEdgeBetween $i $ngb earray]); #mogu uzeti stare tezine - posto iste - #incr id($ngb) $eweight([...]); - } else { - incr part_ed($i) $eweight([getEdgeBetween $i $ngb earray]); - #incr ed($ngb) $eweight([...]); - } - };#foreach - - if {[expr $part_ed($i) > 0 || [llength $nneighbour($i)] == 0]} then { - lappend part_boundary $i; + foreach ngb $nneighbour($i) { + if {$partition($ngb) == $partition($i)} then { + incr part_id($i) $eweight([getEdgeBetween $i $ngb earray]); #mogu uzeti stare tezine - posto iste + #incr id($ngb) $eweight([...]); + } else { + incr part_ed($i) $eweight([getEdgeBetween $i $ngb earray]); + #incr ed($ngb) $eweight([...]); } + };#foreach + + if {[expr $part_ed($i) > 0 || [llength $nneighbour($i)] == 0]} then { + lappend part_boundary $i; + } } set part_partition($i) $partition($i); incr pwgts2($partition($i)) $nweight($i); @@ -1355,78 +1352,72 @@ proc project2waypartition {nvertices edge_array edge_weight node_neighbour node_ # * snode_map_help -- help variable, needed for later connecting, in this procedure disconnected graphs #**** proc splitGraph {nvertices node_neighbour node_weight edge_array edge_weight snode_neighbour snode_weight sedge_array sedge_weight snode_map sn_vtxs sn_edges snode_map_help} { - global part_partition; - - upvar $node_neighbour nneighbour; - upvar $node_weight nweight; - upvar $edge_array earray; - upvar $edge_weight eweight; - upvar $snode_neighbour snneighbour; - upvar $snode_weight snweight; - upvar $sedge_array searray; - upvar $sedge_weight seweight; - upvar $snode_map snmap; - upvar $snode_map_help snmap_h; - upvar $sn_vtxs snvtxs; - upvar $sn_edges snedges; - - array set sum_np {}; - set sum_np(0) 0; - set sum_np(1) 0; - - array set auxn {}; - array set auxw {}; - - #sets variables needed later for connecting the splited graph - for {set i 0} {$i < $nvertices} {incr i} { + global part_partition; + + upvar $node_neighbour nneighbour; + upvar $node_weight nweight; + upvar $edge_array earray; + upvar $edge_weight eweight; + upvar $snode_neighbour snneighbour; + upvar $snode_weight snweight; + upvar $sedge_array searray; + upvar $sedge_weight seweight; + upvar $snode_map snmap; + upvar $snode_map_help snmap_h; + upvar $sn_vtxs snvtxs; + upvar $sn_edges snedges; + + array set sum_np {}; + set sum_np(0) 0; + set sum_np(1) 0; + + array set auxn {}; + array set auxw {}; + + #sets variables needed later for connecting the splited graph + for {set i 0} {$i < $nvertices} {incr i} { set p $part_partition($i); set snmap($p,$i) $snvtxs($p); set snmap_h($p,$snvtxs($p)) $i; incr snvtxs($p); - } - - #split the graph - for {set i 0} {$i < $nvertices} {incr i} { - set p_i $part_partition($i); - set s_i $snmap($p_i,$i); - set sum 0; - - if {[info exists nneighbour($i)]} then { - foreach ngb $nneighbour($i) { - set p $part_partition($ngb); - if {$p == $p_i} then { - set twin 0; - set sngb $snmap($p_i,$ngb); - lappend snneighbour($p_i,$s_i) $sngb; - for {set a 0} {$a < $snedges($p_i)} {incr a} { - if {$searray($p_i,$a) == "$s_i $sngb" || $searray($p_i,$a) == "$sngb $s_i"} then { - set twin 1; - break; - } - } - if {$twin == 0} then { - set searray($p_i,$snedges($p_i)) "$s_i $sngb"; - set seweight($p_i,$snedges($p_i)) $eweight([getEdgeBetween $i $ngb earray]); - incr snedges($p_i); - } - incr sum $nweight($ngb); - } else { - incr sum [expr {-$nweight($ngb)}] - } + } - };#foreach -} + #split the graph + for {set i 0} {$i < $nvertices} {incr i} { + set p_i $part_partition($i); + set s_i $snmap($p_i,$i); + set sum 0; + + if {[info exists nneighbour($i)]} then { + foreach ngb $nneighbour($i) { + set p $part_partition($ngb); + if {$p == $p_i} then { + set twin 0; + set sngb $snmap($p_i,$ngb); + lappend snneighbour($p_i,$s_i) $sngb; + for {set a 0} {$a < $snedges($p_i)} {incr a} { + if {$searray($p_i,$a) == "$s_i $sngb" || $searray($p_i,$a) == "$sngb $s_i"} then { + set twin 1; + break; + } + } + if {$twin == 0} then { + set searray($p_i,$snedges($p_i)) "$s_i $sngb"; + set seweight($p_i,$snedges($p_i)) $eweight([getEdgeBetween $i $ngb earray]); + incr snedges($p_i); + } + incr sum $nweight($ngb); + } else { + incr sum [expr {-$nweight($ngb)}] + } + };#foreach + } set snweight($p_i,$s_i) $nweight($i); set sadjwgtsum($p_i,$s_i)) $sum; - } - + } } - - -#####################PROCEDURES ########################## - #****f* graph_partitioning.tcl/sum_array # NAME # sum_array @@ -1441,14 +1432,14 @@ proc splitGraph {nvertices node_neighbour node_weight edge_array edge_weight sno # * sum -- the sum of first "end" numbers #**** proc sum_array {end arr} { - upvar 1 $arr a; - set sum 0.0; + upvar 1 $arr a; + set sum 0.0; - for {set i 0} {$i < $end} {incr i} { + for {set i 0} {$i < $end} {incr i} { set sum [expr {$sum + $a($i)}]; - } + } - return $sum; + return $sum; } #****f* graph_partitioning.tcl/mult_array @@ -1468,10 +1459,10 @@ proc sum_array {end arr} { # * #**** proc mult_array {start end arr prod} { - upvar 1 $arr a; - for {set i $start} {$i < $end} {incr i} { - set a($i) [expr {$a($i) * $prod }]; - } + upvar 1 $arr a; + for {set i $start} {$i < $end} {incr i} { + set a($i) [expr {$a($i) * $prod }]; + } } #****f* graph_partitioning.tcl/makePermList @@ -1487,25 +1478,25 @@ proc mult_array {start end arr prod} { # * list -- permuted list #**** proc makePermList {num} { - array set permList ""; + array set permList ""; - for {set i 0} {$i < $num} {incr i} { - set permList($i) $i; - } + for {set i 0} {$i < $num} {incr i} { + set permList($i) $i; + } - if {$num > 4} { + if {$num > 4} { for {set i 0} {$i < $num} {incr i 16} { - set rand1 [expr {int(rand() * ($num - 4))}] - set rand2 [expr {int(rand() * ($num - 4))}] + set rand1 [expr {int(rand() * ($num - 4))}] + set rand2 [expr {int(rand() * ($num - 4))}] - swap permList $rand1 $rand2; - swap permList [expr $rand1+1] [expr $rand2+1]; - swap permList [expr $rand1+2] [expr $rand2+2]; - swap permList [expr $rand1+3] [expr $rand2+3]; + swap permList $rand1 $rand2; + swap permList [expr $rand1+1] [expr $rand2+1]; + swap permList [expr $rand1+2] [expr $rand2+2]; + swap permList [expr $rand1+3] [expr $rand2+3]; } - } + } - return [array get permList]; + return [array get permList]; } #****f* graph_partitioning.tcl/makePermArray @@ -1521,26 +1512,26 @@ proc makePermList {num} { # * list -- permuted list #**** proc makePermArray {arr} { - upvar $arr a; - array set permList ""; - set a_size [llength $a]; - for {set i 0} {$i < $a_size} {incr i} { - set permList($i) [lindex $a $i]; - } - - if {$a_size > 4} { + upvar $arr a; + array set permList ""; + set a_size [llength $a]; + for {set i 0} {$i < $a_size} {incr i} { + set permList($i) [lindex $a $i]; + } + + if {$a_size > 4} { for {set i 0} {$i < $a_size} {incr i 16} { - set rand1 [expr {int(rand() * ($a_size - 4))}] - set rand2 [expr {int(rand() * ($a_size - 4))}] + set rand1 [expr {int(rand() * ($a_size - 4))}] + set rand2 [expr {int(rand() * ($a_size - 4))}] - swap permList $rand1 $rand2; - swap permList [expr $rand1+1] [expr $rand2+1]; - swap permList [expr $rand1+2] [expr $rand2+2]; - swap permList [expr $rand1+3] [expr $rand2+3]; + swap permList $rand1 $rand2; + swap permList [expr $rand1+1] [expr $rand2+1]; + swap permList [expr $rand1+2] [expr $rand2+2]; + swap permList [expr $rand1+3] [expr $rand2+3]; } - } + } - return [array get permList]; + return [array get permList]; } #****f* graph_partitioning.tcl/swap @@ -1556,11 +1547,11 @@ proc makePermArray {arr} { # * idx2 -- index of the second element #**** proc swap {permArray idx1 idx2} { - upvar $permArray rarray; + upvar $permArray rarray; - set temp $rarray($idx1); - set rarray($idx1) $rarray($idx2); - set rarray($idx2) $temp; + set temp $rarray($idx1); + set rarray($idx1) $rarray($idx2); + set rarray($idx2) $temp; } #****f* graph_partitioning.tcl/getEdgeBetween @@ -1578,12 +1569,12 @@ proc swap {permArray idx1 idx2} { # * i -- index of the edge connecting the nodes, or null #**** proc getEdgeBetween {node1 node2 edge_array} { - upvar $edge_array earray; - for {set i 0} {$i < [array size earray]} {incr i} { + upvar $edge_array earray; + for {set i 0} {$i < [array size earray]} {incr i} { if {$earray($i) == "$node1 $node2" || $earray($i) == "$node2 $node1"} then { - return $i; - };#if - };#foreach + return $i; + } + } } #****f* graph_partitioning.tcl/push @@ -1609,14 +1600,14 @@ interp alias {} push {} lappend # * hi_elem -- element from the array #**** proc pop {queue_name} { - upvar 1 $queue_name queue; - - #sort items after priority - set queue [lsort -integer -decreasing -index 1 $queue]; - set hi_ [lindex $queue 0]; - set hi_elem [lindex $hi_ 0]; - set queue [lrange $queue 1 end]; - return $hi_elem; + upvar 1 $queue_name queue; + + #sort items after priority + set queue [lsort -integer -decreasing -index 1 $queue]; + set hi_ [lindex $queue 0]; + set hi_elem [lindex $hi_ 0]; + set queue [lrange $queue 1 end]; + return $hi_elem; } #****f* graph_partitioning.tcl/removeFromQueue @@ -1631,15 +1622,15 @@ proc pop {queue_name} { # * node -- node id #**** proc removeFromQueue {queue_name node } { - upvar 1 $queue_name queue; + upvar 1 $queue_name queue; - foreach q $queue { - set n [lindex $q 0]; - if {$n == $node} then { - set node_idx [lsearch $queue $q]; - set queue [lreplace $queue $node_idx $node_idx]; - } + foreach q $queue { + set n [lindex $q 0]; + if {$n == $node} then { + set node_idx [lsearch $queue $q]; + set queue [lreplace $queue $node_idx $node_idx]; } + } } diff --git a/initgui.tcl b/initgui.tcl index 2df5996..f1ecd35 100755 --- a/initgui.tcl +++ b/initgui.tcl @@ -1,4 +1,4 @@ -# $Id: initgui.tcl,v 1.36 2007/07/19 01:17:05 marko Exp $ +# $Id: initgui.tcl,v 1.37 2007/07/19 02:33:14 marko Exp $ # # Copyright 2004, 2005 University of Zagreb, Croatia. All rights reserved. # @@ -560,9 +560,9 @@ menu .button3menu.ethereal -tearoff 0 # set invisible -1 bind . { - global invisible - set invisible [expr $invisible * -1] - redrawAll + global invisible + set invisible [expr $invisible * -1] + redrawAll } #