Skip to content

Commit

Permalink
add direction of optimization of nds()
Browse files Browse the repository at this point in the history
  • Loading branch information
jbytecode committed Dec 16, 2021
1 parent 6b7b3b3 commit 1e44e5c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
### 0.2.8
- Direction of optimization added for nds()
- New tests added

### 0.2.7
- Bug in Moore fixed.
- Bug in Marcos fixed.
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "JMcDM"
uuid = "358108f5-d052-4d0a-8344-d5384e00c0e5"
authors = ["Mehmet Hakan Satman (jbytecode) <[email protected]>", "Bahadir Fatih Yildirim <[email protected]>"]
version = "0.2.7"
version = "0.2.8"

[deps]
Cbc = "9961bab8-2fa3-5c5a-9d89-47fab24efd76"
Expand Down
38 changes: 21 additions & 17 deletions src/nds.jl
Original file line number Diff line number Diff line change
@@ -1,62 +1,65 @@
"""
dominates(p1::Array, p2::Array)
dominates(p1::Array, p2::Array, fns)
Return true if each element in p1 is not less than the corresponding element in p2 and at least one element in p1 is bigger than the corresponding element in p2.
# Arguments
- `p1::Array`: Numeric array of n elements.
- `p2::Array`: Numeric array of n elements.
- `fns::Array{Function, 1}`: Vector of functions with elements of maximum or minimum.
# Examples
```julia-repl
julia> dominates([1,2,3], [1,2,1])
julia> dominates([1,2,3], [1,2,1], makeminmax([maximum, maximum, maximum]))
true
julia> dominates([0,0,0,0], [1,0,0,0])
julia> dominates([0,0,0,0], [1,0,0,0], makeminmax([maximum, maximum, maximum]))
false
```
# References
Deb, Kalyanmoy, et al. "A fast elitist non-dominated sorting genetic algorithm for multi-objective optimization: NSGA-II."
International conference on parallel problem solving from nature. Springer, Berlin, Heidelberg, 2000.
"""
function dominates(p1::Array, p2::Array)::Bool
function dominates(p1::Array, p2::Array, fns::Array{Function, 1})::Bool
n = length(p1)
notworse = count(i -> p1[i] < p2[i], 1:n)
better = count(i -> p1[i] > p2[i], 1:n)
notworse = count(i -> if fns[i] == maximum p1[i] < p2[i] else p1[i] > p2[i] end, 1:n)
better = count(i -> if fns[i] == maximum p1[i] > p2[i] else p1[i] < p2[i] end , 1:n)
return (notworse == 0) && (better > 0)
end



"""
ndsranks(data)
ndsranks(data, fns)
Sort multidimensional data usin non-dominated sorting algorithm.
# Arguments
- `data::DataFrame`: DataFrame of variables.
- `fns::Array{Function, 1}`: Vector of functions with elements of maximum or minimum.
# References
Deb, Kalyanmoy, et al. "A fast elitist non-dominated sorting genetic algorithm for multi-objective optimization: NSGA-II."
International conference on parallel problem solving from nature. Springer, Berlin, Heidelberg, 2000.
"""
function ndsranks(data::DataFrame)::Array{Int}
function ndsranks(data::DataFrame, fns::Array{Function, 1})::Array{Int}

#mat = convert(Matrix, data)
mat = Matrix(data)
return ndsranks(mat)
return ndsranks(mat, fns)

end



"""
ndsranks(data)
ndsranks(data, fns)
Sort multidimensional data using non-dominated sorting algorithm.
# Arguments
- `data::Matrix`: n x k matrix of observations where n is number of observations and k is number of variables.
- `fns::Array{Function, 1}`: Vector of functions with elements of maximum or minimum.
# Examples
```julia-repl
Expand All @@ -67,9 +70,9 @@ end
Deb, Kalyanmoy, et al. "A fast elitist non-dominated sorting genetic algorithm for multi-objective optimization: NSGA-II."
International conference on parallel problem solving from nature. Springer, Berlin, Heidelberg, 2000.
"""
function ndsranks(data::Matrix)::Array{Int64}
function ndsranks(data::Matrix, fns::Array{Function, 1})::Array{Int64}

n, p = size(data)
n, _ = size(data)

ranks = zeros(Int64, n)

Expand All @@ -78,7 +81,7 @@ function ndsranks(data::Matrix)::Array{Int64}
@inbounds for i in 1:n
@inbounds for j in 1:n
if i != j
if dominates(mat[i,:], mat[j,:])
if dominates(mat[i,:], mat[j,:], fns)
ranks[i] += 1
end
end
Expand All @@ -90,12 +93,13 @@ end


"""
nds(data)
nds(data, fns)
Sort multidimensional data using non-dominated sorting algorithm.
# Arguments
- `data::DataFrame`: n x k desicion matrix with n cases and k criteria.
- `fns::Array{Function, 1}`: Vector of functions with elements of maximum or minimum.
# Output
- `::NDSResult`: NDSResult object that holds multiple outputs including ranks and best index.
Expand All @@ -120,7 +124,7 @@ julia> nd = makeDecisionMatrix(cases)
3 │ 1.0 3.0 2.0
4 │ 4.0 5.0 6.0
julia> result = nds(nd);
julia> result = nds(nd, makeminmax([maximum, maximum, maximum]));
julia> result.ranks
4-element Array{Int64,1}:
Expand All @@ -137,9 +141,9 @@ julia> result.bestIndex
Deb, Kalyanmoy, et al. "A fast elitist non-dominated sorting genetic algorithm for multi-objective optimization: NSGA-II."
International conference on parallel problem solving from nature. Springer, Berlin, Heidelberg, 2000.
"""
function nds(data::DataFrame)::NDSResult
function nds(data::DataFrame, fns::Array{Function, 1})::NDSResult

ranks = ndsranks(data)
ranks = ndsranks(data, fns)

bestIndex = sortperm(ranks) |> last

Expand Down
46 changes: 35 additions & 11 deletions test/testmcdm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -434,23 +434,47 @@


@testset "NDS" begin
cases = [
1.0 2.0 3.0
2.0 1.0 3.0
1.0 3.0 2.0
4.0 5.0 6.0
]
@testset "NDS - all maximum" begin
cases = [
1.0 2.0 3.0
2.0 1.0 3.0
1.0 3.0 2.0
4.0 5.0 6.0
]

nd = makeDecisionMatrix(cases)
nd = makeDecisionMatrix(cases)

result = nds(nd)
fns = makeminmax([maximum, maximum, maximum])

@test isa(result, NDSResult)
result = nds(nd, fns)

@test result.bestIndex == 4
@test isa(result, NDSResult)

@test result.bestIndex == 4

@test result.ranks == [0, 0, 0, 3]
@test result.ranks == [0, 0, 0, 3]
end

@testset "NDS - all minimum" begin
cases = [
1.0 2.0 3.0 4.0
2.0 4.0 6.0 8.0
4.0 8.0 12.0 16.0
8.0 16.0 24.0 32.0
]

nd = makeDecisionMatrix(cases)

fns = makeminmax([minimum, minimum, minimum, minimum])

result = nds(nd, fns)

@test isa(result, NDSResult)

@test result.bestIndex == 1

@test result.ranks == [3, 2, 1, 0]
end
end


Expand Down

0 comments on commit 1e44e5c

Please sign in to comment.