【问题标题】:MATLAB : Networks have common values, how to separate them in groups?MATLAB:网络有共同的价值,如何将它们分组?
【发布时间】:2019-09-17 21:24:18
【问题描述】:

我正在做一个项目,但在分隔值时遇到了问题。

说明:我有一个包含 X 列和 X 行的矩阵。 通常,这是一个矩阵示例,其中列是网络。

一个=

 1     2     2     1
 2     3     5    12
 0     4     6    13
 0     5     7    14
 0     6     8    15
 0     0     9    16
 0     0     0    17
 0     0     0    18
 0     0     0    19
 0     0     0    20
 0     0     0    21
 0     0     0    22

每个网络都有许多车辆,有时两个或三个网络有公共车辆。

我的问题是:如何根据以下规则将它们分成不同的组。

  • 如果两个网络具有共同的价值,请将它们分成两组,
  • 如果两个网络没有共同的值,请将它们重新组合为一组,
  • 例如,如果一个网络与另一个网络没有共同价值,则将其添加到第 1 组而不是第 2 组(根据规则 2)。 如果一个网络与另一个网络具有共同值,则将其放置在不包含任何具有共同值的网络的第一组中(根据规则 1)。
  • 我接受有关第一条规则的答案,但目标是拥有平衡的群体。

我尝试了很多方法来解决这个问题。

这段代码可以让我找到每列之间的共同值:

lastColumn = nbNetworks_5; % = 4 in my example

for i = 1 : lastColumn

    for columnIndex = 1 : lastColumn

        if lastColumn == 1 
           % do nothing.
 
        elseif columnIndex ==  lastColumn 
           % do nothing.
 
        else
            [CommonValue,posInCln1,posInCln2] = intersect(a(:,columnIndex), a(:, lastColumn))
            
            % If there is a common value
            if CommonValue ~= 0
                regroup = false;
                
            else % If there is no common value
                regroup = true;
                
            end
        end
    end
    
    % Decrease the max number of columns.
    % We start from the end to get to the beginning.
    lastColumn = lastColumn - 1
    
end

这就是我的代码所做的:

我将第一列与最后一列进行比较,然后将第二列与最后一列进行比较,然后将第三列与最后一列进行比较。 然后我向后移动一列..等

我不知道如何分离和放置这些网络..

这就是我想要得到的最终结果:

group1network1,

group2network2network4

group3network3

创建组数:3

为了做到这一点:

network1在group1中,--Intersect with all networks

network2在group2中,--与Network3相交

network3 正在 group3 中,

network4 进入 group2。

感谢您花时间解决我的问题!

卡安

【问题讨论】:

  • 您说“我有一个包含 X 列和 X 行的矩阵”,它表示一个方阵,但在您的示例中它不是方阵。错字?如果将组定义为预期输出中的组,我认为显示您在此过程中做出的“决定”会很有帮助。乍一看,网络 1-3 都共享值2,所以应该归为一组,不是吗?
  • 是的,对不起,它是 X 列和 Y 行。不,它们必须分开而不是分组。

标签: matlab


【解决方案1】:

我有一个解决方案,但不幸的是它更难理解,因为它更短。

首先,您按原样定义数据。矩阵a 是您提供的矩阵。命令size(a,2) 给出a 中的列数。然后您创建一个向量,该向量稍后将包含每个组的数量。现在我们取零表示我们还没有找到这些组。 zeros(1,lastColumn) 将创建 [0 0 0 0]。

a= [1     2     2     1
 2     3     5    12
 0     4     6    13
 0     5     7    14
 0     6     8    15
 0     0     9    16
 0     0     0    17
 0     0     0    18
 0     0     0    19
 0     0     0    20
 0     0     0    21
 0     0     0    22];

lastColumn = size(a,2); %amount of columns
group=zeros(1,lastColumn);

这个循环框架很简单:我们从第一列开始循环到for 循环中的最后一列。然后我们从第一组 (current_gourp = 1) 开始,检查当前列是否有来自当前组的任何值。如果该组确实有一个值,我们检查下一个组,如果该组没有该值(因为该值不存在或该组到现在为止是空的)我们将current_group 设置为我们的current_column 的值.困难的部分是如何检查它,我将在代码下面解释它。

for current_column = 1 : lastColumn
    current_group = 1;
    while any(ismember(a(:,current_column),a(:,group==current_group)) & a(:,current_column)>0)
        current_group = current_group +1;
    end
    group(current_column) = current_group;
end


disp(['Total amount of groups: ' int2str(max(group))]);
disp(['The groups are ' int2str(group)]);

size_of_group=zeros(1,lastColumn);
for current_group=1:max(group)
    size_of_group(current_group) = sum(group==current_group);
    disp(['Group ' int2str(current_group) ' contains ' int2str(sum(group==current_group))]);
end

从 Matlab 帮助你得到:

ismember(A,B) 对于数组 A 和 B 返回相同的数组 大小为 A 包含真,其中 A 的元素在 B 中,假 否则。

所以intersect 可能仍然有效,但这似乎更合适。使用group==current_gourp,您将获得某个组中的所有列,或者如果该组到目前为止还没有成员,则什么都没有(在循环之前和循环之后尝试group==2)。由于两个 groupy 都可能包含零,第二部分 a(:,current_column)>0 检查该值是否高于 0。只有当两个值都为真时,当前组中当前列的元素且值高于 0,该值才会变为真。在这附近,any() 命令检查对于足以跳过该组的任何当前列是否为真。

希望对你有帮助

【讨论】:

  • 非常感谢您!自从我被困在这个问题上以来已经有一段时间了。它允许我在我的代码中前进。抱歉,由于我的声誉,我不能投票给你。还有一个问题,我怎样才能拥有一个组中的网络数量? (1 代表第 1 组,2 代表第 2 组,1 代表第 3 组)。
  • 我在上面添加了一个循环。您不需要投票,但请接受解决方案,以便问题显示为已解决
  • 但是我该如何保存呢?因为我需要将值“Z”除以每组的网络数。像 Z/1、Z/2 和 Z/1 一样?我想我必须循环执行此操作..
  • 好的,我在上面又添加了一行。现在你可以有一个向量size_of_group。如果你想使用它,最简单的方法是上面的循环for current_group=1:max(group)
猜你喜欢
  • 2015-07-01
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 2022-07-20
  • 1970-01-01
相关资源
最近更新 更多