Сохранение нескольких разреженных массивов в одном большом разреженном массиве - PullRequest
1 голос
/ 16 июня 2020

Я пытался реализовать какой-то код в Julia JuMP. Идея моего кода заключается в том, что у меня есть for l oop внутри моего while l oop, который выполняется S раз. В каждом из этих циклов я решаю подзадачу и получаю несколько переменных, а также opt = 1, если подзадача была оптимальной, или opt = 0, если она не была оптимальной. В зависимости от значения opt у меня есть два типа ограничений: либо ограничения оптимальности (если opt = 1), либо ограничения осуществимости (если opt = 0). Итак, цель моего кода состоит в том, что я добавляю все сокращения оптимальности только в том случае, если нет ограничений по выполнимости для s = 1: S (т.е. мы получаем opt = 1 на каждой итерации от 1: S). Я ищу лучший способ сохранить значения ubar, vbar и wbar. В настоящее время я сохраняю их по одному с помощью for-l oop, что довольно дорого. Итак, проблема в том, что мои значения ubar, vbar и wbar являются разреженными массивами осей. Я попытался сохранить их другими способами, например, создать трехмерный разреженный массив осей, который мне не удалось заставить работать, так как я не мог понять, как его инициализировать.

Приведенный ниже код работает (с правильный код, вставленный в мои <>, конечно), но работает не так хорошо, как я с sh. Так что, если есть способ более эффективно сохранять значения двумерных массивов разреженных осей, я хотел бы знать это! Заранее спасибо!

ubar2=zeros(nV,nV,S)
vbar2=zeros(nV,nV,S)
wbar2=zeros(nV,nV,S)
while <some condition>
    opts=0
    for s=1:S
        <solve a subproblem, get new ubar,vbar,wbar and opt=1 if optimal or 0 if not>
        opts+=opt
        if opt==1
            # Add opt cut Constraints
            for i=1:nV
                for k=1:nV
                    if i!=k
                        ubar2[i,k,s]=ubar[i,k]
                    end
                end
                for j=i:nV
                    if links[i,j]==1
                        vbar2[i,j,s]=vbar[i,j]
                        wbar2[i,j,s]=wbar[i,j]
                    end
                end
            end
        else
            # Add feas cut Constraints
            @constraint(mas, <constraint from ubar,vbar,wbar> <= 0)
            break
        end
        if opts==S
            for s=1:S
               @constraint(mas, <constraint from ubar2,vbar2,wbar2> <= <some variable>)
            end
        end
    end

1 Ответ

1 голос
/ 16 июня 2020

A SparseAxisArray - это просто тонкая обертка поверх Dict. Он был определен таким образом, что когда пользователь создает контейнер в макросе JuMP, независимо от того, получает ли он Array, DenseAxisArray или SparseAxisArray, он ведет себя как можно ближе друг к другу, поэтому пользователю не нужно заботиться о том, что он получил для большинства операций. По этой причине мы не могли просто создать Dict, так как он ведет себя иначе как массив. Например, вы не можете сделать getindex с несколькими индексами как x[2, 2]. Здесь вы можете использовать Dict или SparseAxisArray по своему усмотрению. Оба они имеют сложность O (1) для установки и получения новых элементов и разреженное хранилище, которое кажется достаточным для того, что вам нужно. Если вы выберете SparseAxisArray, вы можете инициализировать его с помощью

ubar2 = JuMP.Containers.SparseAxisArray(Dict{Tuple{Int,Int,Int},Float64}())

и установить с помощью

ubar2[i,k,s]=ubar[i,k]

Если вы выберете Dict, вы можете инициализировать его с помощью

ubar2 = Dict{Tuple{Int,Int,Int},Float64}()

и установите его с помощью

ubar2[(i,k,s)]=ubar[i,k]
...