четверг, 28 июля 2011 г.

Алгоритм поиска минимального остовного дерева

cls

$m = @(
    @(0,  13, 3,  9,  9),
    @(13, 0,  11, 11, 13),
    @(3,  11, 0,  9,  7),
    @(9,  11, 9,  0,  2),
    @(9,  13, 7,  2,  0)
)

$a = @(
    @(0,  0,  0,  0,  0),
    @(0,  0,  0,  0,  0),
    @(0,  0,  0,  0,  0),
    @(0,  0,  0,  0,  0),
    @(0,  0,  0,  0,  0)
)

$atemp = @(
    @(0,  0,  0,  0,  0),
    @(0,  0,  0,  0,  0),
    @(0,  0,  0,  0,  0),
    @(0,  0,  0,  0,  0),
    @(0,  0,  0,  0,  0)
)

function copyarr($source, $dest){
    for($i=0; $i -lt $source.Length; $i++){
        for($j=0; $j -lt $source[$i].Length; $j++){
            $dest[$i][$j] = $source[$i][$j]   
        }
    }
}

function matrixdost($matrix){
    #алгоритм уоршела, для вычисления матрицы достижимости
    for ($k = 0; $k -lt $matrix.Length; $k++){
        for ($i = 0; $i -lt $matrix.Length; $i++){
            for ($j = 0; $j -lt $matrix.Length; $j++){
                $matrix[$i][$j] = $matrix[$i][$j] -or ($matrix[$i][$k] -and $matrix[$k][$j])
            }
        }
    }
}

function matrixsv($matrix){
    $v = @()
    $a = @()
    [object[]]$all = @()
    for($i = 0; $i -lt $matrix.Length; $i++){
        $v += 1
    }
   
    #компоненты связанности
    for($i = 0; $i -lt $v.Length; $i++){
        $a = @()
        if ($v[$i] -eq 0){
            continue
        }
        for($j = 0; $j -lt $v.Length; $j++){
            if ($matrix[$i][$j]){
                $a += $j
                $v[$j] = 0
            }
        }
        if ($a.Length -ne 0){
            $all += [object]$a
            $all += "-"
        }
    }
   
    for ($i=0; $i -lt $v.Length; $i++){
        if ($v[$i] -eq 1){
            $all += $i
            $all += "-"
        }
    }
   
    return $all
}

function numedges($matrix, $points){
    $num = 0
    for($i = 0; $i -lt $points.Length - 1; $i++){
        for($j = $i + 1 ; $j -lt $points.Length; $j++){
            if ($matrix[$points[$i]][$points[$j]] -ne 0){
                $matrix[$points[$j]][$points[$i]] = 0
                $num++
            }
        }
    }
    return $num
}

function iscycle($matrix){
    copyarr $matrix $atemp
    matrixdost $atemp
    $sv = matrixsv $atemp
    $points = @()
   
    for($i = 0; $i -lt $sv.Length; $i++){
        if ($sv[$i] -eq "-"){
            copyarr $matrix $atemp
            if ($points.Length -gt 2){
                $num = numedges -matrix $atemp -points $points
                if ($num -ge $points.Length){
                    return $true
                }
            }
            $points = @()
        }
        else {
            $points += $sv[$i]
        }
    }
    return $false
}

function matrixminel($matrix){
    $min = @(0,0,0)
    for ($i = 1; $i -lt $matrix.Length; $i++){
        for($j = 0; $j -lt $i; $j++){
            if (($matrix[$i][$j] -ne 0 -and $min[0] -gt $matrix[$i][$j]) -or ($min[0] -eq 0)){
                $min[0] = $matrix[$i][$j]
                $min[1] = $i
                $min[2] = $j
            }
        }
    }
    return $min
}

function matrixprint($matrix){
    for($i = 0; $i -lt $matrix.Length; $i++){
        $str = [System.String]::Join(",", $matrix[$i])
        Write-Host $str
    }
}

matrixprint $m

$minel = matrixminel $m

while ($minel[0] -ne 0){
    $a[$minel[1]][$minel[2]] = $minel[0]
    $a[$minel[2]][$minel[1]] = $minel[0]
    $m[$minel[1]][$minel[2]] = 0
    $m[$minel[2]][$minel[1]] = 0
   
    if (iscycle $a){
        $a[$minel[1]][$minel[2]] = 0
        $a[$minel[2]][$minel[1]] = 0
    }
   
    $minel = matrixminel $m
}

"-----------------" | Out-Host
matrixprint $a

Комментариев нет:

Отправить комментарий